¿No entiendes websocket? Este artículo te permite comprender a fondo el principio de websocket

Acerca del análisis de video de websocket:

Charla en profundidad sobre el protocolo websocket, la subcontratación tcp y las soluciones de paquetes adhesivos, las
técnicas de entrevista de las grandes empresas y los escenarios de uso y los esquemas de implementación del protocolo websocket

Primero, veamos los antecedentes de websocket. Sabemos que el protocolo de la serie http se basa en tcp. En teoría, puede comunicarse en ambas direcciones. Pero antes de http1.1, el servidor no implementó la función push. Cada vez es una solicitud del cliente y el servidor responde. Echemos un vistazo al desarrollo del protocolo HTTP en el procesamiento de solicitudes.

  1. En http1.0, el ciclo de vida de una solicitud http es que el cliente inicia la solicitud, el servidor responde y la conexión se desconecta. Pero sabemos que la desventaja del protocolo tcp es que toma tiempo para el protocolo de enlace de tres vías, junto con el inicio lento y otras características, si cada solicitud http es así, la eficiencia es muy baja.
  2. En http1.1, la conexión larga está habilitada de forma predeterminada (el encabezado de mantener vivo se establece en la solicitud del cliente). Después de que el servidor procesa una solicitud, no cerrará la conexión inmediatamente, sino que esperará un cierto tiempo. La conexión se cierra si no hay solicitud. De esta manera, el navegador no solo puede enviar solicitudes continuamente en una conexión tcp (el servidor también limitará el umbral de solicitud que se puede procesar en una conexión), sino que incluso puede enviar muchas solicitudes a la vez. Esta es la tecnología de canalización de http1.1. Pero también tiene un problema, porque para un cliente basado en el protocolo http, aunque puede enviar muchas solicitudes, cuando una solicitud regresa, no puede saber a qué solicitud pertenece. Por lo tanto, los paquetes devueltos solo se pueden devolver en el orden solicitado, lo que conduce a otro problema: Bloqueo de cabeza de enlace. Y aunque http1.1 admite conexiones largas, no admite la capacidad del servidor de empujar (empujar). Si el servidor tiene datos para entregar al cliente, solo puede esperar a que el cliente los recupere (extracción).
  3. Cuando se trata de http2.0, no solo se realiza la inserción del servidor, sino que también se utilizan tecnologías como frame (iframe) y stream (stream) para resolver el problema del bloqueo de subprocesos. En una conexión tcp, http2.0 puede enviar múltiples http solicita al mismo tiempo. Cada solicitud es una secuencia, y una secuencia se puede dividir en muchos marcos. Con el número de etiqueta, el servidor puede devolver el paquete a voluntad. Una vez que el cliente lo recibe, puede volver a ensamblarlo según la etiqueta.

Los anteriores son algunos desarrollos del protocolo http sobre solicitudes, y websocket proporciona otra solución para la inserción del servidor. Es esencialmente otro protocolo de capa de aplicación (protocolo websocket) encapsulado en el protocolo tcp. Debido a que se basa en tcp, la inserción del lado del servidor, naturalmente, no es un problema. Sin embargo, en términos de implementación, no se conecta directamente a una conexión tcp y luego transmite paquetes de datos basados ​​en el protocolo websocket. Implica un proceso de actualización (intercambio) de protocolo. Veamos este proceso.

1 El cliente envía una solicitud de actualización del protocolo. Agregue el siguiente encabezado http a la solicitud http

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: k1kbxGRqGIBD5Y/LdIFwGQ==
Sec-WebSocket-Version: 13
Upgrade: websocket

2 Si el servidor admite el protocolo websocket, devolverá un código de estado 101 para indicar que está de acuerdo con la actualización del protocolo y admite varias configuraciones (si el servidor no admite ciertas funciones o versiones, o dígale al cliente que el cliente puede enviar una solicitud de actualización de protocolo nuevamente). El servicio devolverá el siguiente encabezado http (consulte el protocolo websocket).

Connection: Upgrade
Sec-WebSocket-Accept: y73KZR4t+hqD6KKYbkx2tULfBsQ=
Upgrade: websocket

3 Esto completa la actualización del protocolo La comunicación de datos subsiguiente se basa en la conexión tcp y utiliza el paquete de datos encapsulado por el protocolo websocket.

Entendamos este proceso a través de wirehark. Primero iniciamos un servidor (ip: 192.168.8.226).

var http = require('http');
var fs = require('fs');
const WebSocket = require('ws');
// 如果在浏览器控制台进行测试,可以不起http服务器
const server = http.createServer(options,function(req,res){
    
    
    res.end(fs.readFileSync(`${
    
    __dirname}/websocket.html`));
}).listen(11111);

const wss = new WebSocket.Server({
    
     server }); 
wss.on('connection', function connection(ws) {
    
    
  ws.on('message', function(message) {
    
    
    ws.send(message);
  });

  ws.send('get it');
});

[Beneficios del artículo] Materiales de aprendizaje para arquitectos de servidores C / C ++ Linux más el grupo 812855908 (datos que incluyen C / C ++, Linux, tecnología golang, Nginx, ZeroMQ, MySQL, Redis, fastdfs, MongoDB, ZK, medios de transmisión, CDN, P2P, K8S, Docker, TCP / IP, corrutina, DPDK, ffmpeg, etc.)
Inserte la descripción de la imagen aquí

