WebSocket

WebSocket, լրիվ դուպլեքս միացման արձանագրություն (կարող է փոխանցել և ստանալ միաժամանակ) TCP-միացման հիման վրա՝ նախատեսված բրաուզերի և վեբ-սերվերի միջև իրական ժամանակի ռեժիմում հաղորդագրություններ փոխանակեու համար։ Ներկայումս W3C-ում իրականացվում է API Web Sockets ստանդարտացում։ Այդ տարբերակի սևագրային տարբերակը հաստատված է IETF-ի կողմից։

WebSocket-ը մշակված է վեբ-բրաուզերներում և վեբ-սերվերներում օգտագործման համար, բայց այն կարող է նաև օգտագործվել ցանկացած սերվերային կամ կլիենտային հավելվածի համար։ WebSocket-ը անկախ արձանագրություն է՝ հիմնված TCP արձանագրության վրա։ Այն հնարավոր է դարձնում առավել սերտ համագործակցությունը բրաուզերի և վեբ-կայքիի միջև՝ նպաստելով ինտերակտիվ բովանդակության տարածմանը և իրական ժամանակում աշխատող հավելվածների ստեղծմանը։

WebSocket միացման ստեղծում 
WebSocket միացման ստեղծման համար կլիենտը և սերվերը օգտագործում են արձանագրություն, որը նման HTTP -ի։ Կլիենտը ձևավորում է հատուկ HTTP-հարցում, որին սերվերը պատասխանում է որոշակի կերպ։

Արձանագրություն 75 
Մինչև համար 75 արձանագրության սևագրի խմբագրումը WebSocket միացումը հաստատվում էր հետևյալ կերպ։ Կլիենտի հարցում․

GET /demo HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
WebSocket-Protocol: sampleՍերվերի պատասխանը, որը հաստատում է անցումը WebSocket-ի։ HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Location: ws://example.com/demo
Sec-WebSocket-Protocol: sampleՊատասխանն ուղարկելուց անմիջապես հետո WebSocket-միացումը հաստատված է համարվում։ Կլիենտը և սերվերը կարող են սկսել նույն TCP-միացումով հաղորդագրությունների երկկողմ փոխանակումը։ Տեքստային հաղորդագրության (UTF-8 կոդավորմամբ) փոխանցման համար անհրաժեշտ է փոխանցել 0-ական բայթ, իսկ հետո` 255 նշանակմամբ բայթ։

Արձանագրություն 76 
2010 թ. հունիսի 2-ին WebSocket արձանագրության մեջ ավելացվել էին առանց հետադարձ համապատասխանության պահպանման WebSocket միացումի հաստատման գործընթացը փոփոխող ճշտումներ։ WebSocket արձանագրության սևագրի 76-րդ խմբագրության մեջ ավելացված է կեղծ հարցումներից պաշտպանություն։ Կլիենտը ուղարկում է հետևյալ հարցումը.
 GET /demo HTTP/1.1
 Upgrade: WebSocket
 Connection: Upgrade
 Sec-WebSocket-Key2: 4 @1 46546xW%0l 1 5
 Host: example.com
 Sec-WebSocket-Key1: 12998 5 Y3 1 .P00
 Origin: http://example.com
 WebSocket-Protocol: sample
Հարցման մեջ ավելացվել են նոր վերնագրեր` "Sec-WebSocket-Key1" և "Sec-WebSocket-Key2" ու հարցման 8 բայթանի մարմին։ Նրանք բոլորը գեներացվում են կլիենտի կողմից պատահական կերպով։

