One 、WebSocket origin
WebSocket It's a persistent protocol , Pass for the first time HTTP Request Once the connection is established , Then upgrade the communication protocol to websocket, Keep connected , Subsequent data exchange does not require repeated requests .websocket It can be regarded as a kind of TCP/IP Of socke t technology , stay web In application 、 And get the same TCP/IP The same two-way communication function as communication , Therefore, both the client and the server can send and receive messages , At the same time, it also supports the function of multiplexing , Because it borrows HTTP Some of the concepts of the agreement , So it's called WebSocket.
webSocket API Defined web A common interface between an application and a server , Concrete constructors create objects 、 Object properties 、 Method 、 Event and its meaning , In the last article 《HTML5( 11、 ... and )——WebSocket Basic course 》 The article has described in detail .
Two 、WebSocket Communication process
WebSocket The agreement can be divided into two parts : Handshake phase and data communication phase .
WebSocket For application layer protocol , It's defined in TCP/IP On the protocol stack , Connect to the server url In order to ws or wss At the beginning .ws The default at the beginning TCP Port is 80,wss The default port at the beginning is 443.
ws(websocket) It's not safe , Easily bugged , As long as others know your ip And port number , Anyone can connect to the communications .
wss(web socket secure) yes websocket The encrypted version of .
2.1、 Establishing a connection
The client establishes a connection with the server TCP Connect , Client generation websocket object , And then use API Establishing a connection , The code is as follows :
let ws= new WebSocket('ws://localhost:8888') ws.onopen = function(){ console.log(" Connect ") }
2.2、 handshake phase
After the client establishes a connection with the server , Client sends handshake request , Then the server sends a handshake response to complete the handshake phase .
The client handshake request is as follows :
'GET / HTTP/1.1',
'Host: localhost:8888',
'Connection: Upgrade',
'Pragma: no-cache', 'Cache-Control: no-cache', 'Upgrade: websocket', 'Origin: file://', 'Sec-WebSocket-Version: 13', 'Accept-Encoding: gzip, deflate, br', 'Accept-Language: zh-CN,zh;q=0.9', 'Sec-WebSocket-Key: In1aAp/ya9Lkv+tsUtXLXQ==', 'Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits',
The server handshake response is as follows :
Status Code: 101 Switching Protocols Connection: Upgrade sec-websocket-Accept: HBMDBbZMiS59r3aAITpGtJ64Mfc= Upgrade: websocket
2.3、 Data communication
WebSocket After the handshake connection is successful . have access to send Send data ,onmessage receive data , Send as follows “ Hello ”:
let ws= new WebSocket('ws://localhost:8888') ws.onopen = function(){ console.log(" Successful connection ") ws.send(" Hello ") } ws.onmessage = function(res){ console.log(' Messages received ',res) }
The server prints the received data , Such as :<Buffer 81 86 af 87 53 b4 4b 3a f3 51 0a 3a>.
websocket When sending data , Organized into a series of data frames , Then send . The transmitted frame consists of two parts : Data frame and control frame . Data frames can carry text data or binary data , The control frame consists of a close frame and Ping/Pong frame .

