Reputation: 128
I have the following Hub fragment working with SignalR, a Redis backplane and a single server.
public abstract class HubBase : Hub { private readonly static ConnectionMapping Connections = new ConnectionMapping(); public override Task OnConnected() { Connections.Add(Context.User.Identity.Name, Context.ConnectionId); return base.OnConnected(); } }
I am storing the connecting users in a static variable so I can map the connectionId to the username and am able to message specific users later on.
My question is, will the OnConnected function be called on all servers in a SignalR farm? I tested it and from the looks of it, it only gets called on the server to which the client connects.
If it doesn't get called on all servers, what's the recommended way of handling such scenario?
edit: thinking about this now I realize that my sample code might have a serious flaw. If the OnConnected method was called on another server as well, then clearly Context.User.Identity.Name would not be set since there is no request coming with the call. I guess the only way to solve this problem then is to use groups.
Upvotes: 3
Views: 3070
Reputation: 972
There is a way to do this, but as penderi said signalr is stateless so there is no guarantee that a specific user is still connected. I am not sure about Redis, but SQL server backplane uses IMessageBus, and it will store all messages in a local cache, if a user disconnects, then IMessageBus process will send all messages that have been broadcast since the user disconnected when the user reconnects. The caveat is that the cache only holds messages for so long.
Here is a link to a database implementation for mapping users to their connectionIds
Upvotes: 0