Սերվերի` WebSocket-ի անցման պատասխանը.
 HTTP/1.1 101 Web Socket Protocol Handshake
 Upgrade: WebSocket
 Connection: Upgrade
 Sec-WebSocket-Origin: http://example.com
 Sec-WebSocket-Location: ws://example.com/demo
 Sec-WebSocket-Protocol: sample
Պատասխանը պարունակում է վերնագրերի նոր անուններ ("Sec-WebSocket-Origin":"Sec-WebSocket-Location":"Sec-WebSocket-Protocol"` "WebSocket-Origin"-ի փոխարեն։ "WebSocket-Location":"WebSocket-Protocol") և պատասխանի 16-բայթանի մարմինը, որը հաշվարկվում է հետևյալ կերպ.
 հարցման վերնագրի նշանակմամբ տողում Sec-WebSocket-Key1 - ից բացառել բոլոր նշանները, որոնք թիվ չեն հանդիսանում («0»..«9» միջակայքում չեն),
 ստացված տողը վերածել 64-բիթանի ամբողջ թվի (վերոնշյալ օրինակում կստացվի 1299853100),
 ստացված թիվը բաժանել ամբողջթվային բաժանմամբ վերնագրի նշանակմամբ ելքային տողի բացատների քանակին, 
 ստացված թիվը ներկայացնել 4-բայթանի 32-բիթանի թվի տեսքով` big endian ֆորմատով։ 
 Նույնը կատարել Sec-WebSocket-Key2 վերնագրի հետ,
 4 և 5 կետերի թվերի որպես 4-բայթանի տողեր ինտերպրետացիայի ժամանակ դրանք մի տողի վերածել և որպես տող ավելացնել հարցման մարմինը, 
 ստացված 16-բայթանի թվից հաշվել MD5 նշանակումը և այն գրել պատասխանի մարմնում ինչպես կա` առանց որևէ նշանակման վերածելու։
Չնայած նոր հարցումների և պատասխանների նմանությանը, HTTP արձանագրության հարումներին և պատասխաններին, նրանք նույնը չեն։ Օրինակ` հարցման մեջ կա մարմին, սակայն վերնագրերում "Content-Length" դաշտը բացակայում է։

Սերվերային մասը պետք է կարողանա տարբերել կլիենտների 2 տիպերը` ըստ հարցումներում Sec-WebSocket-Key1 и Sec-WebSocket-Key2 վերնագրերի առկայության կամ բացակայության։

Արձանագրություն 07 
Արձանագրության սևագրի 07 տարբերակում 2011թ. ապրիլի 22-ին մտցվել են փոփոխություններ։

Ի տարբերություն 76 արձանագրության, համաձայն որի` տվյալները փոխանցվում են առանց գաղտնագրման, արձանագրության այս տարբերակում կլիենտից սերվեր փոխանցվող տվյալների յուրաքանչյուր բայթը անպայման գաղտնագրվում է 4-բայթանի դիմակով։ Դրանք յուրաքանչյուր հաղորդագրության համար նորից են ստեղծվում։

Փոխանցվող հաղորդագրությունը այժմ ունի վերնագիր, որում պարունակվում են այնպիսի տվյալներ, ինչպիսին են`
 ֆրագմենտացված է արդյոք հաղորդագրությունը,
 փոխանցվող տվյալների տիպը,
 արդյոք հաղորդագրությունը ենթարկվել է քողարկման,
 տվյալների մեծությունը,
 այլ տվյալներ (ping, pong...):
Կլիենտի և սերվերի միջև փոխգործակցությունը սկսվում է կլիենտի կողմից հարցմամբ։ 
 GET /chat HTTP/1.1
 Host: server.example.com
 Upgrade: websocket
 Connection: Upgrade
 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
 Sec-WebSocket-Origin: http://example.com
 Sec-WebSocket-Protocol: chat, superchat
 Sec-WebSocket-Version: 7
Սերվերի պատասխանը ունի հետևյալ տեսքը.
 HTTP/1.1 101 Switching Protocols
 Upgrade: websocket
 Connection: Upgrade
 Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 Sec-WebSocket-Protocol: chat
