Hub.Clients.User(userId).methodCall 总是抛出 Object reference not set to an instance of an object
Hub.Clients.User(userId).methodCall always throws Object reference not set to an instance of an object
我有一个 NotificationHub class,它继承自集线器 class。
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);
}
}
如果您想从集线器处理程序方法之外向客户端发送内容(即不是在服务器上处理消息期间),您必须使用 GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
原因是当调用该方法来处理某些客户端消息时,集线器实例由 SignalR 创建并且 Clients
属性 已正确初始化。当您自己从服务器代码调用方法(并且可能自己创建集线器实例)时,情况并非如此。
恕我直言,错误消息不是很清楚,这个用例应该由 SignalR 更好地处理。无论如何,出于同样的原因,我建议将所有向客户端发送消息的方法分开,这些方法旨在从服务器代码调用到不同的 class(不是从 Hub
派生)。
我有一个 NotificationHub class,它继承自集线器 class。
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);
}
}
如果您想从集线器处理程序方法之外向客户端发送内容(即不是在服务器上处理消息期间),您必须使用 GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
原因是当调用该方法来处理某些客户端消息时,集线器实例由 SignalR 创建并且 Clients
属性 已正确初始化。当您自己从服务器代码调用方法(并且可能自己创建集线器实例)时,情况并非如此。
恕我直言,错误消息不是很清楚,这个用例应该由 SignalR 更好地处理。无论如何,出于同样的原因,我建议将所有向客户端发送消息的方法分开,这些方法旨在从服务器代码调用到不同的 class(不是从 Hub
派生)。