客户端在短时间内发送太多邮件时会丢失邮件

时间:2013-03-17 11:34:52

标签: c# signalr .net-4.5 signalr.client

服务器广播如下消息:

protected override Task OnReceived(IRequest request, string connectionId, string data)
{
    if (_messagesToSent == 0)
    {
        int.TryParse(data, out _messagesToSent);
    }
    else
        return Task.Delay(0);

    // Broadcast data to all clients
    return new TaskFactory().StartNew(() =>
        {
            _log.InfoFormat("Starting broadcasting of {0} messages.", _messagesToSent);
            int sentMessages = 0;

            if (_messagesToSent > 0)
                Connection.Broadcast(GetInfoMessage());

            while (_messagesToSent > 0)
            {
                Connection.Broadcast(GetDataMessage(sentMessages));
                _messagesToSent--;
                sentMessages++;
                if (sentMessages % 1000 == 0)
                    _log.InfoFormat("{0} messages of total {1} messages sent.", sentMessages,
                                    sentMessages + _messagesToSent);
            }
            _log.InfoFormat("{0} messages were sent.", sentMessages);
        });
}

基本思想是在服务器开始时从客户端接收带有要发送的消息数的消息。然后在while循环中,它广播这些消息并进行一些记录。 客户端也很简单,它只计算收到的消息数并记录输入数据:

private void ConnectionOnReceived(string s)
{
    ReceivedMessagesCount++;
    _log.Info(s);
}

我做了几次测试:

  • 广播最多1000条消息正常,客户端收到所有消息
  • 广播2000条消息,客户端只收到大约1500条消息
  • 广播10K消息,同样接收1500-1600条消息

当服务器托管在云服务中时,测试是在本地和Azure上执行的。

那么,我做错了什么?我是否遗漏了配置或其他内容?

1 个答案:

答案 0 :(得分:3)

您发送的邮件速度比客户端收到邮件的速度快,导致客户端错过邮件。

当广播1000条或更少的消息时,您的客户端会收到所有消息,因为SignalR的DefaultMessageBufferSize为1000.这可以通过SignalR的IConfigurationManager进行更改,例如:

GlobalHost.Configuration.DefaultMessageBufferSize = 2000;

然而,chaning DefaultMessageBufferSize只是一个创可贴,因为如果你连续发送的消息比你的客户端可以接收的速度快,你将会超出任何规模的缓冲区。

真正的解决方案涉及限制发送邮件的速率。这种限制可以通过让您的客户定期向您的PersistentConnection发送ACK来指示它已收到多少消息来实现。