c#-“广播” TCP客户端列表的最快方法
作者:互联网
我目前正在用C#自下而上编写一个聊天服务器.
就像一个大房间,所有客户都在里面,然后您也可以发起私人聊天.我还为将来集成多个房间布置了代码(但现在没有必要).
它的编写主要是为了娱乐,也是因为我要为像我这样的年轻人创建一个新的聊天网站,因为丹麦没有人在这里聊天.
我刚刚用170个客户端(用Java编写,带有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);
});
}
这是在每个客户端上调用的send函数:
try {
byte[] bytesOut = System.Text.Encoding.UTF8.GetBytes(message + "\0");
_socket.BeginSend(bytesOut, 0, bytesOut.Length, SocketFlags.None, new AsyncCallback(OnSocketSent), null);
}
catch (Exception ex) { Drop(); }
我想知道是否有任何方法可以加快速度?
我已经考虑过编写某种辅助类来接受消息,然后使用大约20个线程左右来拆分广播列表.
但是我想知道您对这个话题的看法,我是学生,我想学习! (:
顺便说一句.我喜欢如何在即将发布到堆栈溢出时发现代码中的问题.我现在做了一个重载函数,可以在使用广播时从服务器类接受字节数组,因此UTF-8转换只需要发生一次.为了安全起见,字节数组长度的计算现在仅执行一次.请参阅下面的更新版本.
但是我仍然对改进它的方法感兴趣!
更新的广播功能:
lock (_clientLock)
{
byte[] bytesOut = System.Text.Encoding.UTF8.GetBytes(message + "\0");
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(); }
}
解决方法:
对于本地网络,大约1秒的声音确实很慢.平均LAN延迟为0.3毫秒. Nagle是启用还是禁用?我猜它已启用…所以:更改该(Socket.NoDelay).当然,这的确意味着您必须负责不要以过于分散的方式写入套接字-因此,请勿将消息逐个字符地写入.组合消息以将其发送(或更好:多个未完成的消息)在内存中,并将其作为一个单元发送.
标签:performance,concurrency,asyncsocket,c 来源: https://codeday.me/bug/20191201/2077683.html