Hub.Clients.User(userId).methodCall始终抛出未将对象引用设置为对象的实例

时间:2015-06-18 02:03:23

标签: asp.net-mvc-5 signalr

我有一个继承自Hub类的NotificationHub类。

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

这总是失败

[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

但是,如果我这样做:

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

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

它有效......这里给出了什么?我见过的大多数例子都不需要明确地获取上下文,如果Hub尚未提供它?我宁愿不必每次都明确地抓住它。

这是我的IoC设置:

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

激活:

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);
        }
    }

1 个答案:

答案 0 :(得分:8)

如果要从集线器处理程序方法之外向客户端发送内容(即在处理服务器上的消息期间不发送),则必须使用myCustomConcat(_:_*)

原因是当调用方法来处理某些客户端消息时,中心实例由SignalR创建,并且GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();属性已正确初始化。当您从服务器代码自己调用方法时(并且可能自己创建集线器实例),情况并非如此。

Imho错误消息不是很清楚,SignalR应该更好地处理这个用例。无论如何,出于同样的原因,我建议将发送消息的所有方法分离到客户端,这些客户端旨在从服务器代码调用到不同的类(不是从Clients派生的)。