Tuesday 15 August 2017

Sec Websocket Protokoll Binära Alternativ


Det här kapitlet handlar om att uppgradera från det mer responsiva HTML5 WebSocket. Det börjar med en kort översikt över det befintliga nätverksnätverket. Då lär du dig varför och hur du använder WebSocket. Vi ska visa att WebSocket-protokollet bokstavligen inte har någon överhead jämfört med Du kan överväga att använda WebSocket för att utveckla följande typer av applikationer. Live trading auktioner sport notifications. Live collaborative writing. Controlling medicinsk utrustning över webben. Multiplayer online games. Real-time uppdateringar i sociala strömmar. För nästa version av Save The Child-ansökan kommer vi att använda WebSocket för att genomföra ett online-auktionskommunikationslager. Målet är att låta individer och företag köpa handgjorda konsthantverk från barn. Alla intäkter kommer att gå till Spara barnet. Målet är att låta dig se Fördelarna med att ändra protokollet för klient-serverkommunikation på webben Du får tydligt se fördelarna med WebSocket över regelbundet genom övervakning av nätet arbeta trafik med sådana verktyg som Wireshark och Google Chrome Developer Tools. All serverfunktionalitet som stöder detta kapitel är skrivet i Java, med hjälp av Java API för WebSocket-referensimplementering som ingår i Java EE 7-specifikationen Vi använder den senaste Frisläppande av GlassFish-applikationsservern Om du inte känner till Java, behandla bara den här serverns inställning som en tjänst som stöder WebSocket-protokollet. För Java-utvecklare som är intresserade av att dyka in i serverns sida, tillhandahåller vi källkoden och korta kommentarer som en del av de kodprover som följer med den här boken. Vi visar och jämför serverns data push som görs med serverns skickade händelser och WebSocket. Du får också en kort översikt över valda ramar som Portal och Atmosphere som kan effektivisera din WebSocket-applikation Development. Using for Near Real-Time Applications. Protokollet är lingua franca av dagens webbapplikationer, varigenom klient-serverkommunikation baseras på begäran-respo Nse-paradigm På en låg nivå skapar webbläsare en TCP IP-anslutning för varje session. För närvarande finns tre grundläggande alternativ som utvecklare använder för val av webbläsarserverkommunikation, lång polling och streaming. Dessa alternativ är hacks ovanpå en halvduplex a envägsprotokoll för att simulera realtidsbeteende I realtid menar vi möjligheten att reagera på en händelse som det händer. Låt oss diskutera var och en av dem. När du gör en omröstning skickar din klientkod begäran till servern utifrån ett förinställt intervall för Exempelvis med hjälp av JavaScript setInterval-funktionen En del av serverns svar kommer att vara tomma om de begärda uppgifterna inte är färdiga än, vilket illustreras i pollning. Om du till exempel kör en auktion och skickar en förfrågan om att se de uppdaterade buden, Du vann inte ta emot några data om inte någon har lagt ett nytt bud. Visualera ett barn som sitter i baksätet på din bil och fråga varje minut, Har vi anlänt än och du svarar artigt, inte bara än det här liknar en Ett tomt serverns svar Det finns ingen värdefull nyttolast för det här barnet, men hon får fortfarande vissa metadata polling kan resultera i mottagande av verbala svarhuvuden som inte har någon datalast, än mindre distraherande föraren tror att servern utövar andra ansvarsområden. Figur 1 Polling . Lång polling. Lång polling se Lång polling börjar på samma sätt som polling klienten skickar begäran till servern. I det här fallet väntar servern i stället för att skicka ett tomt svar till dess att data för klienten blir tillgängliga. Om den begärda informationen är Inte tillgänglig inom det angivna tidsintervallet skickar servern ett tomt svar till klienten, stänger och återupprättar anslutningen. Vi ger dig en analogi för att jämföra val och lång polling. Föreställ dig en fest på översta våningen i en byggnad utrustad med En smart hiss som går upp varje minut och öppnar dörren om en av gästerna vill gå ner för att röka en cigarett Om ingen går in i hissen, Går till marknivå och på 60 sekunder går upp igen Detta är omröstningsscenariot Men om den här hissen gick upp och väntade tills någon faktiskt bestämde sig för att gå ner eller blev trött på att vänta, kunde vi kalla det en lång polling mode. Från specifikationen perspektivet är det legitimt att det långa pollingsläget kan verka som om vi hanterar en långsam mottagare. Därför kallas denna teknik även som Hanging GET. Om du ser en onlineauktion som automatiskt ändrar priserna som människor bjudar på objekt Ser ut som om servern trycker på data till dig Men chansen är att denna funktionalitet implementerades med hjälp av lång polling, vilket inte är en riktig dataspärr på serversidan, men dess emulering. Figur 2 Lång polling. Streaming. In streaming se streaming, skickar en klient en begäran om data Så snart servern får data redo, börjar den strömma med att lägga mer och mer data till svarobjektet utan att stänga anslutningarna. Servern trycker på data till klienten och låtsas att svaret aldrig slutar Om du till exempel begär en video från YouTube resulterar det i att strömma datagränsen efter rammen utan att stänga anslutningen. Figur 3 streaming. Polling och streaming kan användas som en återgång för äldre webbläsare som inte stöder HTML5 API-serverns server - centra händelser och WebSocket. Implementering av server-skickade händelser. Innan du dyker in i WebSocket-protokollet, låt oss bli bekant med det standardiserade sättet att genomföra serverns skickade händelser. SSE World Wide Web Consortium W3C har publicerat ett API för webbläsare för att tillåta dem Att prenumerera på händelser som skickats av en server Alla moderna webbläsare stöder EventSource-objektet, som kan hantera händelser som kommer i form av DOM-händelser. Detta är inte en begäran-respo Ns-paradigm, men snarare en enkelriktad data-push, från server till webbläsare. Prenumerera på serverns skickade händelser visar hur en webbläsare kan prenumerera och lyssna på server-skickade händelser. Exempel 1 Prenumerera på serverns skickade händelser. WebSocket-handshake. Any nätverkskommunikation som använder WebSocket-protokollet med ett öppet handslag Detta handskak uppgraderar anslutningen från WebSocket-protokollet Det är en uppgradering till meddelandebaserad kommunikation Vi diskuterar meddelanden aka frames senare i det här kapitlet. Varför uppgradera från istället för att börja med TCP som en protokollet i första hand Anledningen är att WebSocket fungerar på samma portar 80 och 443 som det är och Det är en viktig fördel att webbläsarens s-förfrågningar dirigeras via samma portar, eftersom godtyckliga anslutningar inte får tillåtas av företagets brandväggar Av säkerhetsskäl Dessutom tillåter många företagsnätverk endast vissa utgående portar och portar ingår vanligtvis i så kallade vita listor. Hög prestanda Browser Networking. by Ilya Grigorik O Reilly ger mer information om TCP och. Protokolluppgraderingen initieras av en klientförfrågan, som också sänder en specialnyckel med begäran. Servern behandlar denna begäran och skickar tillbaka en bekräftelse på uppgraderingen. Detta säkerställer att en WebSocket-anslutning kan endast upprättas med en slutpunkt som stöder WebSocket. Det här är vad handslaget kan se ut i kundens begäran. Den här klienten skickar GET-förfrågan för protokolluppgraderingen. Sec-WebSocket-Key är bara en uppsättning slumpmässiga byte The Servern tar dessa byte och lägger till denna nyckel en särskild globalt unik identifierings GUID-sträng 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 Sedan skapar den SHA1-hash från Secure Hash Algorithm från den och utför Base64-kodning. Den resulterande strängen av byte måste användas Av både servern och klienten och den här strängen vann t används av nätverksändpunkter som inte förstår WebSocket-protokollet. Sedan kopieras detta värde i Sec-Web Socket-Accept header field Servern beräknar värdet och skickar svaret tillbaka, vilket bekräftar uppgraderingen av protokollet. WebSocket-protokollet använder felkoden 400 Bad Request för att signalera en misslyckad uppgradering. Handskakningen kan också innehålla en subprotocol-förfrågan och WebSocket-versionsinformationen, men du kan inte inkludera andra godtyckliga rubriker Vi kan inte överföra auktorisationsinformationen Det finns två sätt runt detta Du kan antingen sända auktoriseringsinformationen som den första förfrågan till exempel, den unika clientId kan skickas som en del av begäranhuvudet eller HTML-wrapper Eller placera den i webbadressen som en frågeparameter under det första handslaget. Följ följande exempel. Använda WebSocket Frameworks. Working med Vanilla WebSocket API kräver att du gör ytterligare extra hushållskodning, till exempel om klientens webbläsare inte t Stödja WebSocket inbyggt, måste du se till att din kod faller tillbaka till arvet. Den goda nyheten är att det finns ramar som kan hjälpa dig med denna uppgift Sådana ramar sänker utvecklings tiden, så att du kan göra mer med mindre kod I det här avsnittet innehåller vi korta recensioner av två ramar som kan effektivisera din webbapplikationsutveckling med WebSocket. Dessa ramar försöker utnyttja Bäst stöds transport av den aktuella webbläsaren och servern samtidigt som man sparar utvecklaren från att känna till internalerna för den använda mekanismen. Utvecklaren kan koncentrera sig på programmering av applikationslogiken, samtal till ram API när dataöverföring behövs. Resten kommer att ske av ramverket. Portalen är ett server-agnostiskt JavaScript-bibliotek. Det syftar till att använda ett WebSocket-protokoll och tillhandahåller ett enhetligt API för olika transporter, lång polling, streaming, WebSocket. När du har bestämt dig för att använda WebSocket för ditt nästa projekt behöver du Kom ihåg de användare som fortfarande använder tidigare webbläsare som Internet Explorer 9 eller äldre, vilket inte stödjer WebSocket I thi s-fall bör din ansökan gradvis falla tillbaka till det bästa tillgängliga nätverksalternativet. Manuellt skriva kod för att stödja alla möjliga webbläsare och versioner kräver mycket tid, särskilt för att testa och behålla koden för olika plattformar. Portalbiblioteket kan hjälpa, som illustreras i Simple Asynkron webbapplikationsklient med Portal. Example 4 Enkel asynkron webbapplikationsklient med Portal. Det är ett läsbar format. De flesta webbläsare har inbyggda XML-läsare och parsers. XML-data kan valideras mot XSD eller DTD-schema. Ett XML-schema är En användbar språkfunktion eftersom den definierar strukturen, innehållet och semantiken i ett XML-dokument. På grund av dess mänskliga läsbarhet kan XML-schemat användas av personer som inte är programutvecklare och kan användas för att integrera system som är skrivna i olika programmeringar Languages. Its cons är följande. XML är mycket verbose För att skicka namnet på en kund, behöver du något liknande det här custname Mary custname. XML-validering på klienten är en komplex uppgift. Från och med nu finns det inga plattformsoberoende lösningar eller ett API för att utföra validering programmatiskt baserat på XSD eller DTD. XML i ett nötskal. Elliotte Rusty Harold och W Scott Means O Reilly är En välskriven bok som beskriver hela spektrumet av XML-funktioner och - verktyg. Som förklaras i usingajaxandjson står JSON för JavaScript Objektnotation, och det är sätt att representera strukturerad data som kan kodas och avkodas av alla webbläsare. JSON accepteras allmänt av Webbgemenskapen som ett populärt sätt att serialisera data Som tidigare sagt ger det ett mer kompakt sätt än XML för att representera data, och alla moderna webbläsare förstår och kan analysera JSON-data. Googles protokollbuffertar. En Google-protokollbuffert eller protobuf är en Språk - och plattformsneutral extensibel mekanism för strukturerad dataserialisering När du har definierat hur du vill att dina data ska struktureras kan du använda särskild genererad källkod för att enkelt skriva och läsa dig ur strukturerad data till och från en mängd olika dataströmmar Utvecklare kan använda samma scheman över olika miljöer. En utvecklare behöver ange hur den serialiserbara informationen måste struktureras genom att definiera protokollbuffertmeddelandetyperna i filer. Varje protokollbuffertmeddelande är en liten , Logisk registrering av information som innehåller en serie namnvärdespar Detta protokollbuffertmeddelandefil är språkagnostik Protoc-verktyget kompilerar proto-filer och producerar språkspecifika artefakter till exempel och filer. Till exempel kan du skapa en protokollbuffertproto-fil för Spara Barnet för att representera informationen om givare som visas i protokollbuffert för donationsmeddelande. Exempel 5 Protokollbuffert för donationsmeddelande. All nödvändig kod för serialisering-deserilisering av donationsmeddelandet kommer att inkluderas i Vi kommer inte att publicera den genererade koden Här, men du kan generera den här koden själv från den föregående meddelandedeklarationen. Kontrollera tillgängligheten av Protobuf-kompilator för ditt föredragna språk på protobuf wiki-sidan För att bli bekant med protobuf-tekniken, kolla dokumentationen och handledningen. Här finns några protobuf-proffs. Meddelandet kodas till ett kompakt och optimerat binärt format. Du kan hitta detaljer om kodningsformatet på Protokollbuffertens dokumentationswebbplats. Google stöder protokollbuffertar för ett brett utbud av programmeringsspråk Java, C, Python Utvecklarens community stöder det också. Användningen av protokollbuffertar är väl dokumenterad. Följande är några av cons. Binären Formatet är inte mänskligt läsbart. Även om protobuf är kompakt, särskilt när många numeriska värden överförs av en kodningsalgoritm, stöds JSON nativt av JavaScript och behöver inte kräva ytterligare parser implementation. Protobuf kräver webbläsare för att stödja binärt format, Men inte alla av dem gör just ännu Du kan hitta vilka webbläsare som stöder rå binär data vid Kan jag använda. Använda WebSocket med proxies. WebSocket-protokollet själv är inte medvetet om mellanhänder som proxyservrar, brandväggar och innehållsfilter. Proxyservrar används vanligtvis för innehållsfilning, säkerhet och företagsinnehållsfiltrering. Har alltid stött protokolluppgraderingar, men många proxyservrar verkar ha ignorerat den delen av specifikationen Innan WebSocket kom omkring användes inte uppgraderingsattributet Problemet med webbprogram som använder en långlivad anslutning som WebSocket är att proxyservrarna kan välj att stänga direktuppkoppling eller lediga WebSocket-anslutningar eftersom de verkar försöka ansluta till en oansvarig server. Dessutom kan proxyservrar buffra okrypterade svar, förutsatt att webbläsaren behöver svaret i dess helhet. Om du vill ha mer information om hur en WebSocket-aktiverad applikation måste hantera proxyer, kolla in det omfattande forskningspasset från Googles Peter Lubbers, WebSocket och Proxy Servers. Författarna till den här boken använder NGINX en enormt populär load balancer och proxy och server för att servera statiska resurser till exempel, bilder och textfiler, balansera belastningen mellan Java-servrar och utföra SSL-avlastning som gör att webbläsarens s-förfrågningar ändras till N GINX använder ett litet antal trådar för att stödja tusentals samtidiga användare, i motsats till traditionella webbservrar som använder en arbetstråd per anslutning. Nyligen började NGINX stödja WebSocket-protokollet. Lägga till en auktion för att spara barnet. Vi gav dig precis nog teori till gör din aptit för att implementera WebSocket i vår Save The Child-ansökan Målet är att skapa en auktion så att folk kan bjuda och köpa olika varor och få utbetalningarna gå till Save The Child Auctions kräver realtidskommunikation alla som är intresserade av det aktuella auktionsobjektet måste omedelbart anmälas av att vara överbjudna eller att vinna Så att vi ska använda WebSocket som ett sätt att bjuda och tillhandahålla anmälningar om ändringarna i auktionen. För att starta auktionen måste användaren välja alternativet Auktion under menyn Sätt att se Initialt laddas endast två moduler Vi inser att endast ett litet antal användare kommer att bestämma sig för att delta i auktionen, vilken från en arkitektonisk punkt Synvinkel innebär att koden som stöder auktionen ska laddas på begäran endast om användaren väljer att besöka auktionen. Därför måste vi skriva denna kod som en laddningsbar modul och du får ett praktiskt exempel på hur en webbapplikation kan Modularized. In detta kapitel fortsätter vi att använda RequireJS se modularizingjavascriptprojects som ett ramverk för modularisering Med RequireJS, kommer vi att latiska ladda några moduler om och endast om de begärs av användaren. Denna bok handlar om utveckling av användaren Gränssnitt och klientsida av webbapplikationer, så vi kommer inte att täcka alla detaljer om implementering av serverns sida men kommer att göra vår server-sidokod tillgänglig för nedladdning. Vi ska hålla vår server igång så att du kan testa gränssnittet genom att Besöker men vårt huvudmål i det här avsnittet är att visa dig hur du kan byta auktionsdata med servern och bearbeta den på klientsidan med hjälp av WebSocket. Vi ska använda Java-applikationsservern GlassFish 4, vilket är en referens rens implementering av Java EE 7-specifikationen. Författarna till den här boken är Java-utvecklare och vi har spelat in en skärmdump se att markera WebSocket-servern API Om du inte är en Java-utvecklare kanske du vill lära dig själv vilka WebSocket-servrar som finns för Ditt favoritprogramspråk eller - plattform. modularizingjavascriptprojects visar hur en webbapplikation kan skivas i flera moduler med hjälp av KravJS-ramverket. Vi ska använda det här projektet som en bas och skapa en ny, projekt-16-websocket-auktion som lägger till den nya modulen som stöder auktionen WayToGive-modulen visar koden för WayToGive-modulen. Exempel 6 WayToGive-modulen. Efter att applikationen har startat, fyller RequireJS bara de väsentliga modulerna, inloggningen och donationen, som visas. I början är endast två moduler laddade. I Google Chrome Developer Tools-konsolen kan du se det inloggnings - och donationsmodulerna rapporterar om framgångsrik laddning. Två moduler laddas under programmet Starta spara programmet, bekräftar att dessa moduler utför ett fint klick på knappen Donate Now, avslöjar formuläret och genom att klicka på knappen Logga in görs fältet ID och lösenord synligt. 4 Initialt laddas endast två moduler. Figur 5 Två moduler laddas under programmet Starta spara barnet. Nå klicka på W Ay Att ge meny och hålla koll på Utvecklarverktygskonsolen se Auktionskontrollerna laddas och återges Du kommer att se WayToGive-modulen som rapporterar om dess laddning och rendering. Figur 6 Auktionskontrollerna laddas och återges. När användaren klickar Vägen till Ge, KravJS-ramverket måste ladda koden på webbsockelbaserad auktionsmodul. Lägga till väg att ge modulen presenterar kodfliken från JavaScript-filen. Ingångspunkten för vårt Spara barn-programmet. Så här laddar den modulen efter behov. modularizingjavascriptprojects för en RequJS refresher. Example 7 Laddar sättet att ge modulen. Formera förfrågningsmeddelandet Du kan hitta detaljerna i meddelandesformatet i Skapa Spara-barns Auktionsprotokoll. Kontrollera WebSocket-objektstatus Om WebSocket är öppet readyState 1, Ansökan kan skicka ett meddelande Om inte, loggar denna kod helt enkelt offlinemeddelandet på konsolen. I den verkliga världen borde du alltid visa det här meddelandet på användarens s Användargränssnitt Om dina användare arbetar på instabila nätverk som mobil eller 3G, vill du definitivt inte förlora några bitar av data. Det är en bra idé att använda det lokala lagringsprogrammet API, se mockinguptheapp för att fortsätta data lokalt tills applikationen återkommer online och skickar in data. Användaren kan välja auktionspartiet från kombinationsrutan och se bilderna. Konsolen loggar inkomna meddelanden som innehåller en lista med auktionsobjekt som visar vad som visas på konsolen medan siffror och visar innehållet på fliken Nätverk för Båda bilderna. Figur 7 Konsolen loggar inkomna meddelanden som innehåller en lista med auktionsobjekt. Figur 8 Genom att använda nätverksfunktionen i DevTools kan vi övervaka WebSocket-ramar. Bild 9 Köparen kan välja ett annat objekt som ska buda. Övervaka WebSocket Traffic genom att Använda Chrome Developer Tools. Läs igenom den praktiska användningen av teorin som beskrivs i WebSocket handshake. Med hjälp av Chrome Developer Tools kan du övervaka information om det ursprungliga handslaget, som visas i Initial WebSocket handskakning i Chrome DevTools Övervakning WebSocket-trafik i Chrome Developer Tools är på något sätt inte så annorlunda än övervakningsförfrågningar. Trafiken kan ses på fliken Nätverk efter att du har valt sökvägen till WebSocket-ändpunkten i den vänstra panelen. Du kan Klicka också på WebSockets längst ner till höger om du bara visar WebSocket-ändpunkterna Klicka på fliken Ramar i den högra panelen så att de faktiska bilderna utbyts mellan klienten och servern, som visas i Övervakning av WebSocket-ramar i Chrome Developer Tools De vitfärgade raderna representerar inkommande data de i grön eller grå på papper indikerar utgående data. Figuration 10 Initial WebSocket handskakning i Chrome DevTools. Figure 11 Monitoring WebSocket-ramar i Chrome Developer Tools. For mer information kan du navigera Google Chrome till den hemliga URL-krom-nätinterna som ger en hel del användbar information, se Figurer och Du kan hitta dokumentation om nätinterna i Chromium Design Documents. Figure 1 2 Detaljer om det första handslaget i Chrome-nätverket. Google-utvecklarverktyg visar bara dataens längd Men Chrome-internetter visar storleken på WebSocket-ramen, Utvecklarverktyg och nätinterna, jämför vid sidan av sidan synpunkter på nätinterna och utvecklingsverktyg Som du lärt dig tidigare i detta kapitel är den totala storleken på ramen något annorlunda än storleken på nyttolasten. Det finns några fler byte för ramhuvudet Dessutom kommer alla utgående meddelanden att maskeras av webbläsaren se WebSocket-ramanatomi Denna rammask kommer att överföras till servern som en del av ramen själv, vilket skapar ytterligare 32 bitar 4 byte av overhead. Figur 13 Detaljer för uttaget. Figur 14 Utvecklarverktyg och nätverks - internals, sida vid sida. Sniffing WebSocket Frames med Wireshark. Wireshark är ett kraftfullt och övergripande övervakningsverktyg för att analysera nätverkstrafik. Du kan ladda ner den från Wiresharks hemsida. För att börja fånga WebSocket tr Affic på localhost välj loopback-nätverksgränssnittet från den vänstra panelen och klicka på Starta se huvudbilden för Wireshark-programmet. Bild 15 Wireshark-programmets huvudvy. Wireshark fångar all nätaktivitet Du kan ställa in ett filter för att bara se de data du är i Intresserad Vi vill fånga och TCP-trafik på port 8080 eftersom vår WebSocket-server Oracle s GlassFish körs på den här porten se Filter setup Ange i filter textrutan och klicka på Apply. Figure 16 Filter setup. Now Wireshark är redo att sniffa ut trafiken av vår ansökan Du kan starta auktionssessionen och placera bud När du är klar med auktionen kan du återvända till Wireshark-fönstret och analysera resultaten. Du kan se den första handskakts-GET-förfrågan i GET-förfrågan för protokolluppgradering och uppgraderingssvaret i GET-svaret med protokolluppgradering. Figur 17 GET-förfrågan för protokolluppgradering. Figur 18 GET-svaret med protokolluppgradering. Efter den framgångsrika anslutningsuppgraderingen kommer Wire haj fångar strömmen så här rapporterar den WebSocket s-trafik på 8080-porten Högerklicka på den här raden och välj Följ TCP Stream, som visas i Följ TCP Stream-menyn. Figur 19 Följ TCP Stream-menyn. På nästa skärm kan se detaljerna i WebSocket-ramen se En WebSocket-ram Vi tog denna skärmdump strax efter att auktionsansökan startat Du kan se data med listan över tillgängliga auktioner De utgående data visas i rött och inkommande data visas i blått. 20 En WebSocket-ram. Den skärmdump som visas i hela auktionssamtalet togs efter att auktionen stängdes. Du kan se alla data som skickas via WebSocket-anslutningen. Bild 21 Hela auktionssamtalet. Upprätta Spara barns Auktionsprotokoll. Eftersom WebSocket är bara Ett transportprotokoll måste vi komma fram till ett protokoll på applikationsnivå som anger hur auktionsmeddelanden ska formateras i klient-serverns interaktion. Så här bestämde vi oss för att göra det. Kunden s co De kopplar till WebSocket-ändpunkten på servern. Klienten s-kod skickar AUCTIONLIST-meddelandet för att hämta listan över pågående auktioner. Efter auktionen slutar servern meddelandet med de slutliga auktionsresultaten Om wining-användaren är online och ansluten Till auktionsservern kommer den användaren att få ett meddelande med grattis. Andra deltagare kommer att få beklagan. Du vann inte meddelandet. Det här är ganska mycket. Koden som behövs för att implementera klientens sida av auktionen är minimal. Efter anslutningen och uppgraderingen är klar, är det mesta av behandlingen klar i meddelandebehandlaren på WebSocket-objektets onmessage. Efter att ha läst det här kapitlet bör du se fördelarna med att använda WebSocket-protokollet i webbapplikationer. I många fall är WebSocket ett ultimat sätt för Förbättra applikationsprestanda genom att minska nätverks latens och ta bort huvudet på rubrikerna. Du lärde dig att integrera WebSocket-baserad funktionalitet i exis ting ansökan Spara barnet Det är inte nödvändigt att göra kommunikation av webbapplikationen via WebSocket Använd detta kraftfulla protokoll när det förbättrar prestandan och responsen i din ansökan. Som en fördel har du lärt dig hur du använder Google-nätverksövervakningsfunktionerna Utvecklingsverktyg för Chrome och Wireshark genom att snyta WebSocket-trafiken Du kan inte underskatta vikten av övervakningsverktyg, som är de bästa vännerna för webbutvecklare. Den här klassen representerar en WebSocket-server. Det utökar EventEmitter. new callback. host Värdnamnet där du ska binda Server. port Porten där du ska binda servern. backlog Den maximala längden på köen av väntar connections. server En för skapad server. verifyClient En funktion som kan användas för att validera inkommande anslutningar Se beskrivning nedan. handleProtocols En funktion som kan vara Används för att hantera WebSocket-subprotokoll Se beskrivning nedan. path Acceptera endast anslutningar som matchar denna path. noServer Aktivera inte se rver mode. clientTracking Anger om du vill spåra clients. perMessageDeflate Aktivera inaktivera permessage-deflate. maxPayload Den maximala tillåtna meddelandestorleken i byte. Skapa en ny serverns förekomst En av portserver eller noServer måste tillhandahållas eller ett fel kastas. Om du vill verifiera Client är inte inställd så är handslaget automatiskt accepterat Om det är försedd med ett enda argument så är det. origin Värdet i Origin-rubriken som anges av client. req Klienten GET request. sure är sann om eller är inställd. Returvärdet Boolean av funktionen bestämmer huruvida handshake ska accepteras eller inte. Omclient är försedd med två argument då de är. info Samma som ovan. cb En återuppringning som måste ringas av användaren vid inspektion av informationsfälten Argument i denna återuppringning är. resultat Om du inte vill acceptera handskakningen. När resultatet är felaktigt bestämmer fältet felstatuskoden som ska skickas till klienten. När resultatet är felaktigt bestämmer detta fältet orsaken ph rase. If handtagetProtocols är inte inställt så accepteras handslaget automatiskt, annars tar funktionen ett enda argument. protocols Listan över WebSocket-subprotocols angivna av klienten i Sec-WebSocket-Protocol-header. If returnerat värde är falskt då handslaget är avvisas med 401-statuskoden, annars anger det returnerade värdet värdet på Sec-WebSocket-protokollhuvudet i 101 response. perMessageDeflate kan användas för att styra uppträdandet av permessage-deflate-förlängningen. Utvidgningen är inaktiverad när falskt. ett objekt tillhandahålls då det är förlängningsparametrar. serverNoContextTakeover Oavsett om du vill använda kontext ta över eller inte. clientNoContextTakeover Värdet som ska beställas till klienterna om du vill använda kontext ta över eller inte. serverMaxWindowBits Värdet av windowBits. clientMaxWindowBits Värdet på max windowBits till uppmanas till clients. memLevel Värdet av memLevel. threshold Payloads mindre än detta kommer inte att komprimeras Standard s till 1024 byte. Om en egenskap är tom används antingen en erbjuden konfiguration eller ett standardvärde. När ett fragmentat meddelande skickas längs det första fragmentets längd jämfört med tröskelvärdet. Detta bestämmer om komprimering används för hela meddelandet. läggas till som en lyssnare för lyssningsevenemanget när servern skapas internt och det är när portalternativet är tillgängligt. Inmatat när handslaget är klart är uttaget ett exempel på WebSocket. Anslutningen är closed. new WebSocket-adress, protokoll, alternativ adressadress Den URL till vilken connect. protocols ska lista Listan över subprotocols. protocol Värdet av Sec-WebSocket-protokollet header. perMessageDeflate Aktivera inaktivera permessage-deflate. localAddress Lokalt gränssnitt för att binda för nätverksanslutningar. protocolVersion Värde för Sec-WebSocket - Version header. headers Ett objekt med anpassade rubriker för att skicka tillsammans med request. origin Värdet av originalen eller Sec-WebSocket-Origin-huvudet beroende på protokollVersio n. agent Använd det angivna Agent. host-värdet för den host-header. family-IP-adressfamiljen som ska användas under värdnamnssökningen 4 eller 6.checkServerIdentity En funktion för att validera serverns värdnamn. rejektUnderbehörig Verifiera eller inte serverns certifikat. passphrase Lösenordsfrasen för privat nyckel eller pfx. ciphers Ciphren att använda eller utesluta. cert Certifikatnyckeln. koden Den privata nyckel. pfx Den privata nyckeln, certifikatet och CA certs. ca-parametrarna för betrodda certifikat. perMessageDeflate är desamma av servern, den enda skillnaden är riktningen för förfrågningar, t. ex. serverNoContextTakeover är värdet som ska beställas till servern. Skapa en ny WebSocket instance. UNIX Domain Sockets. ws stöder att göra förfrågningar till UNIX domänuttag. För att göra en, använd följande URL-schema. Notera som är separatorn mellan sockelbanan och URL-sökvägen Om URL-banan utelämnas. Avslutad när anslutningen är stängd är koden ett numeriskt värde som anger statuskoden och förklarar varför anslutningen har varit nära d orsaken är en mänsklig läsbar sträng som förklarar varför anslutningen har stängts. Inmönts när ett fel uppstår Fel i underliggande är vidarebefordrade här. Inmatad när ett meddelande tas emot från servern. Inlämnad när en pong mottas från servern. Inlämnad när serverns svar inte är det förväntade, till exempel ett 401-svar Den här händelsen ger möjlighet att läsa svaret för att extrahera användbar information Om servern skickar ett ogiltigt svar och det finns ingen lyssnare för det här händelsen skickas ett fel. type A string representing the event type to listen for. listener The listener to add. Register an event listener emulating the EventTarget interface. A string indicating the type of binary data being transmitted by the connection This should be one of nodebuffer , arraybuffer or fragments Defaults to nodebuffer Type fragments will emit the array of fragments as received from the sender, without copyfull concatenation, which is useful for the performance of binary p rotocols transfering large messages with multiple fragments. The number of bytes of data that have been queued using calls to send but not yet transmitted to the network. Received bytes count. code A numeric value indicating the status code explaining why the connection is being closed. reason A human-readable string explaining why the connection is closing. Initiate a closing handshake. An object containing the negotiated extensions. An event listener to be called when connection is closed The listener receives a CloseEvent named close. An event listener to be called when an error occurs The listener receives an Error instance. An event listener to be called when a message is received from the server The listener receives a MessageEvent named message. An event listener to be called when the connection is established The listener receives an OpenEvent named open. Pause the socket. mask , failSilently. data The data to send in the ping frame. mask Specifies whether data should be masked or not Defaults to true when websocket is not a server client. failSilently Specifies whether or not to throw an error if the connection is not open. mask , failSilently. data The data to send in the ping frame. mask Specifies whether data should be masked or not Defaults to true when websocket is not a server client. failSilently Specifies whether or not to throw an error if the connection is not open. The subprotocol selected by the server. The WebSocket protocol version used for this connection, 8 or 13.The current state of the connection This is one of the ready state constants. type A string representing the event type to remove. listener The listener to remove. Removes an event listener emulating the EventTarget interface. Resume the socket. options , callback. data The data to sendpress Specifies whether data should be compressed or not Defaults to true when permessage-deflate is enabled. binary Specifies whether data should be sent as a binary or not Default is autodetected. mask Specifies whether data should be masked or not Defaults to true when websocket is not a server client. fin Specifies whether data is the last fragment of a message or not Defaults to true. callback An optional callback which is invoked when data is written out. Send data through the connection. Forcibly close the connection. The GET request sent by the client Useful for parsing authority headers, cookie headers, and other information This is only available for server clients. The URL of the WebSocket server Server clients don t have this attribute. What s different in the new WebSocket protocol. Developer Advocate in Tokyo. The WebSocket protocol specification has recently been updated to solve previous security concerns and is largely stable Below is a sum mary of the changes involved, along with some notes on current implementations. What has been changed since WebSocket HyBi 00.The protocol frame format has been changed HyBi 00 used to use 0x00 for head and 0xff for tail for each frame HyBi 10 now uses new format like following. Security issues have been addressed. Sec-WebSocket-Key and Sec-WebSocket-Accept are added in place of HyBi 00 s three keys The browser gives randomly generated number to Sec-WebSocket-Key Then, the server uses it with WebSocket protocol s specific GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 and SHA1 BASE64, etc to return Sec-WebSocket-Accept so that browser can confirm that it understands WebSocket This prevents a cross-protocol attack. On each frame, frame masking is now required This prevents cache poisoning on proxy Sec-WebSocket-Origin is added to prevent access from scripts that the service provider isn t aware of. Sec-WebSocket-Origin is added in place of HyBi 00 s Origin key to prevent access from scripts that the service provider doesn t aware of Note that this will be just Origin on HyBi 11.JS API changes. subprotocol can now be array, allowing a method signature of new WebSocket String url, Array subprotocol. attribute String. attribute Blob ArrayBuffer. Status code and reason why the connection is closed have been added to CloseEvent The close function has also been changed to accept these two arguments accordingly. Sec-WebSocket-Extensions is added Proposed extensions are. deflate-frame makes frames compressed at source and extracted at destination. x-google-mux to support multiplexing but is in early stage. Is there compatibility between HyBi 00 and HyBi 10 on both server and browser implementation. Server implementations can support both HyBi 00 and HyBi 10 by looking at the handshake header However, it is not recommended to support HyBi 00 since it s known to be vulnerable. The WebSocket JavaScript API is largely similar between old and new versions But as noted above, we don t recommend supporting HyBi 00 since it s known to be vulnerable. Which browser support HyBi 10.Chrome 14 supports HyBi 10 protocol although the WebSocket JavaScript API changes mentioned above are still on the way Firefox 7 is also planne d to support HyBi 10.Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3 0 License and code samples are licensed under the Apache 2 0 License For details, see our Site Policies Java is a registered trademark of Oracle and or its affiliates. 28, 2017.The latest news on the Chromium blog. Fork our API code samples and other open-source projects. Connect with ChromiumDev on Twitter. Check out the Web Developer Relations team s videos. Attend a developer event and get hacking. Contribute to WebFundamentals. High Performance Browser Networking by Ilya Grigorik. Chapter 17 WebSocket. WebSocket enables bidirectional, message-oriented streaming of text and binary data between client and server It is the closest API to a raw network socket in the browser Except a WebSocket connection is also much more than a network socket, as the browser abstracts all the complexity behind a simple API and provides a number of additional services. Connection negotiation and same-origin policy enforcement. Interoperability with existing infrastructure. Message-oriented communication and efficient message framing. Subprotocol negotiation and extensibility. WebSocket is one of the most versatile and flexible transports available in the browser The simple and min imal API enables us to layer and deliver arbitrary application protocols between client and server anything from simple JSON payloads to custom binary message formats in a streaming fashion, where either side can send data at any time. However, the trade-off with custom protocols is that they are, well, custom The application must account for missing state management, compression, caching, and other services otherwise provided by the browser There are always design constraints and performance trade-offs, and leveraging WebSocket is no exception In short, WebSocket is not a replacement for XHR, or SSE, and for best performance it is critical that we leverage the strengths of each transport. WebSocket is a set of multiple standards the WebSocket API is defined by the W3C, and the WebSocket protocol RFC 6455 and its extensions are defined by the HyBi Working Group IETF. WebSocket API. The WebSocket API provided by the browser is remarkably small and simple Once again, all the low-level detail s of connection management and message processing are taken care of by the browser To initiate a new connection, we need the URL of a WebSocket resource and a few application callbacks. Open a new secure WebSocket connection wss. Optional callback, invoked if a connection error has occurred. Optional callback, invoked when the connection is terminated. Optional callback, invoked when a WebSocket connection is established. Client-initiated message to the server. A callback function invoked for each new message from the server. Invoke binary or text processing logic for the received message. The API speaks for itself In fact, it should look very similar to the EventSource API we saw in the preceding chapter This is intentional, as WebSocket offers similar and extended functionality Having said that, there are a number of important differences as well Let s take a look at them one by one. WebSocket protocol has undergone a number of revisions, implementation rollbacks, and security investigations However, the good news is that the latest version v13 defined by RFC6455 is now supported by all modern browsers The only notable omission is the Android browser For the latest status, see. Similar to the SSE polyfill strategy Emulating EventSource with Custom JavaScript , the WebSocket browser API can be emulated via an optional JavaScript library However, the hard part with emulating WebSockets is not the API, but the transport As a result, the choice of the polyfill library and its fallback transport XHR polling, EventSource, iframe polling, etc will have significant impact on the performance of an emulated WebSocket session. To simplify cross-browser deployment, popular libraries such as SockJS provide an implementation of WebSocket-like object in the browser but also go one step further by providing a custom server that implements support for WebSocket and a variety of alternative transports The combination of a custom server and client is what enables seamless fallback the performa nce suffers, but the application API remains the same. Other libraries, such as go even further by implementing additional features, such as heartbeats, timeouts, support for automatic reconnects, and more, in addition to a multitransport fallback functionality. When considering a polyfill library or a real-time framework, such as pay close attention to the underlying implementation and configuration of the client and server always leverage the native WebSocket interface for best performance, and ensure that fallback transports meet your performance goals. WS and WSS URL Schemes. The WebSocket resource URL uses its own custom scheme ws for plain-text communication e g , and wss when an encrypted channel TCP TLS is required Why the custom scheme, instead of the familiar. The primary use case for the WebSocket protocol is to provide an optimized, bi-directional communication channel between applications running in the browser and the server However, the WebSocket wire protocol can be used out side the browser and could be negotiated via a exchange As a result, the HyBi Working Group chose to adopt a custom URL scheme. Despite the negotiation option enabled by the custom scheme, in practice there are no existing standards for alternative handshake mechanisms for establishing a WebSocket session. Receiving Text and Binary Data. WebSocket communication consists of messages and application code and does not need to worry about buffering, parsing, and reconstructing received data For example, if the server sends a 1 MB payload, the application s onmessage callback will be called only when the entire message is available on the client. Further, the WebSocket protocol makes no assumptions and places no constraints on the application payload both text and binary data are fair game Internally, the protocol tracks only two pieces of information about the message the length of payload as a variable-length field and the type of payload to distinguish UTF-8 from binary transfers. When a new message is received by the browser, it is automatically converted to a DOMString object for text-based data, or a Blob object for binary data, and then passed directly to the application The only other option, which acts as performance hint and optimization for the client, is to tell the browser to convert the received binary data to an ArrayBuffer instead of Blob. Force an ArrayBuffer conversion when a binary message is received. User agents can use this as a hint for how to handle incoming binary data if the attribute is set to blob , it is safe to spool it to disk, and if it is set to arraybuffer , it is likely more efficient to keep the data in memory Naturally, user agents are encouraged to use more subtle heuristics to decide whether to keep incoming data in memory or not. The WebSocket API W3C Candidate Recommendation. A Blob object represents a file-like object of immutable, raw data If you do not need to modify the data and do not need to slice it into smaller chunks, then it is the optimal format e g you can pass the entire Blob object to an image tag see the example in Downloading Data with XHR On the other hand, if you need to perform additional processing on the binary data, then ArrayBuffer is likely the better fit. Decoding Binary Data with JavaScript. An ArrayBuffer is a generic, fixed-length binary data buffer However, an ArrayBuffer can be used to create one or more ArrayBufferView objects, each of which can present the contents of the buffer in a specific format For example, let s assume we have the following C-like binary data structure. Given an ArrayBuffer object of this type, we can create multiple views into the same buffer, each with its own offset and data type. Each view takes the parent buffer, starting byte offset, and number of element s to process the offset is calculated based on the size of the preceding fields As a result, ArrayBuffer and WebSocket give our applications all the necessary tools to stream and process binary data within the browser. Sending Text and Binary Data. Once a WebSocket connection is established, the client can send and receive UTF-8 and binary messages at will WebSocket offers a bidirectional communication channel, which allows message delivery in both directions over the same TCP connection. Send a UTF-8 encoded text message. Send a UTF-8 encoded JSON payload. Send the ArrayBuffer contents as binary payload. Send the ArrayBufferView contents as binary payload. Send the Blob contents as binary payload. The WebSocket API accepts a DOMString object, which is encoded as UTF-8 on the wire, or one of ArrayBuffer, ArrayBufferView, or Blob objects for binary transfers However, note that the latter binary options are simply an API convenience on the wire, a WebSocket frame is either marked as binary or te xt via a single bit Hence, if the application, or the server, need other content-type information about the payload, then they must use an additional mechanism to communicate this data. The send method is asynchronous the provided data is queued by the client, and the function returns immediately As a result, especially when transferring large payloads, do not mistake the fast return for a signal that the data has been sent To monitor the amount of data queued by the browser, the application can query the bufferedAmount attribute on the socket. Subscribe to application updates e g game state changes. Check the amount of buffered data on the client. Send the next update if the buffer is empty. The preceding example attempts to send application updates to the server, but only if the previous messages have been drained from the client s buffer Why bother with such checks All WebSocket messages are delivered in the exact order in which they are queued by the client As a result, a large backlog of queued messages, or even a single large message, will delay delivery of messages queued behind it head-of-line blocking. To work around this problem, the application can split large messages into smaller chunks, monitor the bufferedAmount value carefully to avoid head-of-line blocking, and even implement its own priority queue for pending messages instead of blindly queuing them all on the socket. Many applications generate multiple classes of messages high-priority updates, such as control traffic, and low-priority updates, such as background transfers To optimize delivery, the application should pay close attention to how and when each type of message is queued on the socket. Subprotocol Negotiation. WebSocket protocol makes no assumptions about the format of each message a single bit tracks whether the message contains text or binary data, such that it can be efficiently decoded by the client and server, but otherwise the message contents are opaque. Further, unlike or XHR requests, w hich communicate additional metadata via headers of each request and response, there is no such equivalent mechanism for a WebSocket message As a result, if additional metadata about the message is required, then the client and server must agree to implement their own subprotocol to communicate this data. The client and server can agree on a fixed message format upfront e g all communication will be done via JSON-encoded messages or a custom binary format, and necessary message metadata will be part of the encoded structure. If the client and server need to transfer different data types, then they can agree on a consistent message header, which can be used to communicate the instructions to decode the remainder of the payload. A mix of text and binary messages can be used to communicate the payload and metadata information e g a text message can communicate an equivalent of headers, followed by a binary message with the application payload. This list is just a small sample of possible stra tegies The flexibility and low overhead of a WebSocket message come at the cost of extra application logic However, message serialization and management of metadata are only part of the problem Once we determine the serialization format for our messages, how do we ensure that both client and server understand each other, and how do we keep them in sync. Thankfully, WebSocket provides a simple and convenient subprotocol negotiation API to address the second problem The client can advertise which protocols it supports to the server as part of its initial connection handshake. Array of subprotocols to advertise during WebSocket handshake. Check the subprotocol chosen by the server. As the preceding example illustrates, the WebSocket constructor accepts an optional array of subprotocol names, which allows the client to advertise the list of protocols it understands or is willing to use for this connection The specified list is sent to the server, and the server is allowed to pick one of the pr otocols advertised by the client. If the subprotocol negotiation is successful, then the onopen callback is fired on the client, and the application can query the protocol attribute on the WebSocket object to determine the chosen protocol On the other hand, if the server does not support any of the client protocols advertised by the client, then the WebSocket handshake is incomplete the onerror callback is invoked, and the connection is terminated. The subprotocol names are defined by the application and are sent as specified to the server during the initial handshake Other then that, the specified subprotocol has no effect on the core WebSocket API. WebSocket Protocol. The WebSocket wire protocol RFC 6455 developed by the HyBi Working Group consists of two high-level components the opening handshake used to negotiate the parameters of the connection and a binary message framing mechanism to allow for low overhead, message-based delivery of both text and binary data. The WebSocket Protocol attempts to address the goals of existing bidirectional technologies in the context of the existing infrastructure as such, it is designed to work over ports 80 and 443 However, the design does not limit WebSocket to and future implementations could use a simpler handshake over a dedicated port without reinventing the entire protocol. WebSocket Protocol RFC 6455.WebSocket protocol is a fully functional, standalone protocol that can be used outside the browser Having said that, its primary application is as a bidirectional transport for browser-based applications. Binary Framing Layer. Client and server WebSocket applications communicate via a message-oriented API the sender provides an arbitrary UTF-8 or binary payload, and the receiver is notified of its delivery when the entire message is available To enable this, WebSocket uses a custom binary framing format Figure 17-1 , which splits each application message into one or more frames transports them to the destination, reassembles them, and finally notifies the receiver once the entire message has been received. Figure 17-1 WebSocket frame 2 14 bytes payload. Frame The smallest unit of communication, each containing a variable-length frame header and a payload that may carry all or part of the application message Message A complete sequence of frames that map to a log ical application message. The decision to fragment an application message into multiple frames is made by the underlying implementation of the client and server framing code Hence, the applications remain blissfully unaware of the individual WebSocket frames or how the framing is performed Having said that, it is still useful to understand the highlights of how each WebSocket frame is represented on the wire. The first bit of each frame FIN indicates whether the frame is a final fragment of a message A message may consist of just a single frame. The opcode 4 bits indicates type of transferred frame text 1 or binary 2 for transferring application data or a control frame such as connection close 8 , ping 9 , and pong 10 for connection liveness checks. The mask bit indicates whether the payload is masked for messages sent from the client to the server only. Payload length is represented as a variable-length field. If 0 125, then that is the payload length. If 126, then the following 2 bytes repr esent a 16-bit unsigned integer indicating the frame length. If 127, then the following 8 bytes represent a 64-bit unsigned integer indicating the frame length. Masking key contains a 32-bit value used to mask the payload. Payload contains the application data and custom extension data if the client and server negotiated an extension when the connection was established. The payload of all client-initiated frames is masked using the value specified in the frame header this prevents malicious scripts executing on the client from performing a cache poisoning attack against intermediaries that may not understand the WebSocket protocol For full details of this attack, refer to Talking to Yourself for Fun and Prot presented at W2SP 2011.As a result, each server-sent WebSocket frame incurs 2 10 bytes of framing overhead The client must also send a masking key, which adds an extra 4 bytes to the header, resulting in 6 14 bytes over overhead No other metadata, such as header fields or other informa tion about the payload, is available all WebSocket communication is performed by exchanging frames that treat the payload as an opaque blob of application data. WebSocket Multiplexing and Head-of-Line Blocking. WebSocket is susceptible to head-of-line blocking messages can be split into one or more frames, but frames from different messages can t be interleaved, as there is no equivalent to a stream ID found in the 2 0 framing mechanism see Streams, Messages, and Frames. As a result, a large message, even when split into multiple WebSocket frames, will block the delivery of frames associated with other messages If your application is delivering latency-sensitive data, be careful about the payload size of each message and consider splitting large messages into multiple application messages. The lack of multiplexing in core WebSocket specification also means that each WebSocket connection requires a dedicated TCP connection, which may become a potential problem for 1 x deployments due to a r estricted number of connections per origin maintained by the browser see Exhausting Client and Server Resources. On the bright side, the new Multiplexing Extension for WebSockets developed by the HyBi Working Group addresses the latter limitation. With this extension, one TCP connection can provide multiple virtual WebSocket connections by encapsulating frames tagged with a channel ID The multiplexing extension maintains separate logical channels, each of which provides fully the logical equivalent of an independent WebSocket connection, including separate handshake headers. WebSocket Multiplexing Draft 10.With this extension in place, multiple WebSocket connections channels can be multiplexed over the same TCP connection However, each individual channel is still susceptible to head-of-line blocking Hence, one potential workaround is to use different channels, or dedicated TCP connections, to multiplex multiple messages in parallel. Finally, note that the preceding extension is necessary only for 1 x connections While no official specification is yet available for transporting WebSocket frames with 2 0, doing so would be much easier 2 0 has built-in stream multiplexing, and multiple WebSocket connections could be transported within a single session by encapsulating WebSocket frames within the 2 0 framing mechanism. Protocol Extensions. WebSocket specification allows for protocol extensions the wire format and the semantics of the WebSocket protocol can be extended with new opcodes and data fields While somewhat unusual, this is a very powerful feature, as it allows the client and server to implement additional functionality on top of the base WebSocket framing layer without requiring any intervention or cooperation from the application code. What are some examples of WebSocket protocol extensions The HyBi Working Group, which is responsible for the development of the WebSocket specification, lists two official extensions in development. A Multiplexing Extension for WebSockets This extension provides a way for separate logical WebSocket connections to share an underlying transport connection Compression Extensions for WebSocket A framework for creating WebSocket extensions that add compression functionality to the WebSocket Protocol. As we noted earlier, each WebSocket connection requires a dedicated TCP connection, which is inefficient Multiplexing extension addresses this problem by extending each WebSocket frame with an additional channel ID to allow multiple virtual WebSocket channels to share a single TCP connection. Similarly, the base WebSocket specification provides no mechanism or provisions for compression of transferred data each frame carries payload data as provided by the application As a result, while this may not be a problem for optimized binary data structures, this can result in high byte transfer overhead unless the application implements its own data compression and decompression logic In effect, com pression extension enables an equivalent of transfer-encoding negotiation provided by. To enable one or more extensions, the client must advertise them in the initial Upgrade handshake, and the server must select and acknowledge the extensions that will be used for the lifetime of the negotiated connection For a hands-on example, let s now take a closer look at the Upgrade sequence. WebSocket Multiplexing and Compression in the Wild. As of mid-2013, WebSocket multiplexing is not yet supported by any popular browser Similarly, there is limited support for compression Google Chrome and the latest WebKit browsers may advertise an x-webkit-deflate-frame extension to the server However, deflate-frame is based on an outdated revision of the standard and will be deprecated in the future. As the name implies, per-frame compresses the payload contents on a frame-by-frame basis, which is suboptimal for large messages that may be split between multiple frames As a result, latest revisions of the comp ression extension have switched to per-message compression that s the good news The bad news is per-message compression is still experimental and is not yet available in any popular browser. As a result, the application should pay close attention to the content-type of transferred data and apply its own compression where applicable That is, at least until native WebSocket compression support is available widely across all the popular browsers This is especially important for mobile applications, where each unnecessary byte carries high costs to the user. Upgrade Negotiation. The WebSocket protocol delivers a lot of powerful features message-oriented communication, its own binary framing layer, subprotocol negotiation, optional protocol extensions, and more As a result, before any messages can be exchanged, the client and server must negotiate the appropriate parameters to establish the connection. Leveraging to perform the handshake offers several advantages First, it makes WebSockets compatible with existing infrastructure WebSocket servers can run on port 80 and 443, which are frequently the only open ports for the client Second, it allows us to reuse and extend the Upgrade flow with custom WebSocket headers to perform the negotiation. Sec-WebSocket-Version Sent by the client to indicate version 13 for RFC6455 of the WebSocket protocol it wants to use If the server does not support the client version, then it must reply with a list of supported versions Sec-WebSocket-Key An auto-generated key sent by the client, which acts as a challeng e to the server to prove that the server supports the requested version of the protocol Sec-WebSocket-Accept Server response that contains signed value of Sec-WebSocket-Key, proving that it understands the requested protocol version Sec-WebSocket-Protocol Used to negotiate the application subprotocol client advertises the list of supported protocols server must reply with a single protocol name Sec-WebSocket-Extensions Used to negotiate WebSocket extensions to be used for this connection client advertises supported extensions, and the server confirms one or more extensions by returning the same header. With that, we now have all the necessary pieces to perform an Upgrade and negotiate a new WebSocket connection between the client and server. Request to perform an upgrade to the WebSocket protocol. WebSocket protocol version used by the client. Auto-generated key to verify server protocol support. Optional list of subprotocols specified by the application. Optional list of protocol extensions supported by the client. Just like any other client-initiated connection in the browser, WebSocket requests are subject to the same-origin policy the browser automatically appends the Origin header to the upgrade handshake, and the remote server can use CORS to accept or deny the cross origin request see Cross-Origin Resource Sharing CORS To complete the handshake, the server must return a successful Switching Protocols response and confirm the selected options advertised by the client.101 response code confirming WebSocket upgrade. CORS header indicating opt-in for cross-origin connection. Signed Key value proving protocol support. Application subprotocol selected by the server. List of WebSocket extensions selected by the server. All RFC6455-compatible WebSocket servers use the same algorithm to compute the answer to the client challenge the contents of the Sec-WebSocket-Key are concatenated with a unique GUID string defined in the standard, a SHA1 hash is computed, and the resulting stri ng is base-64 encoded and sent back to the client. At a minimum, a successful WebSocket handshake must contain the protocol version and an auto-generated challenge value sent by the client, followed by a 101 response code Switching Protocols from the server with a hashed challenge-response to confirm the selected protocol version. Client must send Sec-WebSocket-Version and Sec-WebSocket-Key. Server must confirm the protocol by returning Sec-WebSocket-Accept. Client may send a list of application subprotocols via Sec-WebSocket-Protocol. Server must select one of the advertised subprotocols and return it via Sec-WebSocket-Protocol If the server does not support any, then the connection is aborted. Client may send a list of protocol extensions in Sec-WebSocket-Extensions. Server may confirm one or more selected extensions via Sec-WebSocket-Extensions If no extensions are provided, then the connection proceeds without them. Finally, once the preceding handshake is complete, and if the handshake is successful, the connection can now be used as a two-way communication channel for exchanging WebSocket messages From here on, there is no other explicit communication between the client and server, and the WebSocket protocol takes over. Proxies, Intermediaries, and WebSockets. In practice, for security and policy reasons, many users have a restricted set of open ports specifically port 80 and port 443 As a result, WebSocket negotiation is performed via the Upgrade flow to ensure the best compatibility with existing network policies and infrastructure. However, as we noted earlier in Proxies, Intermediaries, TLS, and New Protocols on the Web many existing intermediaries may not understand the new WebSocket protocol, which can lead to a variety of failure cases blind connection upgrades, unintended buffering of WebSocket frames, content modification without understanding of the protocol, misclassification of WebSocket traffic as compromised connections, and so on. The WebSocket Key and Acce pt handshake addresses some of these problems it is a security policy against servers and intermediaries that may blindly upgrade the connection without actually understanding the WebSocket protocol However, while this precaution addresses some deployment issues with explicit proxies, it is nonetheless insufficient for transparent proxies, which may analyze and modify the data on the wire without notice. The workaround Establish a secure end-to-end tunnel i e use WSS By negotiating a TLS session prior to performing the Upgrade handshake, the client and server establish an encrypted tunnel, which resolves all of the previously listed concerns This is especially true for mobile clients, whose traffic often passes through a variety of proxy services that may not play well with WebSocket. WebSocket Use Cases and Performance. WebSocket API provides a simple interface for bidirectional, message-oriented streaming of text and binary data between client and server pass in a WebSocket URL to the c onstructor, set up a few JavaScript callback functions, and we are up and running the rest is handled by the browser Add to that the WebSocket protocol, which offers binary framing, extensibility, and subprotocol negotiation, and WebSocket becomes a perfect fit for delivering custom application protocols in the browser. However, just as with any discussion on performance, while the implementation complexity of the WebSocket protocol is hidden from the application, it nonetheless has important performance implications for how and when WebSocket should be used WebSocket is not a replacement for XHR or SSE, and for best performance it is critical that we leverage the strengths of each transport. Refer to XHR Use Cases and Performance and SSE Use Cases and Performance for a review of the performance characteristics of each transport. Request and Response Streaming. WebSocket is the only transport that allows bidirectional communication over the same TCP connection Figure 17-2 the client and se rver can exchange messages at will As a result, WebSocket provides low latency delivery of text and binary application data in both directions. Figure 17-2 Communication flow of XHR, SSE, and WebSocket. XHR is optimized for transactional request-response communication the client sends the full, well-formed request to the server, and the server responds with a full response There is no support for request streaming, and until the Streams API is available, no reliable cross-browser response streaming API. SSE enables efficient, low-latency server-to-client streaming of text-based data the client initiates the SSE connection, and the server uses the event source protocol to stream updates to the client The client can t send any data to the server after the initial handshake. Propagation and Queuing Latency. Switching transports from XHR to SSE or WebSocket does not decrease the roundtrip between client and server Regardless of the transport, the propagation latency of the data packets is the s ame However, aside from propagation latency, there is also the queuing latency the time the message has to wait on the client or server before it can be routed to the other party. In the case of XHR polling, the queuing latency is a function of the client polling interval the message may be available on the server, but it cannot be sent until the next client XHR request see Modeling Performance of XHR Polling By contrast, both SSE and WebSocket use a persistent connection, which allows the server to dispatch the message and client, in the case of WebSocket , the moment it becomes available. As a result, low-latency delivery for SSE and WebSocket is specifically referring to the elimination of message queuing latency We have not yet figured out how to make WebSocket data packets travel faster than the speed of light. Message Overhead. Once a WebSocket connection is established, the client and server exchange data via the WebSocket protocol application messages are split into one or more fra mes, each of which adds from 2 to 14 bytes of overhead Further, because the framing is done via a custom binary format, both UTF-8 and binary application data can be efficiently encoded via the same mechanism How does that compare with XHR and SSE. SSE adds as little as 5 bytes per message but is restricted to UTF-8 content only see Event Stream Protocol. 1 x requests XHR or otherwise will carry an additional 500 800 bytes of metadata, plus cookies see Measuring and Controlling Protocol Overhead. 2 0 compresses the metadata, which significantly reduces the overhead see Header Compression In fact, if the headers do not change between requests, the overhead can be as low as 8 bytes. Keep in mind that these overhead numbers do not include the overhead of IP, TCP, and TLS framing, which add 60 100 bytes of combined overhead per message, regardless of the application protocol see TLS Record Size. Data Efficiency and Compression. Every XHR request can negotiate the optimal transfer encoding format e g gzip for text-based data , via regular negotiation Similarly, because SSE is restricted to UTF-8 only transfers, the event stream data can be efficiently compressed by applying gzip across the entire session. With WebSocket, the situation is more complex WebSocket can transfer both text and binary data, and as a result it doesn t make sense to compress the entire session The binary payloads may be compressed already As a result, WebSocket must implement its own compression mechanism and sel ectively apply it to each message. The good news is the HyBi working group is developing the per-message compression extension for the WebSocket protocol However, it is not yet available in any of the browsers As a result, unless the application implements its own compression logic by carefully optimizing its binary payloads see Decoding Binary Data with JavaScript and implementing its own compression logic for text-based messages, it may incur high byte overhead on the transferred data. Chrome and some WebKit-based browsers support an older revision per-frame compression of the compression extension to the WebSocket protocol see WebSocket Multiplexing and Compression in the Wild. Custom Application Protocols. The browser is optimized for data transfers it understands the protocol, and it provides a wide array of services, such as authentication, caching, compression, and much more As a result, XHR requests inherit all of this functionality for free. By contrast, streaming allows us to deli ver custom protocols between client and server, but at the cost of bypassing many of the services provided by the browser the initial handshake may be able to perform some negotiation of the parameters of the connection, but once the session is established, all further data streamed between the client and server is opaque to the browser As a result, the flexibility of delivering a custom protocol also has its downsides, and the application may have to implement its own logic to fill in the missing gaps caching, state management, delivery of message metadata, and so on. The initial Upgrade handshake does allow the server to leverage the existing cookie mechanism to validate the user If the validation fails, the server can decline the WebSocket upgrade. Leveraging Browser and Intermediary Caches. Using regular has significant advantages Ask yourself a simple question would the client benefit from caching the received data Or could an intermediary optimize the delivery of the asset if it cou ld cache it. For example, WebSocket supports binary transfers, which allows the application to stream arbitrary image formats with no overhead nice win However, the fact that the image is delivered within a custom protocol means that it won t be cached by the browser cache, or any intermediary e g a CDN As a result, you may incur unnecessary transfers to the client and much higher traffic to the origin servers The same logic applies to all other data formats video, text, and so on. As a result, make sure you choose the right transport for the job A simple but effective strategy to address these concerns could be to use the WebSocket session to deliver non-cacheable data, such as real-time updates and application control messages, which can trigger XHR requests to fetch other assets via the protocol. Deploying WebSocket Infrastructure. is optimized for short and bursty transfers As a result, many of the servers, proxies, and other intermediaries are often configured to aggressively timeout idle connections, which, of course, is exactly what we don t want to see for long-lived WebSocket sessions To address this, there are three pieces to consider. Routers, load-balancers, and proxies within own network. Transparent and explicit proxies in external network e g ISP and carrier proxies. Routers, firewalls, and proxies within the client s network. We have no control over the policy of the client s network In fact, some networks may block WebSocket traffic entirely, which is why you may need a fallback strategy Similarly, we don t have control over the proxies on the external network However, this is where TLS may help By tunneling over a secure end-to-end connection, WebSocket traffic can bypass all the intermediate proxies. Using TLS does not prevent the intermediary from timing out an idle TCP connection However, in practice , it significantly increases the success rate of negotiating the WebSocket session and often also helps to extend the connection timeout intervals. Finally, there is the infrastructure that we deploy and manage ourselves, which also often requires attention and tuning As easy as it is to blame the client or external networks, all too often the problem is close to home Each load-balancer, router, proxy, and web server in the serving path must be tuned to allow long-lived connections. For example, Nginx 1 3 13 can proxy WebSocket traffic, but defaults to aggressive 60-second timeouts To increase the limit, we must explicitly define the longer timeouts. Set 60-minute timeout between reads. Set 60-minute timeout between writes. Similarly, it is not uncommon to have a load balancer, such as HAProxy, in front of one or more Nginx servers Not surprisingly, we need to apply similar explicit configuration here as well e g for HAProxy.60-minute inactivity timeout for tunnels. The gotcha with the prece ding example is the extra tunnel timeout In HAProxy the connect client and server timeouts are applied only to the initial Upgrade handshake, but once the upgrade is complete, the timeout is controlled by the tunnel value. Nginx and HAProxy are just two of hundreds of different servers, proxies, and load balancers running in our data centers We can t enumerate all the configuration possibilities in these pages The previous examples are just an illustration that most infrastructure requires custom configuration to handle long-lived sessions Hence, before implementing application keepalives, double-check your infrastructure first. Long-lived and idle sessions occupy memory and socket resources on all the intermediate servers Hence, short timeouts are often justified as a security, resource, and operational precaution Deploying WebSocket, SSE, and 2 0, each of which relies on long-lived sessions, brings its own class of new operational challenges. Performance Checklist. Deploying a high-perfo rmance WebSocket service requires careful tuning and consideration, both on the client and on the server A short list of criteria to put on the agenda. Use secure WebSocket WSS over TLS for reliable deployments. Pay close attention to polyfill performance if necessary. Leverage subprotocol negotiation to determine the application protocol. Optimize binary payloads to minimize transfer size. Consider compressing UTF-8 content to minimize transfer size. Set the right binary type for received binary payloads. Monitor the amount of buffered data on the client. Split large application messages to avoid head-of-line blocking. Leverage other transports where applicable. Last, but definitely not least, optimize for mobile Real-time push can be a costly performance anti-pattern on mobile handsets, where battery life is always at a premium That s not to say that WebSocket should not be used on mobile To the contrary, it can be a highly efficient transport, but make sure to account for its requirements. Wit h Safari, you learn the way you learn best Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more. No credit card required. Websockets 101.written on Monday, September 24, 2012.Out of curiosity I taught the Fireteam presence server websockets as a protocol in addition to the proprietary protocol it speaks out of the box I don t really have a usecase for websocket per-se with the server, but I thought it might make it more useful for customers that want to use the event based parts of the API with HTML5 games This post focuses on implementing websockets on the server, not so much about how you would use them from the client and basically collects all thing I wish I would have known before. What are Websockets. So let s start with that part first What are websockets and why would you use websockets Basically only if you want to have a bidirectional communication between an actual web browser and some server Websocket is not necessarily a good protocol if neither of the endpoints is an actual browser Websockets suffer a lot under the restrictions and implementation details that were forced upon the protocol to make it work with existing infrastructure. Websockets in the current iteration as specified by RFC 6455 do a bunch of things differently to what a raw TCP connections does The name websocket gives the impression that it s a traditional socket In practice it combines the parts of UDP and TCP it s message based like UDP, but it s reliable like TCP So assuming you know what TCP is, here is what websocket adds on top of that. it upgrades from 1 1 through a system previously defined as part of the specification upgrade header. it sends the origin domain in the upgrade so that connections can be restricted to prevent CSRF attacks This works similar to CORS for. Through the handshake it becomes feasible to proxy the connection without losing information a proxy could inject an X-Real-IP or X-Forwarded-For header. It sends mes sages Each message can also carry control information and is wrapped in a frame. Messages sent from the client to the server are obfuscated with a basic transmission mask of 4 bytes which is sent within each websocket package Messages can be of utf-8 text type or binary nature. It adds an agreed way for the two peers to signal that the connection is about to be terminated that does not rely on the underlying TCP connection. Builtin heartbeating support That s actually pretty nifty because the application code in the browser does not have to deal with keeping the connection alive and can just assume that either the server or the browser will make sure that they exchange ping pongs. When to use them. Websockets make you sad There, I said it What started out as a really small simple thing ended up as an abomination of what feels like needles complexity Now the complexity comes for a reason The protocol went through many iterations and basically had to be changed multiple times because of unfor eseen security problems that came up with misbehaving proxies The protocol I created for the internal communication of our server is upgrading from just like websockets do, but without the secure parts And here is why it does not matter. Everybody knows about proxies We have proxies that do load balancing on the application side, we have proxies that do SSL offloading, we have proxies for all kinds of things Unfortunately outside our internal infrastructure everyone of us also has to deal with proxies in corporate networks, and worse, on mobile network connections The amount of shitty middleware installed all around the world is just staggering And this pretty much has shown me that the only way you can do anything useful these days is by putting TLS on top of everything and just force people to stop with their shenanigans On O2 s mobile networks you cannot use websockets unless they are encrypted You cannot get websocket connections through Amazon s ELB Their load balancer Heck, you ca n t even get PATCH as an method through the ELB. Everything that Fireteam will be doing will most likely always be behind an encrypted connection It guarantees me that nothing can do funny things with the data I m sending around And as a positive side effect I don t have to mask my communication like websocket does because I know the software stack on my side until it hits the internet The communication gets encrypted and I know nobody is going to change my data on the way to the client. In fact, I would also recommend to always use websockets through TLS Even if you don t care about the security side of things you will still benefit from the fact that your websocket connections succeed in many more cases Not encrypting your connection is definitely something you will regret sooner or later. The Handshake. Alright After this fairly long disclaimer you re still there, which probably means you still want to do websockets Fair enough Now let s start with the basics, the handshake This is wher e everything starts It upgrades your connection from to something else For the internal protocol we recommend to customers we upgrade our connection basically to a raw TCP connection Websockets are not an upgrade to TCP, it s an upgrade to a message based communication. To begin why would you upgrade from instead of directly starting with TCP as a protocol The reasons for why Fireteam s protocol starts with not all that different from why websockets upgrade from. Websockets upgrade from because it was believed that people would develop servers that serve both websocket connections as well as ones I don t believe for a second that this will be what people do at the end of the day however A server that handles stateless requests to answer with a reply has a very different behavior than a server that keeps TCP connections open However the advantage is that websockets use the same ports as and do and that is a huge win It s a win because these are privileged ports 1024 and they are tradition ally handled differently than non privileged ports For instance on a linux system only root can open such ports Even more important ELB only lets you open a handful of these privileged ports 25, 80 and 443 to be exact Since ELB also does socket level load balancing you can still do websockets on Amazon, just not through their local balancer. We re handling our persistent presence protocol very differently than our webservice but we still benefit from the upgrade in some edge cases That s mainly where we have to tunnel our communication through a library because arbitrary socket connections are not possible for security or scalability reasons If you have ever used Google Appengine or early Windows Phone you will have noticed that connections are possible where regular socket connections are not. You will also see that many corporate networks only allow certain ports outgoing The fact that websockets use the same port as make this much more interesting If anyone has ever used the flash soc ket policy system will know that pain Currently it s entirely impossible to use flash sockets behind Amazon s ELB because the Flash VM will attempt to connect to port 843 to get authorization information That s a port you can t open on the ELB So the idea of starting with is pretty solid. always supported upgrades, but unfortunately many proxies seem to have ignored that part of the specification The main reason for that probably is that until websockets came around nobody was actually using the Upgrade flag There was an SSL upgrade RFC that used the same mechanism but I don t think anyone is using that. Alright So what does the handshake look like The upgrade is initiated by the client, not by the server The way Fireteam upgrades the connection is by following the old SSL RFC and looks like this. The server then replies by upgrading. If the upgrade header was missing, the server instead answers with 426 Upgrade Required. What s interesting about this is that the upgrade require status code is defined, but it does not show up in the RFC Instead if does come from that SSL RFC. Websockets upgrade very similar, but they are using 400 Bad Request to signal a missing upgrade They also transmit a special key with the upgrade request which the server has to process and send back Th is is done so that a websocket connection cannot be established with an endpoint that is not aware of websockets Here is what the handshake looks like for the client. The websocket key here are random bytes The server takes these bytes and appends the special string 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 to it, then creates the SHA1 hash from it and base64 encodes the result the bytes, not the hexadecimal representation The magic string looks like a UUID and also is one, but that s completely irrelevant because the exact string needs to be used A lowercase representation or braces around the string would obviously fail That value is then put into the Sec-WebSocket-Accept header When the server has computed the value it can send an upgrade response back. The handshake can also include a protocol request and the websocket version information but you can t include arbitrary other headers If you compare the websocket upgrade with our own upgrade you will notice that we can t transmit the autho rization information There are two ways around that You can either transmit the authorization information as the first request or put it into the URL as query parameter. Also notice that the Sec-WebSocket-Accept header brings it s own grammar for the value Normally you would expect you can quote the value but the specification specifically requires a base64 value there. Websocket URLs. Alright As if websockets were not painful enough as they are, someone had the amazing idea to also introduce a new URL scheme Two in fact ws and wss Sounds like a tiny change from to but unfortunately that s not the case URLs have scheme specific grammar For instance FTP URLs can have authorization information in the netloc part ftp username server whereas can t mailto URLs don t have the leading slashes etc Websocket URLs are special in that they do not support anchors foo Now why would that matter It matters because whoever created the URL parsing module in Python also decided that they should stick as cl osely as possible to the strict standard that you cannot throw arbitrary URLs at the module For instance if you would try to parse websocket URLs you quickly realize that the results are just wrong. The reason why websockets have a separate URL is beyond me I suspect it stems from the fact that the RFC hints towards eventually dropping the upgrade from so the URL would not make much sense In any case it s just a very annoying example of where we now have to things now that were previously unnecessary. Also since it s a different protocol, protocol relative links will obviously not work You will have to switch between wss and ws by hand. Otherwise the same rules as for style URLs apply Namely that ws is unencrypted and has port 80 as default port and wss requires TLS encryption and port 443 as default. Authorization and IPs. Before we dive further into websockets let me throw yet another problem at you Since proxying is a word that comes up with websockets so very often we should probably ta lk about how proxies work there in the original RFC does not really talk much about TCP and IP addresses don t show up in there either However it has become clear over the last couple of years that there is a lot of value behind knowing which IP address connects to your server Traditionally this is doing by looking at the IP address that is stored in the individual IP packets Unfortunately this falls short the moment you start proxying through another server. There are two headers that have become popular to remedy that situation The first one is X-Forwarded-For which can contain one or multiple IPs of servers that took part in the request Each proxy server would add the remote address of the request to the header So if you have a user agent at 192 168 0 100 connect to 192 168 0 200 which acts as a proxy for 192 168 0 201 you end up with an X-Forwarded-For of 192 168 0 100 Bring in yet another proxy server that one would append it s own IP address to that list. Now there has to be a limi t to this Usually what you do is you configure the first server to reject any already set X-Forwarded-For headers or users can just use a browser extension or a proxy to inject a forged value in there And people do that I remember that people did exactly that to get American streaming content available in Europe by just injecting an American IP into that header. With websockets it s worse Odds are that your frontend proxy is doing TCP level proxying If it would be doing level load balancing and it would understand the Upgrade header it you could make it inject an X-Forwarded-For header and then read that on the server However Amazon s ELB as mentioned only works with websockets if you set it to TCP level proxying for instance And with that you lose your remote address Maybe not a problem for you, it definitely is a problem for us Now I know that protocols exists to inform a peer about the IP address on the other side of a proxy connection, but ELB does not speak it so it s a rather unin teresting thing for me. The way our server works is pretty similar to how the juggernaut server used to work You connect to a presence server that holds your socket connection open and acts as a central hub that uses other means to communicate with backend services We have a pretty lightweight server and we don t want to make it too complicated to authorize requests against it Namely we don t want to implement OAuth a second time for that server when we already use it for the strictly request response based webservice infrastructure. The trick we use for that is that we let a user authorize against the webservice infrastructure through OAuth and then call an endpoint that gives you a ticket that is valid for a few seconds That ticket is stored in redis It contains your account ID and a few important internal attributes, but we also store the IP on it which you used at the time the ticket was generated. With that ticket you go to the presence server and redeem it The presence server only n eeds to connect to redis and check if such a ticket exist and delete it Since we already use redis anyways in that server it s a pretty simple undertaking We obviously assume here that nobody takes the ticket between IP addresses We can t gurantee that this does not happen but we don t care about the implications either Someone could obviously create the ticket through a VPN and then disable the VPN connection when it s time to connect to the presence server But to be honest I don t care It s as far as I am concerned, no security problem. In theory the spec says you can also use any of the authorization systems basic auth, cookies etc but since you can t customize the headers with the JavaScript API that are being sent with the handshake you are basically very limited to implicit auth or auth through one of the first requests URL based. Now that we know how we can connect to the websocket server, how to upgrade to the websocket protocol and how authorization can be handled without losing the IP address information even if we do TCP level load balancing The next thing you have to know is how websocket transfer works As mentioned earlier websocket is not a stream based protocol like TCP, it s message based What s the difference With TCP you send bytes around and have to make sure for the most part that you can figure out the end of a message Our own protocol makes this very easy because we send full JSON objects around which are self terminating For naive JSON parsers like the one in the Python standard library that cannot parse of a stream we also add a newline at the end and ensure that all newlines in JSON strings are escaped So you can just read to the newline and then hand that line to the JSON parser. Websockets makes this easier because it puts a frame around everything Upside easier to handle from the JavaScript side, downside much harder to handle on the server side because you now need to wrap everything in frames. So let s have a look first how the frames are d efined This is what the RFC provides us with. Good news first as of the websocket version specified by the RFC it s only a header in front of each packet The bad news is that it s a rather complex header and it has the frighting word mask in it Here are the individual parts explained. fin 1 bit indicates if this frame is the final frame that makes up the message Most of the time the message fits into a single frame and this bit will always be set Experiments show that Firefox makes a second frame after 32K however. rsv1 rsv2 rsv3 1 bit each it wouldn t be a proper protocol if it did not include reserved bits As of right now, they are unused. opcode 4 bits the opcode Mainly says what the frame represents The following values are currently in use.0x00 this frame continues the payload from the last.0x01 this frame includes utf-8 text data.

No comments:

Post a Comment