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