TCP-пакеты WebSocket объединяются?

Относительно объединения JavaScript и PHP WebSocket TCP-пакетов, с примером ниже.

По какой-то причине при быстрой отправке пакетов по моему VPS или при доступе к моему локальному хосту через домен, указывающий на мой IP-адрес, несколько пакетов будут объединяться. Я пытаюсь в потоковом режиме, например, 20 (@100 байтов) пакетов в секунду. На концах серверов они действительно отправляются с постоянной скоростью, ровно каждые 50 мс, что составляет 20 в секунду. Однако, когда они попадают к клиенту, клиент обрабатывает только новые сообщения примерно каждые 1/4 секунды. Причинение новых пакетов только для получения со скоростью 4 в секунду или около того...

Что вызывает это скопление пакетов вместе? Эта проблема не возникает, когда все через localhost. Что еще более странно, так это то, что он плавно воспроизводится на iOS Mobile Safari на iPhone без каких-либо проблем. НО, это не работает вообще на ПК Safari (потому что я не настроил его для правильной работы со старым форматом Hixie-76 WebSocket, я предполагаю, что Mobile Safari уже использует более новый RFC 6455 или более новый JavaScript компилятор) Я пробовал несколько хостинговых компаний, каждый раз с одинаковыми результатами.

См. Пример ниже, размещенный на VPS InMotion: http://www.hovel.me/script/serverControl.php

(Нажмите [Connect] слева, затем [View Game] справа).

Текущий полученный пакет будет перескакивать примерно на 5 каждый раз, так как каждые 5 пакетов принимаются сразу, каждую 1/4 секунды. Тем не менее, я видел примеры, которые могут посылать постоянный, быстрый поток пакетов. Что заставляет это объединение / пакеты ждать друг друга?

РЕДАКТИРОВАТЬ: Это должно быть что-то делать с алгоритмом Nagle, который собирает и отправляет небольшие пакеты вместе? Я постараюсь обойти это в PHP. Даже с этим установленным в PHP параметром TCP_NODELAY проблема остается. Почему это работает на iPhone, а не на ПК, все равно сбивает меня с толку...
РЕДАКТИРОВАТЬ: установка TCPNoDelay и TcpAckFrequency на 1 в реестре исправляет это, но я не могу ожидать, что каждый пользователь сделает это. Должен быть JavaScript-способ на стороне клиента.

Как я могу иметь функциональность, реплицирующую node.js " socket.setNoDelay (true)", без использования node.js?

2 ответа

Решение

Это ПТС. Это помогает вам экономить на IP-пакетах. Частично это связано с алгоритмом Nagle, но частично это может быть также вызвано промежуточной сетью.

В конце концов, клиент, не распознавший отключенный алгоритм Нейгла, вместе с частотой его подтверждения, все еще установленной на уровне около 200 мс, заставлял промежуточную сеть удерживать следующие пакеты в буфере. Отправка сообщения подтверждения на сервер вручную, каждый раз, когда клиент получает сообщение, приведет к немедленному "пробуждению" сети и продолжению обработки следующих пакетов, в отличие от их хранения в буфере.

Например:

conn = new WebSocket(url);
conn.onmessage = function(evt){
    Server.send('ACKNOWLEDGE BYTES'); // Send ACK to server immediately
    dispatch('message', evt.data); //Do regular event procedures
};

Это временное решение работает, однако это почти удвоит использование полосы пропускания, среди других сетевых проблем. До тех пор, пока я не смогу заставить WebSocket на клиентских компьютерах корректно не переходить в "резервный" режим для подтверждения доступа к серверу, а сеть немедленно отправлять сообщения, это позволяет быстрее получать пакеты без проблем с буферизацией буфера.

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