当对socket.send()进行快速调用时,websocket客户端间歇性地无法传输。

我有一个websocket服务器和客户端。 我可以build立连接并在两个方向上传输消息(数据)。 但是,当运行在Web浏览器中的客户端快速调用socket.send()时,服务器不会收到一些消息。 如果我减慢客户端调用socket.send()所有消息都由服务器接收。 为什么调用socket.send()的时间与间歇性丢弃消息有什么关系?

  • 在Win7,Android和iOs上运行Chrome,FireFox和Safari时会出现这种情况。 所以我不认为这是一个浏览器的错误。
  • 服务器是nodejs,但这是不相关的,因为服务器不是问题。
  • 通过快速调用,我的意思是在由requireAnimationFrame()控制的循环中进行调用。
  • 消息中的数据量很小,每个大约有40个字节。 有<10条消息,即连续调用socket.send()。 因此我不知道如何溢出一个TCP缓冲区。 但是也许?
  • websocket处于“arrays缓冲”模式。
  • socket.bufferedAmount === 0每次发送前后,无论消息是否被客户端丢弃。
  • 丢弃消息后,套接字继续在两个方向上发送消息。 例如,客户端将对socket.send()进行10次调用,服务器将看到除3和7之外的所有消息,而客户端将看到服务器发送的所有消息。
  • 在调用socket.send()之前,我已经validation了数据的完整性。 客户端代码调用var tmpArrayBuffer = new ArrayBuffer(n)在每次调用socket.send(tmpArrayBuffer)之前创build一个新的缓冲区。 所以我不认为我的客户端代码覆盖自己的缓冲区。
  • 从来没有一个错误的消息的情况。 消息要么完好无损,要么完全没有到达。 大多数消息到达。
  • 我的老C程序员认为这是一个写过缓冲区的情况。 但我不明白这是如何在JavaScript中可能的,并给予socket.send()应该是我的责任的数据的结束。
  • 我正在尝试使用MS消息分析器嗅探客户端和服务器之间的TCP通信。 然而,这是一个挑战,因为浏览器异或与websocket键意味着我必须手工解密每个消息。 慢,不好玩。 任何人有更好的主意?
  • 我的代码是一个大型项目的一部分,这个项目太大,太复杂了。 我正在研究一个可能有助于debugging问题的小testing存根。 如果/当我得到它的工作,我会张贴存根(stub)。 在任何情况下,当调用socket.send()的时间间隔较长时,较大的项目“工作”,因此我不认为这是项目中其他代码的问题。
  • 我认为这是我的理解如何使用websockets和/或TCP的问题。
  • 另一个线程提示反病毒软件(stackoverflow问题21191620)。 我试过禁用我的防病毒软件。 没有效果。 此外,Android手机和iTouch上的问题是相同的,它们并不运行防病毒软件。

这是多年来我第一次无法通过诸如计算器(stackoverflow)之类的网站在网上进行研究来解决问题。 我已经search了这个问题,直到我的手指麻木。 于是我终于在这里创build了一个帐户并发布了一个问题。 请帮忙!

具体原因是Nagle的algorithm (维基百科链接)。

具体而言,如果在短时间内发送几条消息,则TCP可以将一些消息组合到相同的TCP帧中。

这将导致在同一个IP数据包中有多个WebSocket(WS)帧。 一个performance良好的WS服务器只会在WS帧的头部有数据的情况下读入TCP帧。 理解Naglealgorithm的行为良好的WS服务器将检查另一个要解码的WS帧。

在开发基于PHP的WS服务器时遇到的一个问题是,一旦服务器读到第一条消息的末尾,如果还有其他数据,当我尝试检查新的数据时,networking堆栈会大声抱怨数据包。

性能较差的WS服务器可能会超出WS框架所说的数据结束位置,并将第二条消息的WS框架包含在第一条消息的数据中,或者以奇怪和不寻常的方式失败。

如果您绝对必须有实时通信,则TCP_NODELAY标志可用。 然而,为了大多数人的networking,让Nagle的algorithm排队和合并消息通常被认为是很好的方式。

这通常是服务器端唯一的问题,因为绝大多数WS客户端是已经知道Naglealgorithm的Web浏览器。

问题出在服务器上,而不是客户端上。 Node.js在单个callback中传递多个消息。 我的代码假设每个ws消息的callback。 这是不是一个问题,直到消息高速通过。 一旦服务器代码被修改以parsing单个消息,问题就消失了。 快乐的时光!