The SignalR service SDK should be a de-multiplexer that plugs at the HubConnectionHandler
See original GitHub issueThis is basically an uber issue caller for the re-design of the how the integration works. Today there’s too much copied code from SignalR which is fragile and ever changing. At an extremely high level, the SignalR SDK is handling incoming messages from the SignalR service and pumping those messages into individual connections as they are received. It should be no different from those connection being directly connected to the application conceptually, the only different being that there’s no physical connection, it’s virtual (being de-multiplexed from the service).
What this means, is that there are 2 major pieces that need to be replaced:
- The IConnectionBuilder - SignalR binds to any IConnectionBuilder that can be provided, by default that’s one provided by Microsoft.AspNetCore.Http.Connections, which provides this abstraction over WebSockets, SeverSentEvents and LongPolling.
- The HubLifetimeManager - This handles messages send from server to client. We have a built in one for in memory (DefaultHubLifetimeManager) and one for redis (RedisHubLifetimeManager).
For 1. the service needs to replace the built in IConnectionBuilder with one that handles incoming traffic from the service. This is basically what HubHost<THub> does (see https://github.com/Azure/azure-signalr/blob/071ad301a934001c872ef417812ed8ee78a1fc3a/src/Microsoft.Azure.SignalR/HubHost/HubHostBuilder.cs#L26-L29).
For 2. the service needs to replace the DefaultHubLifetimeManager with one that sends server to client “commands” back to the service itself. This is what the HostHubLifetimeManager does (https://github.com/Azure/azure-signalr/blob/071ad301a934001c872ef417812ed8ee78a1fc3a/src/Microsoft.Azure.SignalR/HubHost/HubHostLifetimeManager.cs)
Everything should revolve around these 2 layers but today the SDK dives a bit deeper into the SignalR logic which it shouldn’t (see the https://github.com/Azure/azure-signalr/blob/75efc45046d61878c354992bfbc6ab3dff52213d/src/Microsoft.Azure.SignalR/HubHost/HubHostDispatcher.cs). This logic should be the default SignalR logic and the only thing we should be replacing is the transport layer (how bytes get into and out of the application).
Microsoft.Azure.SignalR.Connections
If you look closely at the above, it suggests that in essence the service is itself a transport layer as it completely replaces Microsoft.AspNetCore.Http.Connections. The way I envision this working is that we have a type called ServiceConnectionManager that manages the CloudConnection (maybe rename to ServiceConnection?) that talk to the SignalR service. This is this has 2 responsibilities, it handles the incoming traffic from the service, decodes the messages type appropriately, creates a ConnectionContext
with the appropriate set of features and writes the message payload to the Application’s input pipe. It also needs to read messages coming out of the application’s pipe and write those to the ServiceConnection. This is all hidden from the SignalR layer, nothing on top would need to change, there would be no custom HubDispatcher or any other extensibility.
For the ServiceHubLifetimeManager, it would directly get access to the ServiceConnectionManager to send special messages to the service for those message types. This is very similar to redis except that it’s much easier since it doesn’t need to do any of the receiving of messages.
If you want, I can throw something together quickly to demonstrate how this should work. Let me know.
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (5 by maintainers)
Top GitHub Comments
I decided to throw together some pseudo code. Tell me if I’ve missed anything.
This is fixed