Closed Jacknq closed 6 years ago
Critical feature if you dive your app and dont want everything (every method) in one hub.
Can you explain what this means?
There are currently not plans to support multiple hubs per connection.
sure, you can have an hub with a chat, but you can have a hub with methods getting some reports data and typically -, those two things dont belong together in code. So you create two separate hubs, and you want to access them with one authentication and one connection.
Why can't you put the same authentication on both hubs?
I can put same authorize attribute over them, but why do I need initiate two different connections on client connecting to same endpoint?
Because thats the new model. Let me flip the question, why do you have many hubs?
Because you separate logic into different classes that have nothing to do with each other, and you dont want to end at the end with ONE class containing all the methods - its hell in bigger scenarios. obvious reasons dont you think? they share only the endpoint, but you can remove some hub later..
Thanks for the feedback! No promises but it would be interesting to see how many hubs you have (it is 10? 5? 2?), see what they look like (in terms of number of methods and behavior) to help us understand the scenario better.
Also, it would be interesting to see what the client looks like. I'd like to see how different parts of the application wires up to the various hubs.
If indeed you need to use multiple hubs, instead of multiple hub proxies, you now have multiple connections, it's not as trivial but I'm not yet convinced it's a deal breaker. More data about how you're using it would definitely help.
Imagine big data (terabytes), big app scenario.. You can create something similar like webservice oriented scenario, where each hub is responsible for something. like typical scenario in my case I can Imagine 5-6 hubs, each responsible for another part of the system. Why would you ever combine classes and methods in one hub? Why coudnt you have one connection and access them all? I give you right oway two clients one is web browser another one is desktop app, it could be one and the same application written in react, vue.. and packed for different scenarios. Depending on permissions in that app for particular user, you use different hubs in backend. And yes if user has right for different modules in this app it ll use different hubs simultaneously... I can give you ton of examples that I see in everyday scenarios in field. just ask.
I can give you ton of examples that I see in everyday scenarios in field. just ask.
I'd like to see the typical code in these scenarios, preferably if we have existing signalr apps today that do this exact pattern it would be great to look at.
I cannot pass to you bigger apps from private companies. But you can have anlook at my simple example on github. or i can describe to you real world scenarios and why is good to have one connection with multiple hubs. What suprises me that thinking one connection and one hub will be always enough. no it wont you either want somethung flexible enough ot you go with other libraries like socket.io and so on.. and this now also possible to integrate and call from .net. be smart be flexible and create something that can do more than the others..
no it wont you either want somethung flexible enough ot you go with other libraries like socket.io and so on
Funny thing is socket.io isn't much different here, all you have are events so I'm not sure what you mean.
Thanks, I'll leave this bug open and let others chime in with their experiences.
Sorry, original Signalr 2 has this feature, even the one on .net 4.6, if I m not wrong its one big feature less! Same opinions here: https://stackoverflow.com/questions/19825901/how-to-have-multiple-signalr-hub-on-one-page here.. https://stackoverflow.com/questions/40277903/when-to-use-multiple-hubs-in-signalr , here.. https://stackoverflow.com/questions/19825901/how-to-have-multiple-signalr-hub-on-one-page here https://forums.asp.net/t/2005679.aspx?Multiple+instances+of+hub+does+it+make+sense+ Only argument I can think of why not to separate hubs is mobile battery consumption. Socket was just an example, there are more of them. Dont be just academic.
@Jack85 I think the more important reason why there is one connection per hub is to keep things simple.
Sharing a connection across multiple hubs requires an internal routing solution as well as a much larger API surface (so that you can open the connection, and then pass it for each hub), and all that must be replicated in Javascript as well...
So, if it is an uncommon scenario, it makes sense to prioritize releasing a v1 of the current architecture. And maybe in the next version, this feature would be considered.
Regarding the separation of concerns where you want hubs that handle very different services, a workaround can be to have one SignalR hub as the entry point where each method is a single line calling a separated class for that service.
Yes, but imagine those 1000 methods there, forced to do multiple inheritance, might be only elegant solution. I dont think it has to be complicated somehow authorize connection first and share this authentication with every hub call.
I did exactly as KPixel has pointed out. Separate your logic into multiple service layers as you would an MVC app. The separation of the business logic and database logic is achieved by injecting multiple service layers into the hub. From there the fact that you have a single hub means nothing. Since all its doing is taking the call and passing it straight down to the service layer.
I can see a hub per domain running on one connection. For example, I have a Projects app. The project has some domains like "issues" and "benefits". This app is small and the domains aren't heavyweight enough to dedicate a whole sub-system. They're like micro-domains (I call them Scopes). They service different audiences - everyone gets issues pushed, and stakeholders get benefits pushed. Each Scope has a Front Controller to manage processes and full pages. There is a related Hub for each Scope to handle the chatty stuff in the pages.
Most of the time, these are accessed from the Project scope. A user is working on a project and needs to add an issue. It works either way, but it just feels better to have one connection talking to Project scope, and hitting the other hubs through that same connection.
@davidfowl, I'm still a bit new to Signalr so correct me if I'm wrong.
If you were to use this in an architecture similar to Microservices a hub per service.
You could easily have over 100 hubs,
For each hub you will have to manage the users?
So for each user won't I be storing duplicate data 100 times?
Or is there a way to the users of different hubs, while preventing memory from bloating?
Let me flip the question, why do you have many hubs?
I'll give our scenario. We have four independent software teams working on one module-based product, each team is responsible for their own modules. It sounds like it should be microservice'y, but we went monolith first. Coming from the old/current SignalR, we evolved to a state where each module had it's own hub, so teams could remain as independent as possible.
I don't particularly like where we've ended up. We've got eleven hubs so far with zero methods on them. We are just using them as a filter on the front end, so each module can just subscribe/process their own messages. I don't like that we have a connection per hub.
Judging from #1430 this is discouraged for new SignalR (we've just switched over to alpha2). The partial class suggestion is probably enough to maintain team independence for us.
A solution given here is by creating services. This would mean I would need to pass the HubCallerContext
to every method when needed, right?
We are just using them as a filter on the front end, so each module can just subscribe/process their own messages.
In that case, why not use a single Hub and add the clients to Groups as needed?
This would mean I would need to pass the HubCallerContext to every method when needed, right?
If you wanted to be able to call back to the client in one of your services, then yes. You could always build a base hub that sets up a wrapper to do this for you though.
In that case, why not use a single Hub and add the clients to Groups as needed?
I haven't investigated Groups in new SignalR yet, but my understanding of old SignalR they didn't seem to be a good fit for our use. With our Angular SPA and navigating between module "pages", we always want all SignalR messages to go down to all clients. There could be many Angular components on a "page" from different modules, so each component needs a way to filter out messages for its own module.
so each component needs a way to filter out messages for its own module
Yeah, this could be achieved with groups, but you'd need a separate connection for each module anyway, so it doesn't solve that problem. Is there a reason you can't do this filtering by using attributes in the messages themselves? Both Groups and Hubs have non-trivial server-side state requirements (memory is required to store state, both on the server and backplane, cpu is required to filter messages to the right connections). Tagging the messages on the server and having the client do the filtering/dispatching would move this logic from the server (where thousands of message streams have to be filtered and processed) to the client (where one message stream has to be filtered and processed). If all clients are receiving all messages, you don't really need the server to filter.
Is there a reason you can't do this filtering by using attributes in the messages themselves?
Nope! In fact this is something we will be moving towards soon, especially considering:
Both Groups and Hubs have non-trivial server-side state requirements...
TYVM for the extended explanation, I appreciate it. It definitely adds to the impetus for us.
We periodically close 'discussion' issues that have not been updated in a long period of time.
We apologize if this causes any inconvenience. We ask that if you are still encountering an issue, please log a new issue with updated information and we will investigate.
Critical feature if you dive your app and dont want everything (every method) in one hub. There is greater flexibility needed and anyone can put authorize attributes on methods or hubs that need to be authenticated, using one connection which can call any hub in endpoint. If you need to be more strict you typically make another endpoint where the authentication differs. Using alpha .net core version 1.0.0-alpha1