I have a NotificationHub class which inherits from the Hub class.
public class NotificationHub : Hub
{
public void Send(string userId, Notification notification)
{
Clients.User(userId)
.notificationReceived(notification);
}
}
This always fails with
[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
However if I do this:
public class NotificationHub : Hub
{
public void Send(string userId, Notification notification)
{
var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
context.Clients.User(userId)
.notificationReceived(notification);
}
}
It works .... what gives here? Most of the examples I've seen do not require getting the context explicitly, should it not already be available from Hub? I would rather not have to grab it explicitly every time.
Here is my IoC Setup:
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);
}
}
The SignalR Hubs API enables you to call methods on connected clients from the server. In the server code, you define methods that are called by client. In the client code, you define methods that are called from the server.
The IHubContext is for sending notifications to clients, it is not used to call methods on the Hub . View or download sample code (how to download)
In SignalR, a hub is a core component that exposes a set of methods that can be called by the client. In this section, you define a hub class with two methods: Broadcast : This method broadcasts a message to all clients. Echo : This method sends a message back to the caller.
If you want to send something to clients from outside of hub handler methods (ie not during handling message on server), you have to use GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
Reason is that when the method is called to handle some client side message, hub instance is created by SignalR and Clients
property is correctly initialized. This is not the case when you calling method yourself from server code (and probably creating hub instance yourself).
Imho error message is not very clear and this use case should be handled better by SignalR. Anyway for the same reason i suggest to separate all the methods sending messages to clients which are intended to be called from server code to different class (not derived from Hub
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With