Web Socket 消息未全部接收

Posted

技术标签:

【中文标题】Web Socket 消息未全部接收【英文标题】:Web Socket messages not all being received 【发布时间】:2013-03-06 12:45:20 【问题描述】:

我已经使用Alchemy 网络套接字实现了一个网络套接字服务器,现在我正在尝试对其进行压力测试。我在 C# 中编写了以下方法来创建大量客户端以连接到服务器并发送一些数据:

private void TestWebSocket()

    int clients = 10;
    long messages = 10000;
    long messagesSent = 0;
    String host = "127.0.0.1";
    String port = "11005";

    WSclient[] clientArr = new WSclient[clients];
    for (int i = 0; i < clientArr.Length; i++)
    
        clientArr[i] = new WSclient(host, port);
    

    Random random = new Random();
    var sw = Stopwatch.StartNew();

    for (int i = 0; i < messages; i++)
    
        clientArr[i % clients].Send("Message " + i);
        messagesSent++;
    
    sw.Stop();

    Console.WriteLine("Clients " + clients);
    Console.WriteLine("Messages to Send" + messages);
    Console.WriteLine("Messages Sent " + messagesSent);
    Console.WriteLine("Time " + sw.Elapsed.TotalSeconds);
    Console.WriteLine("Messages/s: " + messages / sw.Elapsed.TotalSeconds);
    Console.ReadLine();

    for (int i = 0; i < clientArr.Length; i++)
    
        clientArr[i].Disconnect();
    

    Console.ReadLine();

但是,服务器接收到的消息较少(即使是很小的数字,例如 100)。或者有时会收到多条消息作为一条消息,例如:

Message1 = abc Message2 = def

接收为 = abcdef

我正在尝试或多或少地复制 here 显示的示例。目前,服务器和客户端都在本地运行。关于问题是什么或如何改进测试方法的任何想法?

【问题讨论】:

【参考方案1】:

github 项目中有两个未解决的问题听起来很相似:

Server drops inbound messages and receives corrupted input JSON messages truncated

其中一位评论者称Fleck 的运气更好

【讨论】:

好的,这对我来说不是问题,感谢您的帮助,我将尝试使用替代的网络套接字实现。【参考方案2】:

TCP 是流式协议,而不是面向消息的协议。这意味着接收者负责查找流中包含的每条消息的开始/结束。这也意味着接收者不仅负责将大量读取拆分为单个消息,而且有时它还需要收集小型读取,直到收到完整的消息。提供的示例消息显示发送了两封邮件并收到了两封,但显然您的服务器无法确定一封邮件在哪里结束,而另一封邮件从哪里开始。您可能需要为您的数据添加某种内部协议来标记每条消息的开始和结束。如果您的消息总是完全相同的长度,您可以只使用大小,但这不太可靠,并且可能难以可靠地移植到其他通信方法(如果在程序生命的后期需要 - 这几乎总是会发生给我!)

如果您的消息长度都相同,接收者通常可以将读取大小(不过我不知道您的库)限制为该长度,这样就不需要分离大读取。但是,由于 TCP/IP 堆栈可能将数据从流中收集到数据包中以在物理网络上传输的方式,仍然可能发生 读取。如果您不想编写集合代码,那么您需要找到一个 peek 函数,它会告诉您在实际执行读取之前 可以读取多少数据,让您的程序等待,直到至少有足够的时间阅读整条消息。

【讨论】:

Websocket protocol 是建立在 TCP 之上的消息传递协议。它已经包含了必要的框架。 @lnmx 从发送/接收的示例消息看来,该功能没有被使用,所以我的回答可能仍然有助于马特通过提醒他该功能的存在来找到该功能。希望。 这可能是问题所在,但是由于我正在使用的库,我认为我无法实现解决方案,因此仅切换库可能更容易。不过,感谢您提供的信息 +1 关于 TCP 的事实是正确的,但答案与问题不符。这可能会让那些对 websocket 有问题的人感到困惑。

以上是关于Web Socket 消息未全部接收的主要内容,如果未能解决你的问题,请参考以下文章

socket.io 客户端未从服务器接收消息

Android 客户端未从 node.js 服务器接收到 socket.io 消息

客户端未使用 websockets 接收所有消息

Ruby 套接字未接收到所有消息

socket接收消息拼接

Python Socket - 同时发送/接收消息