WebSocket

A WebSocket internetes technológia, ami kétirányú, duplex kommunikációs csatornák kiépítését teszi lehetővé egyetlen TCP protokollon keresztül. Kifejlesztésének fő motivációja volt, hogy a webböngészőben futó alkalmazás képes legyen a szerverrel való kétirányú kommunikációra a Comet barkácsmegoldásai[1] (több HTTP-kapcsolat nyitva tartása; XMLHttpRequest vagy <iframe> és long polling) nélkül, bizonyos esetekben a szükségtelen fejlécforgalom akár 500:1-1000:1 arányú, a késleltetés 3:1 arányú csökkentésével.[2] Korlátozó tényező volt a HTTP 1.1 specifikációja, mely kimondja, hogy a böngészőnek legfeljebb két kapcsolatot szabad egyidejűleg nyitva tartani a webszerver felé.[3] A WebSocketet megelőzően nem volt lehetséges komplexebb, a szerverrel valós idejű kommunikációt igénylő webes alkalmazást, pl. csevegő alkalmazások, árfolyamkijelzők, játékok, levelezőkliensek a HTTP-kapcsolat nem rendeltetésszerű használata nélkül megvalósítani.[4]

Bár a fő cél a webböngészőkben és webszervereken való implementáció, más kliens-szerver megoldásokban is használható. A WebSocket API-t a W3C szabványosítja, míg a WebSocket protokollt az IETF az RFC 6455-ben írja le.[5] Mivel nem otthoni környezetben a nem a 80-as TCP portra irányuló kapcsolatokat a rendszergazdák sok esetben blokkolják, a WebSocket arra is használható, hogy a korlátozások ellenére – és a protokollból eredő némi vízfej mellett – az egyetlen hozzáférhető TCP porton több WebSocket-szolgáltatást multiplexáljanak.

A kliensoldalon a WebSocketet eddig a Firefox 4, a Google Chrome 4, az Opera 11 és a Safari 5 böngészőkben valósították meg, továbbá része a Safari mobil verziójának az iOS 4.2-ben.[6] Az OS7-ben lévő BlackBerry Browser is támogatja.[7] A protokoll korai verziójának sebezhetősége miatt a Firefox 4, Firefox 5 és Opera 11 böngészőkben alapértelmezetten kikapcsolták.[8][9] A WebSocket protokoll hibáját a -07 verzióban orvosolták, amit a Firefox 6-ban,[10] illetve a -10 verziót a Chrome 14-ben implementáltak és alapértelmezetten be is kapcsoltak.[11]

Létezik továbbá a Google Chrome-nak egy parancssori kapcsolója (--enable-websocket-over-spdy), ami lehetővé teszi a WebSocket SPDY protokoll fölötti korai, kísérleti implementációjának használatát.[12]

Kézfogás

A WebSocket kapcsolat kiépítéséhez a kliens egy kézfogási kérelmet küld (handshake request), amire a szerver kézfogási válasszal (handshake response) felel, ahogy az alábbi példák mutatják:

draft-ietf-hybi-thewebsocketprotocol-00

Ez a korábbi kézfogási mechanizmus; lejjebb olvashatók az újabb verziók.

A kliens kérelme a szervernek:

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

