Elyas Esna
Elyas Esna

Reputation: 635

signalr check to have only one active connection per user identity

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.

Upvotes: 1

Views: 1440

Answers (2)

Happy Development
Happy Development

Reputation: 117

You can always use Session with HttpContextAccessor.

Or you can store different data for each tab with ProtectedSessionStorage.

Even combine both scenarios.

Maybe this helps:

https://stackoverflow.com/a/75445774/15400027

Upvotes: 0

Maxim Zabolotskikh
Maxim Zabolotskikh

Reputation: 3387

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.

Upvotes: 2

Related Questions