Podemos probar directamente en la consola del navegador.

var ws = new WebSocket("ws://192.168.8.226:11111");
// 连接上后执行
ws.send(11)

En este momento, veamos el paquete wirehark.

Inserte la descripción de la imagen aquí

Primero observe los primeros tres registros, este es el paquete de datos del protocolo de enlace de tres vías de TCP. Todos entendemos esto, así que no lo mostraremos. Luego mire el cuarto registro. El expandido es el siguiente.
Inserte la descripción de la imagen aquí

Vimos que después de que se estableció la conexión tcp, el navegador envió una solicitud http con varios paquetes de datos de websocket. Entonces mira el siguiente.

Inserte la descripción de la imagen aquí

El servicio devolvió un acuerdo para actualizar el acuerdo o cambiar el acuerdo. Podemos ver en el código del servidor que enviamos una cadena get it al navegador al establecer una conexión. Continúe viendo el registro de arriba.

Inserte la descripción de la imagen aquí

Este es el paquete de datos basado en el protocolo websocket que el servidor envía al navegador. Para conocer el significado específico de cada campo, consulte el protocolo websocket. Continuar buscando un registro es un tcp ack para el paquete de datos enviado por el servidor. Finalmente, podemos echar un vistazo a los últimos tres registros con keep-alive. Este es el mantenimiento de la capa tcp mencionada en el artículo anterior. Debido a que no tenemos transmisión de datos, la capa tcp enviará paquetes de sondeo de forma intermitente. Podemos mirar la estructura del paquete de sondeo.

Inserte la descripción de la imagen aquí

Hay un byte de datos de la sonda. ¿Qué pasa si enviamos un paquete de datos al servidor en este momento?

Inserte la descripción de la imagen aquí

Los tres datos sobre un fondo blanco son los datos enviados por el navegador al servidor y los datos devueltos por el servidor. tcp ack. Descubrimos que cuando el servidor empuja al navegador, el navegador envía un ack, pero cuando el navegador envía al servidor, el servidor no parece devolver un ack. Veamos por qué. Primero miramos el paquete enviado por el navegador.

Inserte la descripción de la imagen aquí

Mire el paquete de datos que el servidor envía al navegador.

Inserte la descripción de la imagen aquí

Descubrimos que cuando el servidor (tcp) envió el mensaje, también se trajo el acuse de recibo. En lugar de enviar dos paquetes tcp. Este es el mecanismo de tcp. TCP no envía un acuse de recibo a cada paquete. Acumulará acuses de recibo (enviar acuse de recibo) para reducir los paquetes de red, pero también debe asegurarse de responder al acuse de recibo lo antes posible, de lo contrario, hará que el cliente active una retransmisión de tiempo de espera . ¿Cuándo envía la confirmación tcp? Por ejemplo, cuando es necesario enviar datos, o no se reciben paquetes de datos durante un cierto período de tiempo, o el número de confirmaciones acumuladas alcanza un umbral, etc. Ahora que hemos estudiado tcp, también podríamos estudiar más, echemos un vistazo a lo que sucede si el servidor se apaga en este momento.

Inserte la descripción de la imagen aquí

El servidor enviará un paquete de reinicio al navegador, indicándole que debe desconectarse. Vamos, ¿qué pasa si el propio navegador llama cerca para cerrar la conexión?

Inserte la descripción de la imagen aquí

Vemos que websocket primero enviará un paquete FIN al servidor, y luego el servidor devolverá un paquete FIN, y luego iniciará las cuatro manos reales. Y el primer paquete de aletas agitado cuatro veces fue enviado por el servidor.

Echemos un vistazo a la versión segura de websocket. Iniciamos un servidor https.

var https = require('https');
var fs = require('fs');
const WebSocket = require('ws');

var options = {
    
    
    key: fs.readFileSync('./server-key.pem'),
    ca: [fs.readFileSync('./ca-cert.pem')],
    cert: fs.readFileSync('./server-cert.pem')
};

const server = https.createServer(options,function(req,res){
    
    
    res.end(fs.readFileSync(`${
    
    __dirname}/websocket.html`));
}).listen(11111);

const wss = new WebSocket.Server({
    
     server });

wss.on('connection', function connection(ws) {
    
    
  ws.on('message', function(message) {
    
    
    ws.send(message);
  });
});

Luego ejecútelo en la consola del navegador.

var ws = new WebSocket("wss://192.168.8.226:11111");
ws.sned(11);

Entonces echa un vistazo a wirehark.

Inserte la descripción de la imagen aquí

Primero establezca una conexión tcp y luego establezca una conexión tls. La posterior comunicación de datos se puede realizar mediante encriptación. No repitas. Analizaremos el protocolo tls más adelante.

Después de una serie de análisis, deberíamos tener una mejor comprensión del protocolo websocket y, finalmente, hablar sobre un punto sobre websocket. Descubrimos que si no hay comunicación en la conexión websocket, el tiempo que se mantiene la conexión websocket depende de tcp. Porque descubrimos que la capa tcp siempre enviará paquetes de sondeo. Después de alcanzar el umbral, la conexión se desconectará. Entonces, si queremos mantener la conexión websocket, debemos enviar paquetes de latidos por nosotros mismos, como ping y pong.

¡Preste atención a la cuenta oficial y comparta más contenido de tecnología de Internet que le interese!Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_40989769/article/details/111316270
Recomendado
Clasificación