Պտասխանը պարունակում է Sec-WebSocket-Protocol վերնագիրը կլիենտի կողմից աջակցվող(chat, superchat) բոլոր արձանագրություններից սերվերի կողմից ընտրված (chat) միակ արձագրությամբ։ Sec-WebSocket-Accept վերնագիրը ձևավորվում է հետևյալ կերպ. 
 Sec-WebSocket-Key վերնագրից վերցնել տողային նշանակումը և միավորել 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 տողի հետ (տվյալ օրինակում կստացվի dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11),
 1 կետում ստացված տողից հաշվարկել բինար SHA-1 հեշը (20-նիշանոց բինար տող),
 Հեշը գաղտնագրել Base64-ի (s3pPLMBiTxaQ9kYGzzhZRbK+xOo=)
Վերոնշյալ ալգորիթմի իրագործման օրինակ PHP լեզվով։<?php echo base64_encode(SHA1("dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)); ?>

Արձանագրություն RFC 6455 
2011թ. դեկտեմբերի 11-ին արձանագրությունը ձեռք բերեց RFC կարգավիճակ:

Sec-WebSocket-Origin վերնագրի փոխարեն այժմ օգտագործվում է պարզապես Origin:

URL սխեմա 
Web Socket արձանագրությունը բնութագրվում է 2 URI սխեմաներով` ws: (չգաղտնագրված միացում) и wss: (գաղտնագրված միացում)։

WebSocket-ը բրաուզերներում 
Միացման համար կլիենտի սկրիպտը ստեղծում է WebSocket օբյեկտ, որի կոնստրուկտոր է փոխանցում WebSocket URI պարամետրը և որոշում է հետադարձ կանչի ֆունկցիաները միացման, հաղորդագրության ստացման և միացման ավարտի ժամանակ ։<html>
    <head>
        <script>
            var webSocket = new WebSocket('ws://localhost/echo');

            webSocket.onopen = function(event) {
                alert('onopen');
                webSocket.send("Hello Web Socket!");
            };

            webSocket.onmessage = function(event) {
                alert('onmessage, ' + event.data);
            };

            webSocket.onclose = function(event) {
                alert('onclose');
            };
        </script>
    </head>
    <body>
    </body>
</html>Ներկայումս WebSocket-ը աջակցվում է հետևյալ բրաուզերներում`
 Google Chrome (սկսած 4.0.249.0 տարբերակից),
 Apple Safari (սկսած 5.0.7533.16 տարբերակից),
 Mozilla Firefox (սկսած 4 տարբերակից),
 Opera (սկսած 10.70 9067 տարբերակից),
 Internet Explorer (սկսած 10 տարբերակից),
2010թ. նոյեմբերի վերջին Adam Barth-ը հրապարակեց օգտագործվող արձանագրության հուսալիության հետազոտության արդյունքները։ Նրա արդյունքներից պարզվեց, որ թափանցիկ պրոքսի-սերվերների օգտագործման դեպքում հնարավոր է փոխանցվող տվյալների կեշի փոխարինում այնպես, որ օգտատերերը իրական տվյալների փոխարեն կստանան տվյալների` չարամիտների տարբերակը։ Խնդիրը բավականին լուրջ էր, և Firefox-ի ու Opera-ի մշակողները հայտարարեցին, որ իրենց բրաուզերների հետագա տարբերակներում վեբ-սոքեթների աջակցումը ըստ լռելյայնի անջատված կլինի մինչ տվյալ արձանագրության անապահովության խնդրի լուծումը։

Հղումներ 
 RFC 6455 - The WebSocket protocol : Արձանագրության ստանդարտ
 HTML5 WebSocket API   W3C սպեցիֆիկացիայի սևագիր
 WebSockets.org  կայք` նվիրված WebSocket-ին
 WebSocketsTest.org կայք, որը ստուգում է WebSocket-ի և Comet-ի աշխատանքը ձեր բրաուզերում

Ծանոթագրություններ 

Համացանց