2012-11-14 9 views
11

Dotyczące JavaScript & Zwijanie pakietów PHP WebSocket TCP, przykład poniżej.Pakiety WebSocket TCP zbijają się razem?

Z jakiegoś powodu, podczas szybkiego wysyłania pakietów na moim VPS lub uzyskiwania dostępu do mojego hosta lokalnego przez domenę wskazującą na mój adres IP, wiele pakietów zbija się razem. Próbuję przesyłać strumieniowo, w tym przykładzie, 20 (@ 100byte) pakietów na sekundę. Na końcu serwerów rzeczywiście są wysyłane w stałym tempie, dokładnie co 50 ms, co daje 20 na sekundę. Jednak, gdy docierają do klienta, klient przetwarza nowe wiadomości co około 1/4 sekundy. Powoduje, że nowe pakiety mogą być odbierane tylko z prędkością 4 na sekundę ...

Co powoduje to zbicie się pakietów? Ten problem nie występuje, gdy wszystko za pośrednictwem localhost. Dziwniejsze jest to, że płynnie przesyła się na iPhone'a iOS Mobile Safari, bez żadnego problemu. ALE, nie działa w ogóle na PC Safari (ponieważ nie skonfigurowałem tego poprawnie do starego formatu Hixie-76 WebSocket, zakładam, że Mobile Safari używa już nowszego RFC 6455 lub nowszego JavaScript kompilator) Próbowałem wielu firm hostingowych, z dokładnie takie same wyniki za każdym razem.

Zobacz poniższy przykład hostowane na VPS inMotion za: http://www.hovel.me/script/serverControl.php

(Kliknij [Połącz] w lewo, a następnie [Zobacz mecz] po prawej stronie).

Obecny odebrany pakiet będzie przeskakiwał około 5 za każdym razem, ponieważ każde 5 pakietów jest odbieranych jednocześnie, co 1/4 sekundy. Jednak widziałem przykłady, które mogą wysyłać stały, szybki strumień pakietów. Co powoduje, że to zlepianie się/pakiety czekają na siebie?

EDIT: To musi być coś z Nagle's algorithm, który zbiera & wysyła małe pakiety razem? Będę pracował nad próbą ominięcia tego w PHP. Nawet przy tym ustawieniu TCP_NODELAY w PHP problem nadal występuje. Dlaczego działa na iPhonie, ale nie na komputerze, wciąż mnie wyrzuca ...
EDIT: Ustawienie TCPNoDelay i TcpAckFrequency na 1 w rejestrze naprawia to, ale nie mogę oczekiwać, że każdy użytkownik to zrobi. Musi być po stronie klienta, chleb o masie JavaScript.

Jak mogę mieć funkcjonalność replikacji pliku node.js "" socket.setNoDelay(true) "bez użycia node.js?

Odpowiedz

3

To jest TCP. Pomaga w oszczędzaniu pakietów IP. Część tego jest spowodowana algorytmem Nagle, ale jego część może być również spowodowana przez sieć pośrednią.

+0

Ma to sens, ale nie działa w czasie rzeczywistym, a WebSocket aktualnie nie obsługuje UDP, więc utknąłem na razie. Wiem, że istnieje obejście problemu, ale ustawienie TCP_NODELAY (wyłączenie algorytmu Walkera) za pomocą PHP nie rozwiązało go jeszcze dla mnie. Dzięki za pomoc – TheWandererLee

3

W końcu klient nie rozpoznał wyłączenia algorytmu Nagle, a jego częstotliwość potwierdzenia ustawiona na około 200 ms spowodowała, że ​​sieć pośrednicząca utrzymywała następujące pakiety w buforze. Ręczne wysyłanie wiadomości potwierdzającej na serwer za każdym razem, gdy klient odbierze wiadomość, spowoduje, że sieć natychmiast "przebudzi się" i będzie kontynuowała przetwarzanie kolejnych pakietów, zamiast przechowywać je w buforze.

Dla przykładu:

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 
}; 

To tymczasowe rozwiązanie działa, jednak To prawie dwukrotnie wykorzystanie pasma, między innymi problemy z siecią. Dopóki nie uda mi się sprawić, że WebSocket na kliencie będzie się kończyć poprawnie, zamiast czekać w gotowości na serwer ack, a sieć na natychmiastowe przekazywanie wiadomości, spowoduje to szybsze przesyłanie pakietów bez problemu z korekcją bufora.