¡Websocket se ha jugado con muchos trucos!

Dachang Technology Advanced Front-end Nodo Avanzado

Haga clic en la guía de crecimiento del programador superior, preste atención al número público

Respuesta 1, únete al grupo de intercambio de nodos avanzado

Primero, necesitamos entender el principio del protocolo de enlace Websocket

afabbe7e77a825a7b8662ba93dc77b79.png

características del encabezado de solicitud

  • HTTP debe ser una solicitud GET 1.1

  • El valor del campo Conexión en el encabezado HTTP debe ser Actualizar

  • El campo Actualizar en el encabezado HTTP debe ser websocket

  • El valor del campo Sec-WebSocket-Key es una cadena aleatoria de 16 bytes codificada en base64

  • El valor del campo Sec-WebSocket-Protocol registra el subprotocolo utilizado, como base64 binaria

  • Origen indica la fuente de la solicitud

Características del encabezado de respuesta

  • El código de estado es 101 para los protocolos de conmutación

  • Actualizar/Conexión/Sec-WebSocket-Protocol es consistente con el encabezado de la solicitud

  • Sec-WebSocket-Accept es generado por Sec-WebSocket-Key del encabezado de solicitud

En segundo lugar, sondeo de conexión corta, conexión larga, comparación horizontal de Websocket

1. Sondeo de conexión corta

  • Conexión TCP muy cara

  • Y el encabezado se envía repetidamente

  • Y se inicia a través de una tarea de macro, que está limitada por el bucle de eventos y no puede garantizar la puntualidad.

  • Al mismo tiempo, habrá muchas solicitudes no válidas.

2. Conexión larga

  • Después de activar HTTP keep-alive, aunque TCP se puede reutilizar, el problema de la duplicación de encabezados no se ha resuelto.

  • Al mismo tiempo, HTTP keep-alive también tiene un período de validez. Después de que expire el período de validez, el servidor enviará un marco de exploración para verificar si el TCP es válido.

Fuera de contexto:

La función de HTTP keep-alive es decirle al servidor que mantenga la conexión  TCP actual  y que no la desconecte inmediatamente, para que las solicitudes HTTP posteriores puedan reutilizarla, que es lo que llamamos "conexión larga".

El keep-alive de HTTP es hacer que TCP dure más tiempo, y el propio TCP también tiene un mecanismo de keepalive (tenga en cuenta que no hay una barra horizontal). Este es un mecanismo de mantenimiento de conexión de TCP para detectar el estado de la conexión. Keepalive es un temporizador de mantenimiento de conexión de TCP: después de establecer TCP, si está inactivo, el servidor no puede esperar en vano. set], el servidor intentará enviar un paquete de detección al cliente para juzgar el estado de la conexión TCP. Si no se recibe una respuesta (paquete ACK) de la otra parte, se detectará nuevamente después de un tiempo [se puede configurar]. Respuesta, la conexión TCP se caerá

cec23f4557efcc5478aff8a4e89a083b.png

(Diagrama esquemático de TCP keepalive keepalive)

3. Conector web

  • Al igual que HTTP, se basa en el protocolo TCP, pero solo se puede usar un protocolo de enlace HTTP para establecer una conexión persistente, y no se usará HTTP posterior, sino un marco de datos específico de WebSocket.

  • Comunicación full duplex, transmisión de datos bidireccional

  • El formato de datos es liviano y admite el envío de datos binarios, admite ws y wss encriptado

3. ¿Con qué me he metido usando WebSocket en el subprograma WeChat?

1 Verificación de firma y estrategia de tolerancia a fallas correspondiente (requisitos de estado de inicio de sesión, acceso máximo, tiempo de inactividad anormal del servidor)

Antecedentes y objetivo:

  • Después del protocolo de enlace websocket, la solicitud de interfaz puede abandonar HTTP y cambiar a weboskcet, pero la mayoría de las interfaces comerciales requieren el estado de inicio de sesión, por lo que después de que el protocolo de enlace sea exitoso, primero se debe realizar la autenticación de firma para obtener el estado de inicio de sesión.

  • Cuando hay un escenario de acceso de gran tráfico (como grandes promociones, eventos importantes, etc.) o un error en el servidor hace que el servidor esté inactivo, el front-end hará la tolerancia a fallas correspondiente e inmediatamente degradará la solicitud pendiente en la cola de espera en la memoria para el envío HTTP.

Indicación de pseudocódigo:

SocketTask.onOpen(function () {
  SocketTask.sendSocketMessage({
     msg_type: '验签',
     token: 'xxx'
  }, (response) => {
      console.log(response.user_id, response.access_token)

      // 通道可用,打个标记
      global.isSocketAvaliable = true;
  })
})

