WebSocket

WebSocket
logo
Platforma sprzętowa wieloplatformowy
Rodzaj protokół komunikacyjny
Licencja 2-klauzulowa licencja BSD
Strona internetowa

WebSocketprotokół komunikacyjny, zapewniający dwukierunkowy kanał wymiany danych poprzez pojedyncze połączenie TCP. Protokół WebSockets został ustandaryzowany przez IETF jako RFC 6455 w 2011 roku[1], a jego przeglądarkowe API podlega standaryzacji w W3C.

WebSockets różni się od protokołu HTTP. Oba protokoły są zlokalizowane na 7 warstwie w modelu OSI i zależą od TCP na warstwie 4. Pomimo faktu, że są one różne, standard RFC 6455 mówi, że WebSocket został zaprojektowany do działania na portach 80 i 443 przypisanych do HTTP, a także ma wspierać funkcje proxy i pośredników (intermediaries). Aby osiągnąć kompatybilność z HTTP, handshake WebSocket’u wykorzystuje nagłówek HTTP Upgrade[2], aby przełączyć komunikację z protokołu HTTP na WebSockets.

Protokół WebSocket umożliwia interakcję między przeglądarką internetową (lub inną aplikacją kliencką), a serwerem sieciowym przy niższym obciążeniu niż alternatywne rozwiązania półdupleksowe, takie jak np. odpytywanie HTTP (polling), ułatwiając przy tym znacznie przesyłanie danych w czasie rzeczywistym do i z serwera. Jest to możliwe dzięki zapewnieniu znormalizowanego sposobu wysyłania przez serwer treści do klienta bez uprzedniego żądania klienta i umożliwienia przesyłania komunikatów tam i z powrotem przy zachowaniu aktywnego połączenia. W ten sposób między klientem, a serwerem może odbywać się dwukierunkowa wymiana danych. Komunikacja odbywa się zwykle przez port TCP o numerze 443 (lub 80 w przypadku połączeń niezabezpieczonych), co jest korzystne w środowiskach, które blokują połączenia dla aplikacji innych niż przeglądarki internetowe (np. klienty Torrent, IRC). Przed pojawieniem się WebSocket’ów podobną dwukierunkową komunikację przeglądarka-serwer osiągano w niestandardowy sposób, wykorzystując technologie takie jak Comet czy Adobe Flash Player[3].

Większość współczesnych przeglądarek obsługuje WebSocket’y, w tym m.in.: Google Chrome, Firefox, Microsoft Edge, Internet Explorer, Safari i Opera[4].

W przeciwieństwie do protokołu HTTP, WebSocket zapewnia komunikację w pełnym dupleksie. Dodatkowo WebSocket umożliwia przesyłanie wiadomości na wierzchu protokołu TCP. Sam protokół TCP obsługuje strumienie bajtów bez wbudowanej koncepcji wiadomości. Przed WebSocket komunikacja na porcie 80 w pełnym dupleksie była osiągalna przy użyciu kanałów Comet, jednak implementacja Comet nie jest trywialna, a ze względu na uzgadnianie TCP i obciążenie nagłówka HTTP jest nieefektywna w przypadku małych wiadomości. Protokół WebSocket ma na celu rozwiązanie tych problemów bez naruszania założeń bezpieczeństwa sieci.

