He estado tratando de implementar el protocolo WebSocket desde cero en nodejs, al hacerlo, tengo una pregunta que desde entonces no ha sido respondida. ¿Qué son exactamente los subprotocolos con respecto a los websockets? El segundo parámetro del constructor WebSocket es donde especifica "subprotocolos" -
let socket = new WebSocket("ws://localhost:3000",["http",...]);¿Alguien puede darme una respuesta clara para qué propósito tienen?
Websockets simplemente define un mecanismo para intercambiar mensajes arbitrarios. Lo que significan esos mensajes, qué tipo de mensajes puede esperar un cliente en un momento determinado o qué mensajes puede enviar depende completamente de la aplicación que los implemente. Entonces necesita un acuerdo entre el servidor y el cliente sobre estas cosas. Podría decir… necesita una especificación de protocolo . El parámetro de subprotocolo simplemente permite que los clientes intercambien formalmente esta información. Puede inventar cualquier nombre para cualquier protocolo que desee. El servidor puede simplemente comprobar que el cliente parece adherirse a ese protocolo durante el protocolo de enlace. También puede usarlo para solicitar diferentes tipos de protocolos del servidor, o usarlo para el control de versiones (por ejemplo, cuando presenta my-protocol-v2 , pero aún necesita admitir clientes que solo entiendan my-protocol-v1 ).
Explicado en MDN aquí
Piense en un subprotocolo como un esquema XML personalizado o una declaración de tipo de documento. Todavía está usando XML y su sintaxis, pero además está restringido por una estructura que acordó. Los subprotocolos de WebSocket son así. No introducen nada sofisticado, simplemente establecen una estructura. Al igual que un doctype o schema, ambas partes deben estar de acuerdo en el subprotocolo; a diferencia de un tipo de documento o esquema, el subprotocolo se implementa en el servidor y el cliente no puede hacer referencia a él de forma externa.
Los subprotocolos se explican en las secciones 1.9, 4.2, 11.3.4 y 11.5 de la especificación.
Un cliente tiene que pedir un subprotocolo específico. Para hacerlo, enviará algo como esto como parte del apretón de manos original:
http GET /chat HTTP/1.1 ... Sec-WebSocket-Protocol: soap, wampo equivalente:
... Sec-WebSocket-Protocol: soap Sec-WebSocket-Protocol: wampAhora el servidor debe elegir uno de los protocolos que el cliente sugirió y admite. Si hay más de uno, envíe el primero que envió el cliente. Imagina que nuestro servidor puede usar jabón y wamp. Luego, en el apretón de manos de respuesta, envía:
Sec-WebSocket-Protocol: soapEl servidor no puede enviar más de un encabezado Sec-Websocket-Protocol. Si el servidor no desea utilizar ningún subprotocolo, no debe enviar ningún encabezado Sec-WebSocket-Protocol. Enviar un encabezado en blanco es incorrecto. El cliente puede cerrar la conexión si no obtiene el subprotocolo que desea.
Si desea que su servidor obedezca ciertos subprotocolos, naturalmente necesitará un código adicional en el servidor. Imaginemos que estamos usando un subprotocolo json. En este subprotocolo, todos los datos se pasan como JSON. Si el cliente solicita este protocolo y el servidor quiere usarlo, el servidor necesita tener un analizador JSON. En términos prácticos, esto será parte de una biblioteca, pero el servidor necesita pasar los datos.
Algún código de muestra, cópielo de https://hpbn.co/websocket/#subprotocol-negotiation , para que quede claro.
El cliente puede anunciar qué protocolos admite al servidor como parte de su protocolo de enlace de conexión inicial:
var ws = new WebSocket('wss://example.com/socket', ['appProtocol', 'appProtocol-v2']); ws.onopen = function () { if (ws.protocol == 'appProtocol-v2') { ... } else { ... } }