Отключение алгоритма Nagle на стороне клиента /JavaScript

Нужно ли отключать алгоритм Nagle на стороне клиента? Если это так, я не нашел способа отключить алгоритм Нейгла только через JavaScript.

Я пытаюсь передавать данные через веб-сокет с сервера CLI PHP, размещенного на Raspbian OS (также размещенного на Windows 7 и Ubuntu с такими же результатами). Этот сервер успешно создал сокет и принимает несколько соединений и установил флаг 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 Вот тестовый веб-сайт, нажмите "Подключиться", затем нажмите "Просмотр игры", и вы должны видеть, что текущий пакет постоянно увеличивается от 1 до 20 каждые 50 мс., Тем не менее, на некоторых клиентах он скачет на 4 за раз примерно каждые 200 мс.

Есть идеи, чтобы остановить это? Будет ли использование node.js / socket.io исправлять что-то подобное и все же позволит мне запускать код из браузера пользователя?

2 ответа

По крайней мере, Chrome, похоже, отключает алгоритм Nagle для всех сокетов WebSocket:

Стоит отметить, что Chrome также отключает алгоритм Nagle на всех своих TCP-сокетах.

Но похоже, что опция 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
}

ссылка на исходную строку

См. Также эту возможную идею обходного пути - /questions/25899581/tcp-paketyi-websocket-obedinyayutsya/25899599#25899599

Это нужно включить / отключить на обоих клиентах, однако я не знаю, как это сделать с помощью javascript; для клиентов. Я считаю, что Chrome отключает его по умолчанию для веб-сокетов, но не уверен в других браузерах.

Другие вопросы по тегам