Specyfikacja protokołu WebSocket definiuje ws (WebSocket) i wss (WebSocket Secure) jako dwa nowe schematy jednolitego identyfikatora zasobów (URI), które są używane odpowiednio do połączeń nieszyfrowanych i szyfrowanych[5]. Oprócz nazwy schematu i fragmentu (tj. # nie jest obsługiwany), pozostałe komponenty URI są zdefiniowane tak, aby używały ogólnej składni URI[6].

Wykorzystując narzędzia developera w przeglądarce, twórcy stron mogą sprawdzić zarówno handshake WebSocket’u, jak i poszczególne paczki (frames)[7].

Historia

WebSocket’y zostały po raz pierwszy wymienione jako TCPConnection w bazowej specyfikacji HTML5, jako symbol zastępczy dla interfejsu (API) gniazda, opartego na protokole TCP[8]. W czerwcu 2008 roku Michael Carter przeprowadził serię dyskusji w wyniku których powstała pierwsza wersja protokołu znanego obecnie jako WebSocket[9].

Nazwa „WebSocket” została ukuta przez Iana Hicksona i Michaela Cartera podczas współpracy na kanale IRC #whatwg[10], a następnie włączona do specyfikacji HTML5 przez samego Hicksona. W grudniu 2009 r. Google Chrome 4 została pierwszą przeglądarką z pełną obsługą nowego standardu, z domyślnie włączonym API WebSocket[11]. Rozwój protokołu WebSocket został następnie przeniesiony z grup W3C i WHATWG do IETF w lutym 2010.

Po zakończeniu prac nad protokołem i jego domyślnym włączeniu w większości przeglądarek, standard RFC 6455 został sfinalizowany przez Iana Fettera w grudniu 2011 roku.

RFC 7692 wprowadził rozszerzenie kompresji wiadomości do WebSocket przy użyciu algorytmu DEFLATE.

Przeglądarki wspierające WebSocket

WebSocket został zaimplementowany w przeglądarkach: Firefox 4, Google Chrome 4, Opera 11, Internet Explorer 10 oraz Safari 5 (również w mobilnym Safari dla iOS 4.2). Z powodu luk w zabezpieczeniach WebSocket został domyślnie wyłączony w Firefoksie 4 i Operze 11 do czasu ich naprawienia[12][13]. Aktualnie wszystkie najpopularniejsze przeglądarki wspierają tę technologię[14].

Implementacja WebSocket w przeglądarkach internetowych
Protokół, wersja Data konspektu Internet Explorer Firefox (PC) Firefox (Android) Chrome (PC, iOS, Android) Safari (Mac, iOS) Opera (PC, Android, iOS) Android Browser
hixie-75 4 lutego 2010 4 5.0.0
hixie-76

hybi-00

6 maja 2010

23 maja 2010

4.0 (wyłączono) 6 5.0.1 11.00 (wyłączono)
hybi-07 22 kwietnia 2011 6[15]
hybi-10 11 lipca 2011 7[15] 7 14[16]
RFC 6455 grudzień 2011 10 11 11 16 6 12.10[17] 4.4

Przykładowy klient w języku javaScript

// stworzenie nowego obiektu typu WebSocket
const socket = new WebSocket('ws://game.example.com:12010/updates');

// metoda wywoływana w momencie stworzenia socketu
socket.onopen = function () {
  setInterval(function() {
    if (socket.bufferedAmount == 0)
      socket.send(getUpdateData());
  }, 50);
};

// metoda wywoływana w momencie otrzymania wiadomości
socket.onmessage = function(event) {
  handleUpdateData(event.data);
};

// metoda wywoływana w momencie zamknięcia gniazda
socket.onclose = function(event) {
  onSocketClose(event);
};

// metoda wywoływana w momencie, gdy socket został zamknięty z powodu błędu
socket.onerror = function(event) {
  onSocketError(event);
};

Handshake protokołu

Aby ustanowić połączenie typu WebSocket, klient musi najpierw wysłać żądanie typu handshake, dla którego serwer zwraca odpowiednią odpowiedź, jak pokazane jest to w przykładzie poniżej[18].

Zarówno w żądaniu klienta, jak i odpowiedzi serwera każda linia wiadomości kończy się znakiem nowej linii (\r\n) – identycznie jak ma to miejsce w przypadku protokołu HTTP. Dodatkowo na samym końcu żądania/odpowiedzi musi znajdować się pusta linia.

Żądanie klienta:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

Odpowiedź serwera:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

Handshake rozpoczyna się od żądania/odpowiedzi HTTP, dzięki czemu dany serwer może obsługiwać połączenia HTTP, a także WebSocket na tym samym porcie. Po nawiązaniu połączenia komunikacja przełącza się na dwukierunkowy protokół binarny, który nie jest już zgodny z protokołem HTTP.

Oprócz nagłówka Upgrade klient wysyła również nagłówek Sec-WebSocket-Key zawierający przypadkowe bajty zakodowane w standardzie base64, na co serwer odpowiada, podając hash tego klucza w nagłówku Sec-WebSocket-Accept. Ma to na celu zapobieganie sytuacji, gdzie np. serwer/proxy buforujący wyśle ponownie całą zapisaną konwersację innemu klientowi, podczas gdy ten nie miał de facto styczności z właściwym serwerem[19]. Proces polega na tym, że funkcja szyfrująca dodaje stały ciąg znaków 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 do wartości podanej w nagłówku Sec-WebSocket-Key klienta (nie jest on dekodowany z base64), a następnie stosuje algorytm szyfrujący SHA-1, by na samym końcu zakodować uzyskaną wartość używając base64[20].

Gdy połączenie jest już ustanowione, klient i serwer mogą wysyłać sobie dane w formie binarnej lub tekstowej w postaci tzw. ramek w trybie pełnego dupleksu. Sama ramka ma niewielki narzut, dodając jedynie mały nagłówek, po którym znajdują się docelowe dane[21]. Transmisje WebSocket są opisywane jako „wiadomości”, w których pojedyncza wiadomość może być opcjonalnie podzielona na kilka ramek. Pozwala to na wysyłanie wiadomości, w których dostępne są dane początkowe, ale nie jest znana pełna długość wiadomości (wysyłane są jedna ramka danych za drugą, aż do osiągnięcia końca i zakończenia bitem FIN). Dzięki rozszerzeniom protokołu można to również wykorzystać do multipleksowania kilku strumieni jednocześnie (na przykład w celu uniknięcia monopolizowania użycia gniazda dla pojedynczego dużego ładunku)[22].

Zobacz też

Przypisy

  1. I. Fette, A. Melnikov, The WebSocket Protocol, RFC 6455, IETF, grudzień 2011, DOI10.17487/RFC6455, ISSN 2070-1721, OCLC 943595667 (ang.).
  2. rfc6455 [online], datatracker.ietf.org [dostęp 2021-07-28].
  3. Adobe Flash Platform * Sockets [online], help.adobe.com [dostęp 2021-07-28], Cytat: TCP connections require a “client” and a “server.” Flash Player can create client sockets. (ang.).
  4. WebSockets – Lista Web API | MDN [online], developer.mozilla.org [dostęp 2021-07-28] (ang.).
  5. Uniform Resource Identifier (URI) Schemes [online], www.iana.org [dostęp 2021-07-28] (ang.).
  6. Ian Fette, rfc6455 [online], datatracker.ietf.org [dostęp 2021-07-28].
  7. APPENDIX A: WebSocket Frame Inspection with Google Chrome Developer Tools, [w:] Vanessa Wang, The Definitive Guide to HTML5 WebSocket, Apress, ISBN 978-1-4302-4740-1.
  8. HTML 5 [online], www.w3.org [dostęp 2021-07-28].
  9. [whatwg] TCPConnection feedback from Michael Carter on 2008-06-18 ([email protected] from June 2008) [online], lists.w3.org [dostęp 2021-07-28] (ang.).
  10. IRC logs: freenode / #whatwg / 20080618 [online], krijnhoetmer.nl [dostęp 2021-07-28] (ang.).
  11. Web Sockets Now Available In Google Chrome [online], Chromium Blog [dostęp 2021-07-28] (ang.).
  12. Wpis na blogu Firefoksa dotyczący zablokowania WebSocket.
  13. Wpis na blogu Opery dotyczący zablokowania WebSocket. [dostęp 2010-12-15]. [zarchiwizowane z tego adresu (2010-12-15)].
  14. Can I use Web Sockets [online], caniuse.com [dostęp 2017-11-15] (ang.).
  15. a b 640003 – WebSockets – upgrade to ietf-07 [online], bugzilla.mozilla.org [dostęp 2021-07-28] (ang.).
  16. 64470 – chromium – An open-source project to help move the web forward. – Monorail [online], bugs.chromium.org [dostęp 2021-07-28].
  17. Opera Developer News – A hot Opera 12.50 summer-time snapshot [online], web.archive.org, 5 sierpnia 2012 [dostęp 2021-07-28] [zarchiwizowane z adresu 2012-08-05].
  18. rfc6455 [online], datatracker.ietf.org [dostęp 2021-07-28] (ang.).
  19. FAQ – BiDirectional or Server-Initiated HTTP Wiki [online], trac.ietf.org [dostęp 2021-07-28], Cytat: The computation [...] is meant to prevent a caching intermediary from providing a WS-client with a cached WS-server reply without actual interaction with the WS-server (ang.).
  20. Opening Handshake, [w:] Ian Fette, rfc6455, datatracker.ietf.org [dostęp 2021-07-28] (ang.).
  21. Base Framing Protocol, [w:] Ian Fette, rfc6455, datatracker.ietf.org [dostęp 2021-07-28] (ang.).
  22. John A. Tamplin, A Multiplexing Extension for WebSockets [online], datatracker.ietf.org [dostęp 2021-07-28] (ang.).

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.