First, we need to understand the principle of Websocket handshake
Request header characteristics
- HTTP must be a 1.1 GET request
- The value of the Connection field in the HTTP Header must be Upgrade
- The Upgrade field in the HTTP Header must be websocket
- The value of the SEC-websocket-key field is a random 16-byte string encoded in Base64
- The value of the sec-websocket-protocol field records the subprotocol used, such as binary Base64
- Origin indicates the source of the request
Response head characteristic
- The status code is 101 representing Switching Protocols
- Upgrade/Connection/sec-websocket-protocol is consistent with the request header
- Sec-websocket-accept is generated with the sec-websocket-key of the request header
Second, short connection polling, long connection, Websocket horizontal comparison
1. Polling for short connections
- Expensive TCP connection
- And the Header is sent repeatedly
- In addition, due to the limitation of Event Loop, timeliness cannot be guaranteed due to macro task initiation
- At the same time, there are many invalid requests
2. Long connection
- After HTTP keep-alive is enabled, TCP can be reused, but the problem of duplicate headers is not solved
- In addition, HTTP keep-alive has an expiration date. After the expiration date, the server sends an investigation frame to check whether TCP is valid
An aside:
HTTP keep-alive tells the server to persist the current TCP connection and not break it immediately so that subsequent HTTP requests can reuse it.
HTTP’s keep-alive is designed to keep TCP alive longer, and TCP itself has a keepalive mechanism. Keepalive is a TCP keepalive timer that detects the status of a connection. After the construction of the TCP, idle useless, if the server can’t be white wait, after idle for a period of time can be set to [], the server will try to send the client detect package, to judge the TCP connection, if not received each other’s answer (ACK packet), will/can be set up to detect again in a minute, if times can be set to [] didn’t answer, The TCP connection is discarded
(Schematic diagram of TCP Keepalive)
3. Websocket
- Like HTTP, it is built on TOP of TCP, but only requires an HTTP handshake to establish a persistent connection, and then not HTTP, but WebSocket-specific data frames
- Full duplex communication, two-way data transmission
- Data format is lightweight and supports sending binary data, supports WS and encrypted WSS
Three, I use WebSocket in the micro channel small program have done what?
1 Verification and fault tolerance policies (login state requirements, peak access, and server outage exceptions)
Background and Purpose:
- After the Websocket handshake, the interface request can change from HTTP to WeboskCET. However, most service interfaces require login state. Therefore, after the handshake is successful, you must perform signature authentication to obtain the login state
- When the server is down due to heavy traffic (such as traffic promotion or hot activity) or a bug occurs on the server, the front end will perform fault tolerance to immediately degrade the pending requests in the memory waiting queue to HTTP
Pseudo-code hint:
SocketTask. OnOpen (function () {SocketTask. SendSocketMessage ({msg_type: 'attestation, token: 'XXX'}, (response) => {console.log(response.user_id, response.access_token) // Channel available, Set the mark global. issocketavalunavailable = true; })})Copy the code
2 Heartbeat Keepalive (Reducing TCP usage)
Background and Purpose: To reduce invalid TCP connection usage, the client periodically sends an empty packet to the server to inform the server not to destroy the socket. If the server does not receive heartbeat packets within a certain period of time, the client shuts down and destroys the socket
Pseudo-code hint:
SocketTask. OnOpen (function () {SocketTask. SendSocketMessage ({msg_type: 'attestation, token: 'XXX'}, (response) => {console.log(response.user_id, response.access_token) // Channel available, Set the mark global. issocketavalunavailable = true; / / attestation is successful, start regularly sends a heartbeat packet setInterval (() = > {SocketTask. SendSocketMessage ({msg_type: 'heartbeat'}); }); }); })Copy the code
3 Simulated RTT (for weak network experience optimization)
Background and Purpose: The RTT of a heartbeat packet can be obtained when sending heartbeat packets, so as to simulate the TCP RTT of the current user network environment and calculate smooth RTO for weak network experience optimization
Pseudo-code hint:
SocketTask. OnOpen (function () {SocketTask. SendSocketMessage ({msg_type: 'attestation, token: 'XXX'}, (response) => {console.log(response.user_id, response.access_token) // Channel available, Set the mark global. issocketavalunavailable = true; SetInterval (() => {// calculate RTT const begin = date.now (); SocketTask. SendSocketMessage ({msg_type: 'heartbeat'}, () = > {const end = Date. Now (); const RTT = begin - end; const smoothedRTO = cal(RTT); global.smoothedRTO = smoothedRTO; }); }); }); });Copy the code
4 Snappy Compression (horizontal comparison of Gzip/zip / 7Z)
Background & purpose: Introduce third party compressed packages in applets (at the expense of applets size) to reduce the number of bytes transmitted by WebSocket
Pseudo-code hint:
import Snappy from 'snappy';
SocketTask.sendSocketMessage = function (msg) {
const encryptedMsg = Snappy.encode(msg);
wx.send(encryptedMsg);
}
Copy the code
5 reconnection (step dislocation reconnection to avoid crowding)
Background and Purpose: The user’s network environment is unstable, and the socket may be disconnected actively or passively. In this case, automatic reconnection is required
Pseudo-code hint:
Sockettask.onclose (function () {if (retryCount > maxCount) {return; } retryCount++; setTimeout(() => { SocketTask.connectSocket(); }, retryCount * 1000 + Math.random() * 1000); });Copy the code
6 Buried middle layer cache (repeated user information can not be reported every time, support to refresh the cache)
Background and Purpose: To reduce the volume of packets transmitted over the network, when webSocket is used to report buried point logs, the server can cache some of the repeated field values in the first report. From the second report, only the fields with different values are reported, and then the server merges the logs
Pseudo-code hint:
SocketTask. SendSocketMessage ({msg_type: 'burial site logs, logs: {country:' China ', / / cacheable field city: 'Beijing', / / cacheable field platform: 'Android ', // cacheable click_some_bTN: true // dynamic cacheFields}, cacheFields: ['country', 'city', 'platform'] // only for first reporting});Copy the code
7 enable TCP_NODELAY
TCP_NODELAY is used to disable the Nagle algorithm. Nagle algorithm is designed to improve network bandwidth utilization. Its core idea is to “merge small TCP packets into a large TCP packet”, so as to avoid wasting network bandwidth by too many TCP headers of small packets
Reference data: www.zhihu.com/question/42…
❤️ Thank you
That is all the content of this sharing. I hope it will help you
Don’t forget to share, like and bookmark your favorite things.
Welcome to the public account ELab team harvest dachang good article ~
We are from the front end department of Bytedance, responsible for the front end development of all bytedance education products.
We focus on product quality improvement, development efficiency, creativity and cutting-edge technology and other aspects of precipitation and dissemination of professional knowledge and cases, to contribute experience value to the industry. Including but not limited to performance monitoring, component library, multi-terminal technology, Serverless, visual construction, audio and video, artificial intelligence, product design and marketing, etc.
Bytedance correction/social recruitment promotion code: 8V6EAKQ
Post links: jobs.toutiao.com/s/L2AECBj