WebSocket is een netwerkprotocol dat full-duplex communicatie biedt over een enkele TCP-verbinding. Het WebSocketprotocol is gestandaardiseerd door de Internet Engineering Task Force in 2011 als RFC 6455 en de WebSocketAPI gemaakt in Web IDL is gestandaardiseerd door het World Wide Web Consortium.

WebSocket is ontworpen om te worden toegepast in webbrowsers en webservers. Het WebSocketprotocol is een zelfstandig op TCP gebaseerd protocol. WebSocket vertoont enige gelijkenis met HTTP, omdat de handshake van het WebSocketprotocol door HTTP-servers wordt geïnterpreteerd als een Upgraderequest. Het WebSocketprotocol maakt bidirectioneel dataverkeer mogelijk tussen webbrowsers en webservers. Dit kan doordat het protocol zorgt voor een standaard manier van dataverkeer zonder de noodzaak van een request door de webbrowser om vanaf de server data te sturen naar de browser. Daarnaast staat het protocol toe berichten heen en weer te sturen en daarbij de connectie tussentijds open te houden. Op deze manier is er een voortdurende bidirectionele conversatie tussen webserver en webbrowser. De communicatie vindt plaats over TCP-poort 80 (of TCP-poort 443 als de communicatie over TLS-versleutelde connecties gaat), wat een voordeel is in netwerkomgevingen waar poorten die niet bedoeld zijn voor het web (andere TCP-poorten dan 80 en 443) worden geblokkeerd door een firewall. Soortgelijk bidirectioneel dataverkeer is op andere niet-gestandaardiseerde manieren tot stand gebracht met stopgaptechnologieën zoals Comet.

Het WebSocketprotocol wordt momenteel ondersteund in de meeste grote browsers, waaronder: Google Chrome, Microsoft Edge, Internet Explorer, Firefox, Safari en Opera. WebSocket heeft ook webapplicaties op de server nodig om het te ondersteunen.

Overzicht bewerken

In tegenstelling tot HTTP biedt WebSocket full-duplex-communicatie. Verder zorgt WebSocket voor de mogelijkheid een stroom van berichten te sturen bovenop een TCP-verbinding. TCP zelf regelt alleen een stroom van bytes en kent geen berichtenconcept. Voor WebSocket was full-duplexcommunicatie over poort 80 mogelijk met Comet-channels. Echter, de Comet-implementatie was geen standaard. Ook was de Comet-implementatie zwaarder omdat het werkte bovenop HTTP en het was inefficiënt voor kleine berichten. Het WebSocketprotocol heeft tot doel deze problemen te overwinnen zonder de veiligheid van het web in het geding te laten komen.

De WebSocketspecificatie definieert ws en wss als twee nieuwe URI-schema's, welke gebruikt kunnen worden voor niet-versleutelde en versleutelde verbindingen respectievelijk. Buiten fragmenten en schemanaam wordt de rest van de URI-componenten gedefinieerd volgens URI generic syntax.

Met gebruik van de Development Tools van de browser kunnen ontwikkelaars WebSockethandshakes en WebSocketframes inspecteren.

Geschiedenis bewerken

WebSocket werd eerst TCPConnection genoemd in de HTML5-specificatie als vervanger voor een op TCP gebaseerde socket-API. In juni 2008 werden discussies geleid door Michael Carter, welke resulteerden in de eerste versie van het nu hetende WebSocket.

Na deze discussies is door samenwerking tussen Ian Hickson en Michael Carter in de #whatwg IRC-chatroom de naam WebSocket bedacht. Daarop volgde toevoeging aan de HTML5-specificatie door Ian Hickson en werd de toevoeging aangekondigd op de cometdaily-blog van Michael Carter. In december 2009 was Google Chrome 4 de eerste grote webbrowser die de volledige standaard met WebSocket standaard aangezet ondersteunde. De ontwikkeling van het WebSocketprotocol werd daarna van het W3C en de whatwg-groep verplaatst naar het IETF in februari 2010 met twee revisies onder controle van Ian Hickson.

Nadat het protocol werd ondersteund door meerdere browsers en standaard aangezet was, is de RFC afgemaakt onder Ian Fette in december 2011.

Protocolhandshake bewerken

Om een WebSocketconnectie te starten, stuurt de browser een WebSockethandshakerequest naar de server. De server reageert hierop met antwoord, zoals weergegeven is in de onderstaande figuur.

WebSockethandshakerequest (net zoals bij HTTP, elke regel moet eindigen met \r\n en er moet een lege regel aan het einde overblijven)

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

Serverantwoord:

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

De WebSockethandshake lijkt op een HTTP-request, zodat webservers zowel HTTP-connecties als WebSocketconnecties kunnen verwerken op dezelfde poort. Zodra de connectie is gemaakt door middel van de WebSockethandshake, wisselt de communicatie naar een bidirectioneel binair protocol, die niet meer voldoet aan het HTTP-protocol.

Naast de upgrade-headers stuurt de webbrowser ook de Sec-WebSocket-Key-header mee. Deze header bevat base64-gecodeerde willekeurige bytes die fungeren als een sleutel, de server reageert hierop met een hash van de sleutel in de Sec-WebSocket-Accept-header. Dit wordt gedaan om te voorkomen dat een cache proxy een eerder verzonden conversatie opnieuw verstuurt. Dit mechanisme zorgt niet voor enige vorm van privacy, authenticatie of integriteit. De functie die de hash maakt, voegt de volgende tekst toe: 258EAFA5-E914-47DA-95CA-C5AB0DC85B11(de Universally unique identifier van de webserver) aan de inhoud van Sec-WebSocket-Key-header (zonder de Sec-WebSocket-Key-header te decoderen vanuit base64), voert hier dan de SHA-1-hashingfunctie op uit en het resultaat wordt gecodeerd met base64.

Wanneer de connectie gemaakt is, kunnen de webbrowser en server data- of text-frames heen en weer sturen in full-duplex-modus. De data wordt voorafgegaan aan een kleine header, welke gevolgd wordt door de ladingdata. WebSocket-transmissies worden omschreven als "messages", waarbij elke message kan worden verdeeld over meerdere text-frames. Dit biedt de mogelijkheid messages te sturen waarbij de totale lengte onbekend is maar de eerste data al wel beschikbaar is (het stuurt het ene data-frame na het andere totdat het einde bereikt is en wordt gemarkeerd met de FIN bit). Met uitbreidingen van het protocol kan dit ook worden gebruikt om meerdere datastromen simultaan te versturen en ontvangen, ook wel multiplexing genoemd.

Vanuit een veiligheidsoogpunt is het belangrijk om de Origin-header te controleren tijdens het maken van een connectie vanuit de server. Zo voorkomt men Cross-Site WebSocket Hijacking-attacks, welke mogelijk zijn als de connectie wordt gecontroleerd met cookies of HTTP-authenticatie. Het is beter sleutels of vergelijkbare mechanismen te gebruiken om de betrouwbaarheid van een WebSocketconnectie te waarborgen wanneer er gevoelige informatie wordt verstuurd over de verbinding.