^n:ds[4U

A szerver válasza:

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

8jKS'y:G*Co,Wxa-

A Sec-WebSocket-Key1, a Sec-WebSocket-Key2 mezők, és az utánuk következő 8 bájt egy-egy véletlenszerű token, amiből a szerver a kézfogás befejezésekor 16 bájtos tokent állít össze, amivel igazolja, hogy elolvasta a kliens kézfogását.

A 16 bájtos token a következőképp áll össze: a szerver az első kulcs számjegyeit összeolvassa, majd elosztja a szóközök számával. Ezt megismétli a második kulccsal is. Az eredményül kapott két számot (mindkettő big-endian előjel nélküli 32 bites egész) összeolvassa, és hozzáírja a kliens kérésének utolsó nyolc bájtját. Végül az így kapott string MD5 ellenőrzőösszegét képezik.[13]

A kézfogás a HTTP-re hasonlít, de valójában nem az. Lehetővé teszi azonban, hogy a szerver a kézfogási kérelmet a HTTP protokoll szerint értelmezze, majd átválthasson a WebSocket használatára.

Ha kiépült a kapcsolat a WebSocket adatkereteket full duplex módon lehet a kliens és a szerver között továbbítani. A full duplex szöveges keretek minimálisan két bájtnyi keretinformációt tartalmaznak: minden keret 0x00 bájttal kezdődik és 0xFF bájttal ér véget, a kettő között pedig UTF-8 kódolású szöveges adatot tartalmaz. A bináris keretek JavaScript alapú klienssel nem támogatottak. A WebSocket szöveges keretei lezáró bájtot (terminator) használnak, míg a bináris keretek a fejlécben meghatározott fix hosszúságúak.

draft-ietf-hybi-thewebsocketprotocol-06

A WebSocket 06-os draftjában némileg megváltozott a kliens és szerver közötti handshake pontos menete:

GET /ws HTTP/1.1
Host: pmx
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 6
Sec-WebSocket-Origin: http://pmx
Sec-WebSocket-Extensions: deflate-stream
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==

A szerver válasza:

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

A kliens egyetlen, base64-kódolású Sec-WebSocket-Key kulcsot küld el. A szerver ehhez a következő mágikus stringet fűzi hozzá: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", ezt SHA1-gyel hasheli és újra base64-gyel kódolja. Lényeges, hogy a kliens által base64-gyel kódolt Sec-WebSocket-Key kulcsot nem dekódolja a szerver. Az eredmény a szerver a fejléc "Sec-WebSocket-Accept" mezőjében küldi vissza.

Példa a Sec-WebSocket-Key → Sec-WebSocket-Accept átalakításra:

  • Az "x3JJHMbDL1EzLkh9GBhXDw==258EAFA5-E914-47DA-95CA-C5AB0DC85B11" kiindulási string SHA1-gyel kódolva a "1d29ab734b0c9585240069a6e4e3e91b61da1969" hexadecimális értéket adja.
  • Ez base64-gyel kódolva, például a következő Unix paranccsal: `printf "\x1d\x29\xab\x73\x4b\x0c\x95\x85\x24\x00\x69\xa6\xe4\xe3\xe9\x1b\x61\xda\x19\x69" | base64` megadja a válaszstringet: "HSmrc0sMlYUkAGmm5OPpG2HaGWk="

Proxy-átjárhatóság

A WebSocket protokoll kliensoldali implementációi megpróbálják detektálni, hogy a user agent (tehát a kapcsolódást végző program) proxy használatával kapcsolódik-e; ha igen, a HTTP CONNECT metódusával próbálnak állandó csatornát létrehozni.

Bár a WebSocket protokoll nem foglalkozik a proxyszerverekkel és tűzfalakkal, a használt kézfogási mechanizmus a HTTP-vel kompatibilis, ezért a HTTP-szerverek megoszthatják alapértelmezett HTTP és HTTPS portjaikat (80 és 443) egy WebSocket átjáróval vagy szerverrel. A WebSocket protokoll definiál egy ws:// és wss:// URI-prefixumot a WebSocket, illetve WebSocket Secure kapcsolat jelzésére. Mindkét séma a HTTP 1.1 upgrade mechanizmusát használja a WebSocket protokollra való átváltáshoz. Ez egyes proxykkal problémamentesen működik, mások megakadályozzák a WebSocket kapcsolat kiépülését. Egyes esetekben a proxyszerver konfigurálására, vagy upgrade-jére lehet szükség.

Ha titkosítatlan WebSocket forgalom halad át akár egy explicit, akár egy transzparens proxyn, jelenleg a proxy megfelelő viselkedésétől függetlenül, a kapcsolat jó eséllyel nem tud kiépülni; a WebSocket elterjedésével valószínűleg egyre több proxy fogja felismerni és átengedni a WebSocketet. Ebből következik, hogy a titkosítatlan WebSocket kapcsolatokkal csak a legegyszerűbb hálózati topológiákban érdemes kísérletezni.[14]

A titkosított WebSocket esetén a WebSocket Secure kapcsolatnál alkalmazott Transport Layer Security (TLS) biztosítja, hogy explicit proxy szervernél ki legyen adva a HTTP CONNECT parancs. Ez kiépít egy csatornát, ami a HTTP proxyn keresztülengedi az alacsony szintű, végponttól végpontig terjedő TCP-alapú kommunikációt a WebSocket Secure kliens és a WebSocket szerver között. Transzparens proxyk esetén a böngésző nincs tudatában a proxy jelenlétének, így HTTP CONNECT-et sem küld. Mivel azonban a forgalom titkosított, a köztes, transzparens proxy szerverek jó esetben egyszerűen keresztülengedik a titkosított forgalmat, így nagyobb az esély a sikeres WebSocket kapcsolat kiépülésére, mint a titkosítatlan esetben. A titkosítás némi erőforrást felemészt, de nagyobb esélyt kínál a sikerre.

Egy 2010 közepi draft verzió (version hixie-76) elrontotta a reverse proxykkal és átjárókkal való kompatibilitást, mivel a fejlécek után 8 bájtnyi kulcsadatot küldött anélkül, hogy ezt megjelölte volna egy Content-Length: 8 fejlécsorral.[15] Ez az adat így eldobásra kerülhetett, ami meghiúsítja a kapcsolódást. Az újabb draft verziók (pl. a hybi-09[16]) a kulcsadatot a Sec-WebSocket-Key fejlécben helyezik el, ami hatásosan megoldja ezt a problémát.

URL-séma

A WebSocket protokoll specifikációja két új URI sémát határoz meg: ws: és wss:,[17] a nyílt, illetve a titkosított kommunikációhoz. A séma nevén túl a használt URI komponensek az URI általános szintaxisának (RFC 3986) megfelelnek.[18]

Böngészőtámogatás

Jelenleg kliensoldalon csak a Firefox 11, a Chrome 16 és az Internet Explorer 10 böngészők támogatják a WebSocket protokoll legutolsó verzióját (RFC 6455). Egy részletes tesztjegyzőkönyvben[19] olvashatók a böngészők konkrét megfelelőségi adatai.

A Microsoft a draft-ietf-hybi-thewebsocketprotocol-04-et az Internet Explorerben a HTML5 Labs-ában található böngésző-prototípusaiban támogatja csak.[20]

Megvalósítás státusa
Protokoll Internet Explorer Mozilla Firefox Google Chrome Safari Opera NetFront
hixie-75 4 5.0.0
hixie-76
hybi-00
4.0 (KIKAPCSOLT) 6 5.0.1 11.00 (KIKAPCSOLT)
hybi-06 HTML5 Labs[21] dev[22]
hybi-07 6.0[23]
hybi-09 HTML5 Labs[24]
hybi-10 IE10 developer preview[25] 7[26] 14[27]
RFC 6455 10 PP5 11 16[28] Nightly

Fordítás

  • Ez a szócikk részben vagy egészben a WebSocket című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.

Jegyzetek

  1. Comet Daily: Independence Day: HTML5 WebSocket Liberates Comet From Hacks. [2008. július 4-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 17.)
  2. WebSocket.org: HTML5 Web Sockets: A Quantum Leap in Scalability for the Web. [2011. szeptember 23-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 18.)
  3. HTTP 1.1 specification, section 8.1.4. W3C. Hozzáférés ideje: 2011-09-17
  4. The WebSocket Protocol
  5. RFC 6455
  6. Katie Marsal: Apple adds accelerometer, WebSockets support to Safari in iOS 4.2. AppleInsider.com, 2010. november 23. (Hozzáférés: 2011. május 9.)
  7. Web Sockets API. RIM. [2011. június 10-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. július 8.)
  8. Chris Heilmann: WebSocket disabled in Firefox 4. Hacks.Mozilla.org, 2010. december 8. (Hozzáférés: 2011. május 9.)
  9. Aleksander Aas: Regarding WebSocket. My Opera Blog, 2010. december 10. [2010. december 15-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. május 9.)
  10. Dirkjan Ochtman: WebSocket enabled in Firefox 6. Mozilla.org, 2011. május 27. [2012. május 26-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. június 30.)
  11. Chromium Web Platform Status. (Hozzáférés: 2011. augusztus 3.)
  12. List of Chromium Command Line Switches
  13. The WebSocket protocol, 2010. augusztus 16. (Hozzáférés: 2011. május 9.)
  14. How Web Sockets Interact With Proxy Servers
  15. WebSocket -76 is incompatible with HTTP reverse proxies. [2011. szeptember 14-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 18.)
  16. The WebSocket protocol, draft hybi-09, 2011. június 13. (Hozzáférés: 2011. június 15.)
  17. IANA Uniform Resource Identifer (URI) Schemes
  18. http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
  19. WebSockets Protocol Test Report. Tavendo.de, 2011. október 27. [2012. április 19-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. december 10.)
  20. Microsoft's Interoperability Labs releases WebSockets-04
  21. Latest WebSockets Release Interoperates with Firefox, Eclipse's Jetty - Interoperability @ Microsoft - Site Home - MSDN Blogs
  22. hybi Firefox with WebSockets -06 demo build. [2011. augusztus 25-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 17.)
  23. Bug 640003 - WebSockets - upgrade to ietf-06+
  24. The WebSockets Prototype Gets Another Update
  25. Autobahn test suite. [2011. szeptember 25-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 17.)
  26. WebSockets - upgrade to ietf-07>
  27. Chromium bug 64470
  28. WebKit Changeset 97247: WebSocket: Update WebSocket protocol to hybi-17. Trac.webkit.org. (Hozzáférés: 2011. december 10.)

Külső hivatkozások