3

Nagle のアルゴリズムはクライアント側でも無効にする必要がありますか? この場合、JavaScript だけで Nagle のアルゴリズムを無効にする方法は見つかりませんでした。

Raspbian OS でホストされている PHP CLI サーバー (Windows 7 と Ubuntu でも同じ結果でホストされています) から、websocket 経由でデータをストリーミングしようとしています。このサーバーはソケットを正常に作成し、複数の接続を受け入れ、TCP_NODELAY フラグを設定しました (socket_get_option のみで検証)。

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
socket_set_option($sock, SOL_SOCKET, TCP_NODELAY, 1);

ほとんどのプラットフォームでは、この TCP_NODELAY フラグが設定されているかどうかに関係なく、データは凝集することなくストリーミングされます。ただし、Windows 7 の Chrome と Firefox では、データはチャンクで到着します(明らかな 0.2 秒の遅延があります)。Windows 8 、Linux、iOS、および Windows 7 の Internet Explorer 11: この問題はまったく発生しません

http://www.13willows.com/hovelme/script/serverControl.php これがテスト Web サイトです。[接続] をクリックし、[ゲームを表示] をクリックすると、現在のパケットが 50 ミリ秒ごとに 1 から 20 に着実に増加するのがわかります。 . ただし、一部のクライアントでは、約 200 ミリ秒ごとに一度に 4 つジャンプします。

これを止めるためのアイデアはありますか?node.js / socket.io を使用すると、このような問題が修正され、ユーザーのブラウザーからコードを実行できるようになりますか?

4

1 に答える 1

0

少なくとも Chrome は、すべての WebSocket ソケットに対して Nagle アルゴリズムを無効にしているようです。

Chrome では、すべての TCP ソケットで Nagle アルゴリズムも無効になっていることに注意してください。

しかし、低遅延を保証するために、両側で NODELAY オプションを有効にする必要があるようです。

このような方法を使用して、すべてのプラットフォームで Nagle を既に無効にしていますが、遅延 ACK を無効にすることはできません (または、少なくとも Windows では無効ではありません。他の場所で無効にすることは確かに可能です)。

ソース

Chromium ソース コードはこれを証明しているようです (ただし、私は Chromium 開発者ではないため、上記のコメンテーターの 1 人が言ったように、すべての 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

于 2022-02-05T22:10:27.887 に答える