dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.21k stars 9.95k forks source link

SignalR should allow managing of connections by UserGroup #45114

Open jez9999 opened 1 year ago

jez9999 commented 1 year ago

Is there an existing issue for this?

Is your feature request related to a problem? Please describe the problem.

Right now, I can send messages to an individual user using their NameIdentifier and Clients.User(nameIdentifier).SendAsync. I can also send messages to a group of connections using a group name and Clients.Group(groupName).SendAsync. However, unless I'm missing something, I can't send a message to a group of users (user as identified by nameIdentifier, not connection ID) at the SignalR level.

Describe the solution you'd like

I'd like to be able to send messages to a group of users (user as identified by nameIdentifier, not connection ID) at the SignalR level.

Additional context

Yes, this can of course be done with a roll-your-own backplane, track your own users as a group, and send to multiple users in SignalR according to the group you've defined for yourself. But the beauty of Groups and Users in SignalR is that they inherently support scaling up to multiple SignalR server instances and your code doesn't have to worry about ensuring that the message gets sent out to all SignalR instances.

If I roll-my-own backplane, I have 2 options: 1) Implement my own mechanism for grouping users by nameIdentifier, then when I want to send a message to all users in that group, use Clients.Users(nameIdentifiers). This will work, but each time a server wants to send to the group, it'll have to go to a backplane or database to retrieve the list of all users in that group; it can't use SignalR's existing scaling architecture to just "send to all users in this UserGroup", which would be more convenient and efficient. 2) Use Clients.Group(groupName). Each time a user joins a group, I add their connection ID into that named group, then send to that group to send to all group users. But what about when the user reconnects with a new ID? I need to worry about adding their new ID back into the appropriate groups. And what about when they leave the group? I know their current ID, but not any others associated with their nameIdentifier that may have been added. Seems like this won't really work.

If, however, SignalR offered the concept of UserGroup, I'd add a user to a group when necessary, remove them when necessary, and when I needed to send a message to all group users by nameIdentifier, I'd send it to that UserGroup. A user disconnecting/reconnecting is fine because their nameIdentifier is still in that UserGroup so nothing needs to happen. A user leaving is fine, because my server instance can just remove that nameIdentifier from the UserGroup. And when I need to send a message to all users in the UserGroup, I don't need to spend extra resources going off to a backplane or DB; it's utilizing the one that already exists because I've scaled up SignalR and setup a SignalR backplane already.

ghost commented 1 year ago

Thanks for contacting us.

We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

jez9999 commented 1 year ago

Additional idea: GroupGroup, allowing you to have groups of Groups to which you can send a message.

dkogithub commented 1 year ago

This is a must have feature for us as well. We have a workaround on the client side for now, but it's super ugly solution. It would be great to have a possibility to do filtering on the server side using user ids instead of connection ids.