除非收到另一条消息,否则 Websocket 客户端在握手后无法发送

Posted

技术标签:

【中文标题】除非收到另一条消息,否则 Websocket 客户端在握手后无法发送【英文标题】:Websocket client cannot send after handshake unless another message is received 【发布时间】:2013-06-06 19:53:02 【问题描述】:

我已经在 C# Websocket 服务器上工作了一段时间了,我已经解决了一个问题,但从未解决或找到它存在的适当原因。

我测试的环境在过去一年左右的 Windows XP 和 Windows 7 上的一系列版本中一直使用 Google 的 Chrome 浏览器。我的服务器也已经在这两种操作系统上进行了测试。

我注意到的问题只发生在浏览器在 Windows XP 下运行时。 Websocket 握手完成后,浏览器/客户端无法向服务器发送数据,除非先从服务器向客户端发送消息。

我所做的只是将 Ping 帧标记到服务器握手的末尾,并且所有功能都符合预期。其他框架我也测试过,只要服务端发送消息,客户端就会正常进行。

来自服务器的消息也不需要是即时的。如果客户端尝试发送消息,它可以无限期地等待。一旦服务器向客户端发送消息,客户端就会继续。

现在,我认为我在我的 Websocket 服务器上做错了什么,但如果是这种情况,那么为什么当浏览器在 Windows 7 下运行时一切都按预期工作。我不需要向客户端在客户端向服务器发布消息之前。

作为一个非常基本的示例,如果 Chrome 从 XP 机器连接,这里的服务器代码永远不会完成;

byte[] textPound = 0x81, 0x01, 0x23;

Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 56100);
server.Bind(ip);
server.Listen(100);

byte[] buffer = new byte[1000];

Socket client = server.Accept();
int rec = client.Receive(buffer);
Handshake(buffer, ref rec);//custom function returns the handshake to the buffer
client.Send(buffer, rec, SocketFlags.None);

//client.Send(textPound);
rec = client.Receive(b);
client.Close();

只要 .Send() 被注释掉,如果 Chrome 是从 XP 机器上运行的,则无论您如何从浏览器发送消息,.Receive() 将永远不会完成。如果您要在 .Receive() 之前启动一个线程,该线程会在 x 时间后发出一个 .Send(),那么一旦发生这种情况,该过程就会完成。

有没有人经历过,或者知道为什么会这样?

编辑 -- 对于那些不知道 WebSocket 协议是什么的人;

Protocol Documentation

API Documentation

【问题讨论】:

这不是 HTTP。你为什么用浏览器来测试这个? 服务器使用WebSocket协议与网页通信,网页由浏览器查看。在这种情况下,根据浏览器所在的平台会产生不同的结果,我看看是否有人知道为什么?总之,问题取决于客户端,浏览器就是客户端,我怎么不使用浏览器来测试呢? 浏览器处理超文本传输​​协议。您在上面发布的服务器不使用 HTTP 进行通信,因此对于您发明的任何协议,不应期望浏览器的行为类似于客户端。 【参考方案1】:

如果你正在编写一个新的 WebSocket 实现,你可以看看AutobahnTestsuite。

AutobahnTestsuite 提供了一个全自动测试套件来验证 WebSocket 协议的客户端和服务器实现,以确保规范一致性和实现稳健性。

数十个项目都在使用它,并且是某种用于测试的“事实上的标准”。

披露:我是 Autobahn 的原作者,为 Tavendo 工作。

【讨论】:

以上是关于除非收到另一条消息,否则 Websocket 客户端在握手后无法发送的主要内容,如果未能解决你的问题,请参考以下文章

Websocket4Net 只接收第一条消息的回复

Websocket客户端未收到任何消息

春季启动中websocket的互斥锁

uni-app中websocket的使用 断开重连、心跳机制

在 Android 中的 Java Websocket 服务器收到消息时,未创建 Toast 消息

我在连接 websocket 时遇到问题