8

Abstract

Hi, I was pondering whether it is possible to loose a message with SignalR. Suppose client disconnects but eventually reconnects in a short amount of time, for example 3 seconds. Will the client get all of the messages that were sent to him while he was disconnected?

For example let's consider LongPolling transport. As far as I'm aware long polling is a simple http request that is issued in advance by the client in order to wait a server event.

As soon as server event occurs the data getting published on the http request which leads to closing connection on issued http request. After that, client issues new http request that repeats the whole loop again.

The problem

Suppose two events happened on the server, first A then B (nearly instantly). Client gets message A which results with closing http connection. Now to get message B client has to issue second http request.

Question

If the B event happened while the client was disconnected from the server and was trying to reconnect.

Will the client get the B message automatically, or I have to invent some sort of mechanisms that will ensure message integrity?

The question applies not only to long-polling but to general situation with client reconnection.

P.S. I'm using SignalR Hubs on the server side.


EDIT:

I've found-out that the order of messages is not guaranteed, I was not able to make SignalR loose messages

Community
  • 1
  • 1
Lu4
  • 14,873
  • 15
  • 79
  • 132

1 Answers1

7

The answer to this question lies in the EnqueueOperation method here...

https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/Transports/TransportDisconnectBase.cs

protected virtual internal Task EnqueueOperation(Func<object, Task> writeAsync, object state)
{
    if (!IsAlive)
    {
        return TaskAsyncHelper.Empty;
    }

    // Only enqueue new writes if the connection is alive
    Task writeTask = WriteQueue.Enqueue(writeAsync, state);
    _lastWriteTask = writeTask;

    return writeTask;
}

When the server sends a message to a client it calls this method. In your example above, the server would enqueue 2 messages to be sent, then the client would reconnect after receiving the first, then the second message would be sent.

If the server queues and sends the first message and the client reconnects, there is a small window where the second message could attempt to be enqueued where the connection is not alive and the message would be dropped at the server end. Then after reconnect the client wouldn't get the second message.

Hope this helps

Dean North
  • 3,741
  • 2
  • 29
  • 30