signalr check to have only one active connection per user identity

Viewed 210

How can I manage to have only one connection of signalR per user in different browsers/tabs? so if user is active in one tab/browser and wants to open another tab/browser I have to alert him to first close the previous tab/browser. like Whatsapp. I have implemented this so far but I don't know how to fill the commented par?!

public override async Task OnConnectedAsync()
{
   bool isUserExisted = _onlineUsers.TryAdd(Context.User.FindFirst("username").Value, Context.ConnectionId);
   if (!isUserExisted)
   {
      //avoid to connect the already connected user
      //and send alert to him
   }
   await base.OnConnectedAsync();
}

public override async Task OnDisconnectedAsync(Exception exception)
{
   _onlineUsers.TryRemove(Context.User.FindFirst("username").Value, out _);
   await base.OnDisconnectedAsync(exception);
}

Any help would be appreciated.

1 Answers

I'm not an expert on the client side, but I assume you cannot maintain the same SignalR connection from different tabs because each tab has its own context and establishes its own connection. You can, however, on the server side create a user group, where you would pack all connections of the current user:

var user = GetUser(username); // Get your user from context
await this.Groups.AddToGroupAsync(this.Context.ConnectionId, GetUserGroupName(user)); // Generate unique group name per user and add all user connections to it

Than you can play with whom you send your events, e.g. send to all user connections but for current one (i.e. but for current tab):

this.ctx.Clients.GroupExcept(groupName, currentConnectionId);

I'm not sure when alerting should occur? Do you call a REST method on the server? Or directly a SignalR method? If it's an independent REST method, you could pass your current SignalR connection id in a custom header and read it in the hub.

Related