SignalR是否提供消息完整性机制,确保在客户端重新连接期间不会丢失任何消息

时间:2014-11-30 12:33:44

标签: signalr signalr-hub signalr.client

摘要

嗨,我在思考是否可以使用SignalR丢失消息。假设客户端断开但最终在很短的时间内重新连接,例如3秒。客户端是否会收到断开连接时发送给他的所有消息?

例如,让我们考虑LongPolling传输。据我所知,长轮询是一个简单的http请求,由客户端提前发出,以便等待服务器事件。

一旦服务器事件发生,数据就会在http请求上发布,从而导致在发出的http请求上关闭连接。之后,客户端发出新的http请求,再次重复整个循环。

问题

假设服务器上发生了两个事件,首先A然后B(几乎立即)。客户端收到消息A,这会导致关闭http连接。现在要获取消息B客户端必须发出第二个http请求。

问题

如果在客户端与服务器断开连接并且尝试重新连接时发生了B事件。

客户端是否会自动获取B消息,或者我必须发明某种确保消息完整性的机制?

这个问题不仅适用于长轮询,也适用于客户重新连接的一般情况。

P.S。 我在服务器端使用SignalR Hub。


修改

我发现消息的顺序无法保证,我无法使SignalR松散消息

1 个答案:

答案 0 :(得分:7)

这个问题的答案在于EnqueueOperation方法......

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;
}

当服务器向客户端发送消息时,它会调用此方法。在上面的示例中,服务器会将2条消息排入队列,然后客户端会在收到第一条消息后重新连接,然后发送第二条消息。

如果服务器排队并发送第一条消息并且客户端重新连接,则会有一个小窗口,第二条消息可能会尝试在连接未处于活动状态的情况下排队,并且消息将在服务器端被删除。然后在重新连接后,客户端将不会收到第二条消息。

希望这有帮助