至少 Chrome 似乎禁用了所有 WebSocket 套接字的 Nagle 算法:
值得注意的是,Chrome 还在其所有 TCP 套接字上禁用了 Nagle 算法。
但似乎应该在两侧启用 NODELAY 选项以保证低延迟:
我们已经在所有平台上禁用了 Nagle,只使用了这种方法,但这并没有禁用延迟 ACK(或者至少它不会在 Windows 上,它肯定有可能在其他地方这样做)。
资源
Chromium 源代码似乎证明了这一点(但我不是 Chromium 开发人员,所以我只是猜测在所有 TCP 套接字上调用以下代码,正如上面的评论员之一所说):
void TCPSocketPosix::SetDefaultOptionsForClient() {
DCHECK(socket_);
// This mirrors the behaviour on Windows. See the comment in
// tcp_socket_win.cc after searching for "NODELAY".
// If SetTCPNoDelay fails, we don't care.
SetTCPNoDelay(socket_->socket_fd(), true);
// TCP keep alive wakes up the radio, which is expensive on mobile. Do not
// enable it there. It's useful to prevent TCP middleboxes from timing out
// connection mappings. Packets for timed out connection mappings at
// middleboxes will either lead to:
// a) Middleboxes sending TCP RSTs. It's up to higher layers to check for this
// and retry. The HTTP network transaction code does this.
// b) Middleboxes just drop the unrecognized TCP packet. This leads to the TCP
// stack retransmitting packets per TCP stack retransmission timeouts, which
// are very high (on the order of seconds). Given the number of
// retransmissions required before killing the connection, this can lead to
// tens of seconds or even minutes of delay, depending on OS.
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
const int kTCPKeepAliveSeconds = 45;
SetTCPKeepAlive(socket_->socket_fd(), true, kTCPKeepAliveSeconds);
#endif
}
链接到源代码行
另请参阅这个可能的解决方法 - https://stackoverflow.com/a/13406438/3167374