2015-06-18 15 views
6

Mam klasę NotificationHub, która dziedziczy z klasy Hub.Hub.Clients.User (userId) .methodCall zawsze rzuca Odwołanie do obiektu nie jest ustawione na instancję obiektu

public class NotificationHub : Hub 
    { 
     public void Send(string userId, Notification notification) 
     { 
      Clients.User(userId) 
       .notificationReceived(notification); 
     } 
    } 

To zawsze kończy się niepowodzeniem z

[NullReferenceException: Object reference not set to an instance of an object.] 
    Microsoft.AspNet.SignalR.Hubs.SignalProxy.Invoke(String method, Object[] args) +88 
    Microsoft.AspNet.SignalR.Hubs.SignalProxy.TryInvokeMember(InvokeMemberBinder binder, Object[] args, Object& result) +12 
    CallSite.Target(Closure , CallSite , Object , <>f__AnonymousType0`4) +351 

Jednak jeśli mogę to zrobić:

public class NotificationHub : Hub 
    { 
     public void Send(string userId, Notification notification) 
     { 
      var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>(); 

      context.Clients.User(userId) 
       .notificationReceived(notification); 
     } 
    } 

To działa .... co daje tutaj? Większość przykładów, które widziałem, nie wymaga jawnego kontekstu, jeśli nie jest już dostępna w Hubie? Wolałbym raczej nie chwytać tego wyraźnie za każdym razem.

Oto moja konfiguracja IoC:

GlobalHost.DependencyResolver.Register(typeof(IHubActivator),() => new SimpleInjectorHubActivator(container)); 
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider),() => new SignalRHubUserIdProvider()); 

Activator:

public class SimpleInjectorHubActivator : IHubActivator 
    { 
     private readonly Container _container; 

     public SimpleInjectorHubActivator(Container container) 
     { 
      _container = container; 
     } 

     public IHub Create(HubDescriptor descriptor) 
     { 
      return (IHub) _container.GetInstance(descriptor.HubType); 
     } 
    } 
+0

Wyjątek "NullReferenceException", który otrzymujesz, jest to podczas wywoływania metody 'Send()' z klienta lub z innego kodu serwera? –

+0

Jest to podczas wywoływania wysyłania z serwera, Clients.User (userId) .notificationReceived (powiadomienie); zgłasza wyjątek – Jack

Odpowiedz

8

Jeśli chcesz wysłać coś do klientów spoza metod obsługi piasty (czyli nie w trakcie przenoszenia wiadomości na serwerze) musisz użyć GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();

Powód jest taki, że gdy metoda jest wywoływana do obsługi niektórych komunikatów po stronie klienta, instancja centralna jest tworzona przez SignalR iWłaściwośćzostała poprawnie zainicjowana. Nie dzieje się tak w przypadku samodzielnego wywoływania metody z kodu serwera (i prawdopodobnie samego tworzenia instancji serwera centralnego).

Komunikat o błędzie Imho nie jest bardzo jasny i ten przypadek użycia powinien być lepiej obsługiwany przez SignalR. W każdym razie z tego samego powodu sugeruję oddzielenie wszystkich metod wysyłania wiadomości do klientów, które mają być wywołane z kodu serwera do innej klasy (nie pochodzą od Hub).

Powiązane problemy