"broadcast" TCP 客户端列表的最快方法



我目前正在用C#编写一个自下而上的聊天服务器。

这就像一个大房间,所有的客户都在里面,然后你也可以发起私人聊天。我还为多个房间的未来集成制定了代码(但现在没有必要)。

写这篇文章主要是为了好玩,但也因为我要为像我这样的年轻人创建一个新的聊天网站,因为丹麦已经没有人了。

我刚刚用170个客户端测试了它(用Javascript编写,带有JQuery和Flash桥接到套接字连接)。本地网络上从发送消息到传递消息的响应时间小于1秒。但现在我正在考虑我能从中挤出什么样的表现。

我可以看到,如果我连接两个客户端,然后连接168个其他客户端,在客户端2上写,并观察客户端1,它会立即出现在客户端1上。CPU使用率和RAM使用率丝毫没有显示出服务器压力的迹象。它处理得很好,我认为它可以扩展到至少1000-1500,没有任何问题。

然而,我注意到了一些事情,那就是如果我再次打开170个客户端,在客户端1上发送消息,并在客户端170上进行监视,则会有大约750毫秒的日志。我知道问题,也就是说,当服务器接收到聊天消息时,它会将其广播给服务器上的每个客户端。然而,它确实需要枚举所有这些客户端,这需要时间。现在的延迟对于聊天来说是可以接受的,但我担心客户端1发送到客户端750(尚未测试)可能需要2-3秒。当我开始每秒收到2-3条信息时,我也很担心。

综上所述,我想加快服务器广播过程。我已经在使用一个并行的foreach循环,我也在使用异步套接字。

这是广播代码:

  lock (_clientLock)
        {
            Parallel.ForEach(_clients, c =>
            {
                c.Value.Send(message);
            });
        }

下面是在每个客户端上调用的发送函数:

try {
        byte[] bytesOut = System.Text.Encoding.UTF8.GetBytes(message + "");
        _socket.BeginSend(bytesOut, 0, bytesOut.Length, SocketFlags.None, new AsyncCallback(OnSocketSent), null);
        }
        catch (Exception ex) { Drop(); }

我想知道是否有办法加快速度?我考虑过编写某种帮助类,接受que中的消息,然后使用大约20个线程来拆分广播列表。

但我想知道你对这个话题的看法,我是一名学生,我想学习!(:

Btw。我喜欢在即将发布到堆栈溢出时发现代码中问题的方式。我现在制作了一个重载函数,在使用广播时接受来自服务器类的字节数组,因此UTF-8转换只需要进行一次。为了安全起见,字节数组长度的计算现在只进行一次。请参阅下面的更新版本。但我仍然对如何进一步改进这一点感兴趣!

更新广播功能:

 lock (_clientLock)
        {
            byte[] bytesOut = System.Text.Encoding.UTF8.GetBytes(message + "");
            int bytesOutLength = bytesOut.Length;
            Parallel.ForEach(_clients, c =>
            {
                c.Value.Send(bytesOut, bytesOutLength);
            });
        }

更新了客户端对象上的发送功能:

 public void Send(byte[] message, int length)
    {
        try
        {
            _socket.BeginSend(message, 0, length, SocketFlags.None, new AsyncCallback(OnSocketSent), null);
        }
        catch (Exception ex) { Drop(); }
    }

~1s对于本地网络来说听起来真的很慢。平均LAN延迟为0.3ms。Nagle是启用还是禁用?我猜它已经启用了。。。所以:改变那个(Socket.NoDelay)。确实意味着你必须承担责任,不要以过于分散的方式写入套接字,所以不要一个字符一个字符地滴下消息。在内存中组装要发送的消息(或者更好:多个未完成的消息),并将其作为一个单元发送。

最新更新