- FIN :1bit , Represents the last frame of the message , If the message has only one frame, then the first frame is the last frame .
- RSV1,RSV2,RSV3: Every 1bit, Must be 0, Unless the extension is defined as non-zero . If a non-zero value is accepted but the extension is not defined , You need to close the connection .
- Opcode:4bit, explain Payload data , There are the following different states , If it's unknown , The receiver must close the connection immediately . State the following :0x0( Additional data frames ) 0x1( Text data frame ) 0x2( Binary data frame ) 0x3-7( Reserved for later non control frame use ) 0xB-F( Reserved for later control frames ) 0x8( Close connection frame ) 0x9(ping) 0xA(pong)
- Mask:1bit, Mask , Definition payload Whether the data is masked , If it is 1 Indicates that the mask processing is performed .Masking-key The data of the domain is the mask key , Used to decode PayloadData. The data frame sent by the client needs to be masked , So this bit is 1.
- Payload length:7 position ,7 + 16 position ,7+64 position ,payload Length of data , If it is 0-125, It's real payload length , If it is 126, Then go on to the back 2 Bytes correspond to 16 A bit unsigned integer is payload Data length ; If it is 127, Then go on to the back 8 Bytes correspond to 64 A bit unsigned integer is payload Length of data .
- Masking-key:0 To 4 byte , If MASK Set as 1 Then there are 4 Byte mask decryption key , Otherwise, there will be no .
- Payload data: Any length of data . Including extended definition data and application data , If there is no extension defined, there is no such item , Only application data .
Put the received buffer Convert hexadecimal data to binary data , The control frame is compared with the above types of frames to analyze its significance .
2.4、 Close the connection
Either end can close the connection . The client closes the connection as follows :
ws.close()
Then send the close frame to the other party , Usually with a status code to close the connection , Common status codes are as follows :
- 1000 Connection closed normally
- 1001 Endpoint offline , For example, server down, Or the browser has left this page
- 1002 The endpoint was disconnected due to protocol error
- 1003 The endpoint was disconnected due to an unacceptable data type
- 1004 Retain
- 1005 Retain , It is used to prompt that the application has not received the status code of connection closing
- 1006 The endpoint closes abnormally
- 1007 The data frame type received by the endpoint is inconsistent, resulting in connection closure
- 1008 Close the connection due to data violation
- 1009 The received message data is too large to close the connection
- 1010 The client was shut down because the server did not negotiate extensions
- 1011 The server closed the connection because of an exception
- 1015 TLS Handshake failed. Close connection
3、 ... and 、websocket example
3.1、 Client creation websocket object , And send data after establishing a connection . among ws The address corresponds to the background service port .
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let ws= new WebSocket('ws://localhost:8888') ws.onopen = function(){ console.log(" Connect ") ws.send(" Hello ") } ws.onmessage = function(res){ console.log('res',res) } </script> </body> </html>
3.2、 Use node.js Create a websocket service , Such as creating a serve.js file , The code is as follows :
const http = require("http") const net = require("net") // Native websocket const crypto = require('crypto') // Security verification let serve = net.createServer(sock=>{ // Just shake hands once sock.once('data',(data)=>{ console.log("hand shake start") // Start shaking hands let str = data.toString(); let lines = str.split('\r\n') // Discard the first and last two lines lines = lines.slice(1,lines.length-2) let headers = {} lines.forEach(line=>{ let [key,val] = line.split(': ') headers[key.toLowerCase()] = val }) if( headers['upgrade']!= 'websocket' ){ console.log(" Other agreements ") sock.end() }else if(headers['sec-websocket-version']!=13){ console.log(" Wrong version ") sock.end() }else{ let key = headers['sec-websocket-key'] let mask = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' //sha1(key+mask) -> base64 =>client let hash = crypto.createHash('sha1') hash.update(key+mask) let key2 = hash.digest('base64') sock.write(`HTTP/1.1 101 Switching Protocols\r\nUpgrade:websocket\r\nConnection:Upgrade\r\nsec-websocket-Accept:${key2}\r\n\r\n` ) console.log("hand shake end") // End of handshake // The real data sock.on('data',res=>{ console.log(" Actually receive data ",res) // Data analysis let FIN = res[0]&0x001; let opcode = data[0]&0x0F0; let msak = data[1]&0x001; let payload = data[1]&0x0FE; }) } }) // To break off sock.on('end',()=>{ console.log(" connection dropped ") }) }) serve.listen("8888")
Use command node serve.js or node serve Start the service , After the service is started successfully, you can use localhost:8888 Access the service .
After starting the service , Access the... Created earlier html File access websocket service .
Four 、websocket The advantages of
- First pass http Once the connection is established , Data interaction does not need to be sent http request , Saving bandwidth resources .
- websocket The connection is two-way communication , The server and client can both accept and send messages .
- websocket Multiplexing , Several differences url You can reuse one websocket service .
- yes HTML5 One of the techniques , It has great application prospects .