Home
Github
Personal blog
Weibo
To subscribe to
- Posts – 119, Articles – 20, Comments – 1155
- Cnblogs
- Dashboard
- Login
Barret Lee console.log( ” Hi, I’m Barret, a Web Developer, try to be Excellent~ ” );
More on websocket-Node
2013-12-20 13:42 by Barret Lee, 22526 Read, 20 commentscollection.The editor
In the last article, various methods of Web communication were improved, including polling, long connections, and various methods mentioned in HTML5. This article will describe the implementation of WebSocket protocol in Web communication in detail.
WebSocket protocol
1. An overview of the
The WebSocket protocol allows untrusted client code to control remote hosts in a controlled network environment. The protocol consists of a handshake and a basic message frame, layered through TCP. To put it simply, a handshake response followed by a secure information pipeline is superior to the XMLHttprequest-based IFrame data stream and long polling described above. There are two aspects of the protocol, Handshake and data transfer.
2. Handshake connection
This part is easy, like saying hello to someone you know on the road.
Client: Hey, buddy, do you have a light? (Cigarette passes) Server: Ha, yes, come on. (Light) Client: Matches, ok! (Smoke point, verified)Copy the code
During the handshake connection, the client extends its hand first:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13Copy the code
The client sends a Base64 encrypted Key, the sec-websocket-key you see above. When the Server sees the greeting from the Client, he quietly tells the Client that he knows about it and also says hello.
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chatCopy the code
The Server returns the sec-websocket-accept reply, which is generated in a certain way. The generation algorithm is:
mask = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; Accept = base64(sha1(key + mask));Copy the code
After the key and mask are connected in series, they are processed by SHA-1, and the processed data is encrypted by Base64. Break down the action:
1. t = "GhlIHNhbXBsZSBub25jZQ==" + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-> "GhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
2. s = sha1(t)
-> 0xb3 0x7a 0x4f 0x2c 0xc0 0x62 0x4f 0x16 0x90 0xf6
0x46 0x06 0xcf 0x38 0x59 0x45 0xb2 0xbe 0xc4 0xea
3. base64(s)
-> "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="Copy the code
The HTTP status code returned by the Server is 101. If it is not 101, the handshake failed at the beginning
Here’s a demo, shake hands with the server:
var crypto = require('crypto'); require('net').createServer(function(o){ var key; o.on('data',function(e){ if(! Key){// handshake // reply, omit console.log(e.tostring ()); }else{ }; }); }).listen(8000);Copy the code
Client code:
Var ws = new WebSocket (ws: / / 127.0.0.1: "8000"); ws.onerror=function(e){ console.log(e); };Copy the code
The above is, of course, a string of incomplete code designed to demonstrate that the client greets the server during a handshake. On the console we can see:
An HTTP request is sent, and this can also be seen in the Network browser:
But WebSocket protocol is not HTTP protocol, at the beginning of the verification of the use of HTTP headers, the connection after the success of the communication is not HTTP, do not believe you use Fiddler2 to capture the packet, certainly can not get, behind the communication part is based on TCP connection.
For the server to communicate successfully, there must be a reply. Look below:
Var crypto = require('crypto'); var WS = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; require('net').createServer(function(o){ var key; o.on('data',function(e){ if(! Key) {/ / handshake key = e. oString () the match (/ Sec - WebSocket - key: (. +) /) [1]. key = crypto.createHash('sha1').update(key + WS).digest('base64'); O.w rite (' HTTP / 1.1 101 Switching separate Protocols \ r \ n '); o.write('Upgrade: websocket\r\n'); o.write('Connection: Upgrade\r\n'); o.write('Sec-WebSocket-Accept: ' + key + '\r\n'); o.write('\r\n'); }else{ console.log(e); }; }); }).listen(8000);Copy the code
The crypto module, you can see the official documentation, the above code should be very easy to understand, after the server responds, the Client gets sec-websocket-Accept, and then does a local verification, if the verification passes, will trigger the onopen function.
Var ws=new WebSocket("ws://127.0.0.1:8000 "); Ws. onopen=function(e){console.log(" handshake succeeded "); };Copy the code
You can see
3. Data frame format
The official documentation provides a structure
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+Copy the code
The first time you look at this picture, you’re probably going to vomit blood. If you’re modifying computer networks in college, you’re going to be familiar with this. Data transfer protocols need to define the length of bytes and what that means.
FIN 1bit Indicates the last frame of the message. RSV 1-3 1bit Each is 0 by default. Opcode 4bit indicates the frame type. Payload 7bit length of data Masking-key 1 or 4 bit mask Payload data (x + y) bytes data Extension data x bytes extended data Application Data Y Bytes Indicates program dataCopy the code
Every frame is transmitted in accordance with the protocol rules, know this protocol, then the parsing is not too difficult, I will directly take the cobalt carbonate students code.
4. Data frame parsing and coding
Data frame parsing code:
Function decodeDataFrame(e){var I =0,j,s,frame={FIN:e[I]>>7,Opcode:e[I ++]&15,Mask:e[I]>>7, PayloadLength:e[i++]&0x7F }; If (frame.PayloadLength==126) frame.length=(e[i++]<<8)+e[i++]; If (frame.PayloadLength==127) I +=4, The first four bytes are usually long plastic blank frame. The length = ([i++] < < 24) + e (e/i++ < < 16) + (e/i++ < < 8) + e [i++]; / / determine whether use Mask if (frame. Mask) {/ / frame to Mask item. MaskingKey = [[i++], [i++], e e e [i++], e [i++]]. For (j=0,s=[]; j<frame.PayloadLength; j++) s.push(e[i+j]^frame.MaskingKey[j%4]); }else s=e.slice(i,frame.PayloadLength); S =new Buffer(s); // Convert the buffer to a string if necessary using if(frame.opcode ==1)s= s.tostring (); // Set the data part on frame.PayloadData=s; // Return frame; }Copy the code
Data frame encoding:
//NodeJS function encodeDataFrame(e){ var s=[],o=new Buffer(e.PayloadData),l=o.length; // enter the first byte s.pen ((e.fin <<7)+ e.opcode); // Never use the mask if(l<126) s.ush (l); else if(l<0x10000)s.push(126,(l&0xFF00)>>2,l&0xFF); Else s.ush (127, 0,0,0,0, //8 bytes data, the first 4 bytes are not left blank (l&0xFF000000)>>6,(l&0xFF0000)>>4,(l&0xFF00)>>2,l&0xFF); // Return buffer. concat([new Buffer(s),o]); }Copy the code
Some children may not understand which data to parse. The parse task is mainly handled by the server. The data sent by the client is in binary stream form, for example:
Var ws = new WebSocket("ws://127.0.0.1:8000/");
ws.onopen = function(){
Ws. send(" Handshake successful ");
};Copy the code
The Server receives the following message:
A binary stream in Buffer format. Parse the binary stream as we output:
Var crypto = require('crypto'); var WS = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; require('net').createServer(function(o){ var key; o.on('data',function(e){ if(! Key) {/ / handshake key = e. oString () the match (/ Sec - WebSocket - key: (. +) /) [1]. key = crypto.createHash('sha1').update(key + WS).digest('base64'); O.w rite (' HTTP / 1.1 101 Switching separate Protocols \ r \ n '); o.write('Upgrade: websocket\r\n'); o.write('Connection: Upgrade\r\n'); o.write('Sec-WebSocket-Accept: ' + key + '\r\n'); o.write('\r\n'); }else{console.log(decodeDataFrame(e)); }; }); }).listen(8000);Copy the code
The output is an object with very clear frame information:
5. Connection control
Above I bought a mystery, mentioned the Opcode, did not elaborate, the official document also gave a table:
|Opcode | Meaning | Reference | -+--------+-------------------------------------+-----------| | 0 | Continuation Frame | RFC 6455 | -+--------+-------------------------------------+-----------| | 1 | Text Frame | RFC 6455 | -+--------+-------------------------------------+-----------| | 2 | Binary Frame | RFC 6455 | -+--------+-------------------------------------+-----------| | 8 | Connection Close Frame | RFC 6455 | -+--------+-------------------------------------+-----------| | 9 | Ping Frame | RFC 6455 | -+--------+-------------------------------------+-----------| | 10 | Pong Frame | RFC 6455 | -+--------+-------------------------------------+-----------|Copy the code
DecodeDataFrame parses data in the following format:
{FIN: 1, Opcode: 1, Mask: 1, PayloadLength: 4, MaskingKey: [159, 18, 207, 93], PayLoadData: 'Handshake successful'}Copy the code
So as you can see above, the purpose of this frame is to send text, which is a text frame. The connection is based on TCP, so if you close the TCP connection, the channel will be closed. However, WebSocket is designed to be humanized, and we will notify you before closing it. On the server side, you can determine the frame Opcode:
var frame=decodeDataFrame(e); console.log(frame); if(frame.Opcode==8){ o.end(); // Disconnect}Copy the code
The format of the data (frames) that the client and server interact with is the same, as long as the client sends Ws.close (), the server performs the above operation. Conversely, if the server sends the same close frame to the client:
o.write(encodeDataFrame({
FIN:1,
Opcode:8,
PayloadData:buf
}));Copy the code
The client will respond to the onclose function, so that the interaction is orderly and not prone to error.
Two, matters needing attention
1. WebSocket URIs
Many people may only know ws://text.com:8888, but in fact websocket addresses can be added with path and query.
ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]Copy the code
If the WSS protocol is used, urIs will be connected in a secure manner. The WSS is case insensitive here.
2. The “redundant” part of the agreement
The handshake request contains the sec-websocket-key field, which is a WebSocket connection, and the encryption method of this field is fixed on the server, so if someone wants to hack you, it won’t be too difficult.
Then there is the MaskingKey Mask, since the encryption is mandatory (Mask 1 means encryption, MaskingKey and PayLoadData are xor processing), is there any need for developers to handle this thing? Why don’t we just encapsulate it internally?
3. Relationship with TCP and HTTP
The WebSocket protocol is a TCP-based protocol, which is associated with HTTP (sending an HTTP request) when shaking a connection. This request has been switched to (Upgrade) WebSocket by the Server. Websocket uses port 80 as the default webSocket connection port, and WebSocket runs on port 443.
Iii. Reference materials
- Tools.ietf.org/html/rfc645… web standard – The WebSocket Protocol
- www.w3.org/TR/websocke… W3.ORG – WebSockets
Iv. Special thanks
Thanks again for talking to me for a few hours:), part of this node code is from his blog.
Next time, WE will use PHP as the background to explain websocket.
Elaborate the WebSocket – PHP
To admire the
Copyright notice: Signature – Non-commercial Use – No Deductive 3.0 International (CC BY-NC-ND 3.0)
- Categories: HTML + CSS [3] [5], JavaScript, and Others
- Tags: javascript, communication, webSocket
-
# 1 / f, simonleung The 2013-12-20 o
Websocket starts the handshake with the HTTP onUpgrade event
Not onData with NET.
Nodejs.org/api/http.ht… Support (0) Against (0) -
# 2 floor[I] Barret Lee In 2013-12-20 he
@ simonleung
Net data is more low-level than HTTP onUpgrade.
From the description of the WebSocket protocol to the presentation of the test results, there was no problem.Support (0)Against (0) http://pic.cnblogs.com/face/387325/20150805014702.png -
The # 3 floor Nimah Fan Bingbing The 2013-12-20 and
Well written, I admireSupport (0)Against (0) http://pic.cnblogs.com/face/395638/20140818132358.png
-
# 4 floor Boolean The 2013-12-20 22:04
When using Node-WebKit, I do not know why the number of connections (more than 100) slow accessSupport (0)Against (0) http://pic.cnblogs.com/face/u17705.jpg
-
The # 5 floor Two teacher younger brother Tony The 2013-12-21 11:56
I’m looking for this kind of articleSupport (0)Against (0) http://pic.cnblogs.com/face/348990/20160120104927.png
-
# 6 building Ace8793 The 2013-12-22 22:00
mark Support (0)Against (0) http://pic.cnblogs.com/face/377458/20161107194642.png
-
# 7 floor flyher The 2013-12-23 08:26
@BarretLee
Good article, I saw it on Monday, I really met you too late.Support (0)Against (0) http://pic.cnblogs.com/face/u218282.jpg -
# 8 floor, dotNetDR_ The inscription 2013-12-24
Good ~Support (0)Against (0) http://pic.cnblogs.com/face/u59691.jpg
-
# 9 / f, Calculus g The 2013-12-26 21:07
Good, study!Support (0)Against (0)
-
# 10 floor It the Smurfs The 2014-03-26 20:08
learningSupport (0)Against (0)
-
# 11 floor The topic leaf The 2014-04-02 10:54
Honey, the picture kneelsSupport (0)Against (0)
-
# 12 floor[I] Barret Lee The 2014-04-02 thus
@The topic leaf
I have a good, you refresh is not good?Support (0)Against (0) http://pic.cnblogs.com/face/387325/20150805014702.png -
# 13 floor mcarzx The 2014-04-21 17:46
T =” GhlIHNhbXBsZSBub25jZQ==
. 2, the console log (crypto createHash (‘ sha1). Update (‘ dGhlIHNhbXBsZSBub25jZQ = = 258 eafa5 E914-47 – da – 95 ca – C5AB0DC85B11 ‘). The digest (‘ s ha1’)); // outputs: <SlowBuffer b3 7a 4f 2c c0 62 4f 16 90 f6 46 06 cf 38 59 45 b2 be c4 EA >
If (frame.PayloadLength==126) frame.length=(e[2]<<8) + e[3], I =4; // frame. Length should be frame.Payloadlength. And also in the next line. Check it out. Cobalt subcarbonate. It’s changed over there.
S.ush (126,(l&0xFF00)>>2, L &0xFF); Where >>2, it seems to be >>8. The next line is similar.Support (0)Against (0) -
# 14 floor prof The 2014-11-12 21:03
Could you please tell me, moustache brother, how does postMessage communicate across domainsSupport (0)Against (0)
-
# 15 floor[I] Barret Lee The 2014-11-12 21:51
@prof
Page A communicates with iframe B, A foreign domain of the page.
PostMessage and onMessage are both fired in the same window object.
Handle to the window in A for B, use the biggest ontentWindow. PostMessage sends A message to B, B in onmessage listening in.
B sends messages to A based on the principle that B obtains A’s window handle and sends messages to A using A.parent.postMessage, where A has onMessage listening.
The same window sends a message to itself, but if we get the handle from another window, such as ifame. ContentWindow, or if we get the window from another window, window.parent.
It’s not your ability to understand, it’s your inability to understand these concepts. Still do not understand please read the MSDN/MDN document yourself.Support (0)Against (0) http://pic.cnblogs.com/face/387325/20150805014702.png -
# 16 floor riskers The 2015-03-04 14:24
After the reference key and mask are concatenated, they are processed by SHA-1, and the processed data is encrypted by Base64.
Base64 is an encoding method, not encryptionSupport (0)Against (0) -
# 17 floor CoderZ The 2015-06-29 at 12:05
Please ask little beard brother, just implemented your method is good. IO request header does not contain any websocket information, but it is based on webSocket.Support (0)Against (0) http://pic.cnblogs.com/face/579305/20131227132708.png
-
# 18 building Got kicked male. Orz The 2015-07-20 15:55
mark Support (0)Against (0) http://pic.cnblogs.com/face/520225/20131008114345.png
-
# the 19th floor gongmaolan123 The 2017-01-13 thou
GoEasy Web implements real-time web push in three easy steps
1. The introduction of goeasy. Js
2. Client subscription,
Var goeasy = new goeasy ({appKey: ‘your appkey’});
Goeasy. Subscribe (channel: “your channel”, the onMessage: function (the message)
{alert (‘ a received message ‘+ message. The content)}
)
3. Three push modes
Goeasy. Publish ({channel: ‘your channel’, message: ‘your publish MSG’});
Java SDK:
GoEasy GoEasy = new GoEasy(” appkey “);
Goeasy. The publish (” your channel “, “your MSG”);
RestAPI: Goeasy. IO/goeasy/publ…
Easy web push and receive in three steps. Website:goeasy.io, complete documentationSupport (0)Against (0) -
# 20 buildings38077282017/10/11 18:57:09 Cinux, The 2017-10-11 18:57
@ simonleung
HTTP module is based on NET, NET does not have this eventSupport (0)Against (0)
Blog readdress: http://barretlee.com
@Barret
A mustache and elder brother
barretlee
Barret Lee
Five years and seven months
Recommend the blog
2731
20
+ add attention
The latest essays
- Nginx configuration overview
- Talk about my growth in Ali
- Revealed 0.1 + 0.2! = 0.3
- How to be a good intern
- Talk about my technical growth in the last three years
- Work for five years and repeat the first year for the next four?
- ECMAScript 6 literacy
- The current end also has Server capabilities
- Describe the operation process of OAuth 2.0
- Front-end technology inventory in recent years and technology development direction in 2016
- NodeJS code debugging and performance tuning
- New app comes on Snippet
- What about these two days of Apple software poisoning?
- Site SEO and the secrets between it and webmaster tools
- Blogs have migrated to http://barretlee.com/entry/, share here from time to time synchronization
The latest comments
- Re: More on websocket-PHP
Learn, thank you — Stormpass - Re: Talk about my growth in Ali
Moustache, we’ll meet again - Re: More on Websocket-Node
@simonleung HTTP module is written based on NET, NET does not have this event — Cinux, - Re: collects and monitors front-end code exception logs
Even the browser source are moved out, have to praise — cloud – - Re: Implementation of javascript chained invocation
You’re good! They are very inadequate, still need to work hard. Doomed to be abused by code
Archives of essays
- November 2016 (1)
- October 2016 (3)
- July 2016 (3)
- February 2016 (1)
- January 2016 (2)
- October 2015 (1)
- September 2015 (4)
- August 2015 (6)
- July 2015 (1)
- May 2015 (2)
- April 2015 (4)
- December 2014 (1)
- November 2014 (1)
- October 2014 (1)
- September 2014 (1)
- August 2014 (4)
- July 2014 (1)
- May 2014 (6)
- April 2014 (4)
- March 2014 (8)
- February 2014 (7)
- January 2014 (4)
- December 2013 (6)
- November 2013 (5)
- October 2013 (2)
- September 2013 (3)
- August 2013 (3)
- July 2013 (3)
- June 2013 (6)
- May 2013 (5)
- April 2013 (12)
- March 2013 (6)
- September 2012 (2)
javascript
- ajaxian
- alistapart
- developer.mozilla.org
- diveintohtml5
- ecmascript
- Eric Meyer
- es5
- nanto
- perfectionkills
- ppk
- sitepoint
- webfx
- Webkit documentation
- High performance Website construction
The calendar
|
||||||
day | one | two | three | four | five | six |
---|---|---|---|---|---|---|
29 | 30 | 31 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
Classification of essays
- AJAX(5)
- Cross Domain(3)
- Design patterns(4)
- DOM(2)
- ECMAScript specification (8)
- HTML[5]+CSS[3](17)
- JavaScript(62)
- Javascript plugins(7)
- jQuery and plugins(1)
- Linux(2)
- Node(5)
- Others(52)
- PHP(4)
- translation(4)
Recommended leaderboard
- 1. View the front end from the Login box (136)
- 2. Front-end Technology Inventory in recent years and technology development Direction in 2016 (85)
- 3. Front-end code anomaly log collection and monitoring (63)
- 4. I stayed with Ali for three months (62)
- 5. Principle of Asynchronous JavaScript Programming (43)
- 6. JavaScript Template Engine Principles, A Few lines of Code (36)
- 7. Why does the modification of Hosts not take effect? DNS cache? (29)
- 8. How to Make your JavaScript Code more semantic (25)
- 9. Websocket-node in Detail (23)
- 10. JavaScript Multi-file Download (23)
Reading leaderboards
- 1. Websocket-php in detail (40514)
- 2. Front View from the Login box (29573)
- 3. Implementation and Application of PJAX (27324)
- 4. Make the browser no longer display HTTP request alerts in HTTPS pages (25059)
- 5. JavaScript Template Engine principle, a few lines of code (23234)
- 6. Websocket-node in detail (22523)
- 7. Front-end code anomaly log collection and monitoring (21883)
- 8. JavaScript Multi-file Download (21859)
- 9. Principle of Asynchronous JavaScript Programming (17802)
- 10. Why does the modification of Hosts not take effect? DNS cache? (16597).
css
- css-tricks
- CSS manual
- css-infos.net/
- sketchpad
friends
- Aaron
- Rss Barret Lee
- guangwong
- Rss Time cobalt carbonate
- The sea cast net
- Tencent AlloyTeam
- Small flying fish with jade face
- Rss Zhang Xinxu
Tools
- cleancss
- css-validator
- proxyie.cn/
- jsbeautifier
- JSLint
- Packer-Decoder
- regexper
- RunJS
- stackoverflow
- User Agent
- Formatting HTML online
Ready to do
- Learning front-end architecture ideas
- ECMAScript6 research
- Read ECMA – 262
Recently in the…
- Micro share
- The animation library
- – _ – please _ please work
advertising
- Taobao UED front-end intern, where is your resume? Send it here at [email protected]
- I’ve been doing some micro-sharing
The source code
feedback
- Current 201 group chat 0