-
Notifications
You must be signed in to change notification settings - Fork 25.2k
How does a client tell the server what group it wants to be in or what user it is? #7255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@anurse please comment. |
The client does not have control over what groups it is in. The server is the only thing that can assign groups (this is partially a security measure). For a client to join a group, it needs to call a Server hub method that will add it to the group. |
Alternatively you can use users, in which case it depends on how you have configured ASP.NET Core Authentication. |
@anurse Maybe this is a fundamental misunderstanding then. I have thousands of physical IoT devices worldwide, allocated to different customers. When I want to send content to those those devices, I only want to send to those devices for a single customer. Groups therefore seems the approach I should use. When the IoT device connects to the Hub it knows what customer its for, so it tells the hub this - the only way I can work out how to do this is via the URL used during the HubConnectionBuilder process. The hub picks this up during it's OnConnecting event and then, based on the customer in the Url it's inspected from the incoming request, assigns the ConnectionId to an appropriate hub group for that customer. I'm guessing this is not the recommended way to pass context from a client to the Hub. So what is the recommended way, and can we have an example please? |
There are two primitives that can work for you here in SignalR: Groups and Users. Groups are 100% controlled by the server. But of course, since the client can invoke methods on the server, you can have a server hub method that adds a client to a group. For example: public class DeviceHub: Hub
{
public async Task Initialize(string customerId)
{
await Groups.AddAsync(Context.ConnectionId, $"Customer:{customerId}");
}
} Then on the client: await connection.StartAsync();
await connection.InvokeAsync("Initialize", customerId); The risk here is that you are trusting the client to provide the right customer ID. Nothing would stop a malicious user from simply specifying a random customer ID and becoming part of the group. The other option is Users. The "User ID" for a connection is assigned as part of authenticating the connection, and then it basically just serves as an "automatic" group. I do think that's a better approach for your scenario. That all depends on how you are authenticating users though. What kind of security/authentication are you using for clients? Do you have a security token (such as a JWT token) that you use to identify the customer? |
@anurse Ok... the invokeAsync from the client can work and yes, we are using JWT tokens too.. (not sure how to enable that yet, but I'll work on it). My scenario was simplified though - we have customer level security tokens but they have multiple locations too. We really only want to send to a specific customer-location not to all customers, so JWT may not be enough on its own. How does either scenario handle reconnects though? Reading through some of the previous issues, the .NET client now handles reconnects automatically. What isn't clear from the Docs (or I can't find it) is how it does it and how does the client know there has been an issue. For example, a server restart will clear down the connections and the groups they are in - I don't really want a persistent store server-side as this can get stale, so the client needs to know the connection has been dropped and then when it reconnects automatically it can get itself added back into the appropriate group. There is the Closed event on HubConnection class to help with this, but I can't see a reconnected event (or something similar such as an exposed ConnectionState) to know when it's ok to invoke the Initialize method on the hub again. (this comes back to my original concern, which is these tutorial docs leave out a lot of functionality that is necessary for a robust system we'd consider putting into production) |
This is definitely a case where groups are good. Once you've "authenticated" that the connection is from the right user the client can call a method on the server to assign itself to the group
Where did you get that impression? ASP.NET Core SignalR does not automatically reconnect, that was intentionally removed, so I'd like to figure out what content you're reading that's telling you otherwise so we can clear it up.
In ASP.NET Core SignalR, once a connection is closed, it's gone. However, the
It's early days and tutorials often cover just the basics, we're getting the docs moving, and questions like this are exactly how we figure out what information people need. So thanks for the input! |
I found it here https://github.com/aspnet/SignalR/issues/1057 and this PR aspnet/SignalR#1147 Reading it again, I notice your comment that auto-reconnect will be later - I think I got confused with the PR and the issue. Thanks for the info so far, it really is helping to fill in the blanks. |
Ok, good, I'm glad that our docs aren't making the wrong impression here. Sometimes the issues are a little bit unclear, because they're primarily just for planning our own work and reporting problems/feature requests 😉 . Are there some specific modifications to the docs that would help clear this up? Writing full tutorials is a lot of work, but explanatory docs are a lot easier to write/update. We've got #6757 filed to talk about reconnect scenarios, so feel free to comment there if there's anything you think we could add. |
Uh oh!
There was an error while loading. Please reload this page.
Scenario: Multiple listeners deployed worldwide, each listener belongs to a group. When a message is published it belongs to every listener in the group (or if you want to design it as such, to that user which has multiple listeners attached). How does the listener, using the .NET client, tell the hub what group it's in (or what user it is)?
From what I can gather (this article doesn't make it clear), I can pass context on the client query string and then access this HTTP context in the OnConnected event of the Hub.
I worked this out by trial and error..... I'm sorry, but a number of these examples are just too simple and leave many questions unanswered as a tutorial.
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
The text was updated successfully, but these errors were encountered: