Search code examples
signalrsignalr-backplane

Signalr backplane based on ScaleoutMessageBus needs an incrementing identifier?


I am trying to understand how to create my own IMessageHub. I don't want to rely on any extra infrastructure and the number of messages are low. So I decided to use a simple socket solution to replicate the messages. I have looked at the source code for the different ScaleoutMessageBus implementations but these seem to require an additional strictly increasing identifier (Redis implementation uses 'INCR' for instance). Can someone confirm that this is the case? A random identifier will not cut it?

The identifier is the second parameter to the OnRecieved method below

 public abstract class ScaleoutMessageBus : MessageBus
     {
...
   protected virtual void OnReceived(int streamIndex, ulong id, ScaleoutMessage message)

Solution

  • You are correct that the identifier should be strictly increasing.

    This is used so SignalR clients can have a global identifier of the last message they received. When SignalR clients reconnect to another server (this is especially common with the long polling transport), they pass it this identifier to the new server so it can send any messages the reconnecting client missed out of its in-memory cache.

    If the identifier ever decreases, SignalR will continue to operate, but each server would immediately flush its in-memory cache of received messages. This would likely cause reconnecting clients to miss messages.

    To see why SignalR needs to operate this way, consider messages coming from the scaleout provider with identifiers in the following order:

    1, 2, 3, 1, 2, 3
    

    Then suppose a client reconnects to a different server saying the last identifier it received was "2". There is no way the server can respond with messages without risking either sending duplicates or missing messages. With the way SignalR is designed, the client should not receive duplicates, but would miss messages "3, 1, 2".