2 Heartbeat mantener vivo (reducir el uso de TCP)

Antecedentes y propósito: para reducir la ocupación inválida de conexiones TCP, el cliente envía regularmente un paquete vacío al servidor para informarle que no destruya el socket.Si el servidor no recibe un paquete de latido dentro de un cierto período de tiempo , se cerrará y destruirá el socket.

Indicación de pseudocódigo:

SocketTask.onOpen(function () {
  SocketTask.sendSocketMessage({
     msg_type: '验签',
     token: 'xxx'
  }, (response) => {
      console.log(response.user_id, response.access_token)

      // 通道可用,打个标记
      global.isSocketAvaliable = true;
      
      // 验签成功,开始定时发送心跳包
      setInterval(() => {
          SocketTask.sendSocketMessage({
            msg_type: '心跳'
          });
      });
   });
})

3 Simular RTT (para optimización de experiencia de red débil)

Antecedentes y propósito: al enviar un paquete de latidos, se puede conocer el RTT de un paquete de latidos para simular el TCP RTT del entorno de red del usuario actual y, en base a esto, se puede calcular un RTO suave para optimizar la experiencia de red débil.

Indicación de pseudocódigo:

SocketTask.onOpen(function () {
  SocketTask.sendSocketMessage({
     msg_type: '验签',
     token: 'xxx'
  }, (response) => {
      console.log(response.user_id, response.access_token)

      // 通道可用,打个标记
      global.isSocketAvaliable = true;
      
      // 验签成功,开始定时发送心跳包
      setInterval(() => {
          // 计算 RTT
          const begin = Date.now();

          SocketTask.sendSocketMessage({
            msg_type: '心跳'
          }, () => {
            const end = Date.now();
            
            const RTT = begin - end;
            
            const smoothedRTO = cal(RTT);
            
            global.smoothedRTO = smoothedRTO;
          });
      });
   });
});

4 Compresión rápida (de lado en comparación con gzip/zip/7z)

Antecedentes y propósito: Introducir un paquete comprimido de terceros en el subprograma (sacrificando el tamaño del paquete del subprograma) para reducir la cantidad de bytes transmitidos por websocket

Indicación de pseudocódigo:

import Snappy from 'snappy';

  SocketTask.sendSocketMessage = function (msg) {
     const encryptedMsg = Snappy.encode(msg);
     
     wx.send(encryptedMsg);
  }

5 Reconexión (reconexión de dislocación escalonada para evitar aglomeraciones)

Antecedentes y propósito: el entorno de red del usuario es inestable, puede haber una desconexión activa/pasiva de los enchufes y se requiere una reconexión automática

Indicación de pseudocódigo:

SocketTask.onClose(function () {
  // 限定最大重连次数
  if (retryCount > maxCount) {
    return;
  }
  
  retryCount++;

  setTimeout(() => {
    SocketTask.connectSocket();
  }, retryCount * 1000 + Math.random() * 1000);
});

Caché de capa intermedia de 6 puntos enterrados (la información de usuario duplicada no se puede informar cada vez, admite actualización de caché)

Antecedentes y propósito: para reducir el volumen de paquetes de transmisión de la red, al informar registros de puntos ocultos a través de websocket, algunos valores de campo repetidos se pueden almacenar en caché en el servidor en el primer informe, y solo los campos con valores no repetidos se informan desde el segundo informe. , y luego el servidor realiza la combinación de registros

Indicación de pseudocódigo:

SocketTask.sendSocketMessage({
     msg_type: '埋点日志',
     logs: {
       country: 'China', // 可缓存字段
       city: '北京', // 可缓存字段
       platform: '安卓', // 可缓存字段
       click_some_btn: true // 动态变化的埋点字段
     },
     cacheFields: ['country', 'city', 'platform'] // 只在第一次上报时携带
 });

7 Habilitar TCP_NODELAY

TCP_NODELAY se usa para deshabilitar el algoritmo de Nagle. El propósito del diseño del algoritmo de Nagle es mejorar la utilización del ancho de banda de la red.

Referencia: https://www.zhihu.com/question/42308970

Node 社群


我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。

如果你觉得这篇内容对你有帮助,我想请你帮我2个小忙:

1. 点个「在看」,让更多人也能看到这篇文章2. 订阅官方博客 www.inode.club 让我们一起成长

点赞和在看就是最大的支持❤️

Supongo que te gusta

Origin blog.csdn.net/xgangzai/article/details/124373475
Recomendado
Clasificación