Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

WebSocket

Autor: Piotr Karpiuk o środa 10. Listopad 2010

Aby dowiedzieć się więcej o innych zagadnieniach związanych z nowym standardem HTML5, zajrzyj do osobnego artykułu.

HTTP jest protokołem zapytanie-odpowiedź z własnymi narzutami na niepotrzebne nagłówki, przez co słabo się nadaje na realizację kanału full-duplex czasu rzeczywistego. Podejmowano różne rozpaczliwe próby rozwiązania problemu – wszystkie słabo skalowalne, nadmiernie obciążające sieć i procesor, wolne, nierzadko podatne na błędy i skomplikowane:

  • Ajax polling,
  • Ajax long-polling: polling wstrzymujący odpowiedź serwera gdy nie ma danych do przesłania,
  • streaming: serwer odsyła odpowiedź ale nie sygnalizuje jej końca, przez co przeglądarka odbiera kolejne „uzupełnienia” będące kolejnymi komunikatami od serwera; problemem są tu serwery proxy po drodze, które nie widząc końca komunikatu mogą zdecydować o jego buforowaniu; rozwiązanie to użycie TLS (SSL) lub powrót do Ajax long-polling przy wykryciu buforujących proxy po drodze; Comet (zwany też Ajax Push, Reverse Ajax, Two-way web, HTTP streaming, HTTP server push) – to zbiorczy termin dla zestawu różnych technik sprowadzających się do tego że długo realizowana odpowiedź na żądanie HTTP z przeglądarki pozwala serwerowi WWW wpychać kolejne dane do klienta.

HTML5 WebSocket definiuje kanał komunikacyjny full-duplex przeznaczony dla sterowanych zdarzeniami aplikacji WWW „czasu rzeczywistego”. W chwili obecnej implementowany w Chrome 4.0+, Firefox 4.0+ i Safari 5.0+ (nie ma w MSIE i Operze).

Jeśli serwer WWW implementuje standard, wówczas w dowolnym momencie istniejące połączenie HTTP można łatwo przekształcić w połączenie WebSocket. Wystarczy, że przeglądarka wyśle do serwera komunikat HTTP:

    GET /demo HTTP/1.1
    Host: example.com
    Connection: Upgrade
    Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
    Sec-WebSocket-Protocol: sample
    Upgrade: WebSocket
    Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
    Origin: http://example.com

    [8-byte security key]

Serwer odpowiada:

    HTTP/1.1 101 WebSocket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    WebSocket-Origin: http://example.com
    WebSocket-Location: ws://example.com/demo
    WebSocket-Protocol: sample

    [16-byte hash response]

Od tej pory komunikaty mogą być wymieniane asynchronicznie w obie strony. Każdy komunikat jest zwykłym łańcuchem UTF-8 poprzedzonym bajtem 0x00 i zakończonym bajtem 0xFF.

Rozważmy zyski. Polling HTTP co sekundę wymaga na same nagłówki ok. 1KB, co w przypadku 1000 klientów wymaga przepustowości 8Mbps, dla 10.000 klientów 80Mbps, a dla 100.000 klientów 800Mbps. Komunikat WebSocket nakłada tylko 2 bajty narzutu, co oznacza odpowiednio 0.015Mbps, 0.153Mbps i 1.526Mbps. Szacuje się, że WebSocket w porównaniu z pollingiem HTTP redukuje obciążenie sieci do 500 razy, a opóźnienie do 3 razy.

Istnieją już implementacje serwerów WebSocket, m.in.:

Jeśli chcesz zaimplementować własny serwer (co wcale nie jest trudne), możesz zajrzeć do oficjalnej specyfikacji protokołu przypominającej dokument RFC.

Aby sprawdzić czy przeglądarka obsługuje standard WebSocket:

    if( window.WebSocket ) { ... }

Aby zestawić połączenie WebSocket wystarczy podać URL, przy czym można się łączyć do innego serwera niż serwer WWW z którego załadowano stronę HTML:

    w = new WebSocket( "ws://localhost:8080/echo" );

(protokół ws oznacza WebSocket, a wss oznaczałby secure WebSocket).
Teraz wystarczy zarejestrować słuchaczy dla zdarzeń otwarcia i zamknięcia gniazda oraz nadchodzących komunikatów. Do wysyłania komunikatu służy metoda send():

    w.onopen = function() { console.info( "open" ); }
    w.onmessage = function(e) { console.info( d.data ); }
    w.onclose = function() { console.info( "closed" ); }
    ...
    w.send( "Komunikat" );
    ...
    w.close();
Share and Enjoy:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Śledzik
  • Blip
  • Blogger.com
  • Gadu-Gadu Live
  • LinkedIn
  • MySpace
  • Wykop

Zostaw komentarz

XHTML: Możesz użyć następujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>