Saltar al contenido

¿Cómo terminar una conexión WebSocket?

Solución:

Entonces, debido a algún tipo de omisión en la documentación con respecto a ws.close() y ws.terminate() Creo que las soluciones en las respuestas proporcionadas no cerrarán los sockets con gracia en algunos casos, por lo que los mantendrán colgados en el bucle de eventos.

Compare los siguientes dos métodos de ws paquete:

  • ws.close():

Inicializa el apretón de manos cercano, enviando el marco cercano al par y esperando recibir el marco cercano del par, luego envía el paquete FIN en un intento de realizar un cierre de socket limpio. Cuando se recibe la respuesta, el enchufe se destruye. Sin embargo, hay una closeTimeout que destruirá el socket solo en el peor de los casos, y potencialmente podría mantener el socket durante 30 segundos adicionales, evitando la salida elegante con su tiempo de espera personalizado:

// ws/lib/WebSocket.js:21
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
  • ws.terminate():

Destruye a la fuerza el socket sin cerrar marcos ni intercambiar paquetes fin, y lo hace instantáneamente, sin ningún tiempo de espera.

Apagado duro

Teniendo en cuenta todo lo anterior, el escenario de “aterrizaje forzoso” sería el siguiente:

wss.clients.forEach((socket) => {
  // Soft close
  socket.close();

  process.nextTick(() => {
    if ([socket.OPEN, socket.CLOSING].includes(socket.readyState)) {
      // Socket still hangs, hard close
      socket.terminate();
    }
  });
});

Apagado suave

Puede darles a sus clientes algo de tiempo para responder, si puede permitirse esperar un rato (pero no 30 segundos):

// First sweep, soft close
wss.clients.forEach((socket) => {
  socket.close();
});

setTimeout(() => {
  // Second sweep, hard close
  // for everyone who's left
  wss.clients.forEach((socket) => {
    if ([socket.OPEN, socket.CLOSING].includes(socket.readyState)) {
      socket.terminate();
    }
  });
}, 10000);

Importante: correcta ejecución de close() el método emitirá 1000 cerrar código para close evento, mientras terminate() señalará un cierre anormal con 1006 (Evento MDN WebSocket Close).

Si desea expulsar a TODOS los clientes sin cerrar el servidor, puede hacer esto:

for(const client of wss.clients)
{
  client.close();
}

también puedes filtrar wss.clients también si quieres buscar uno en particular. Si desea expulsar a un cliente como parte de la lógica de conexión (es decir, envía datos incorrectos, etc.), puede hacer esto:

let WebSocketServer = require("ws").Server;
let wss = new WebSocketServer ({ port: 8080 });

wss.on('connection', function connection(ws) {
    ws.send('something');
    ws.close(); // <- this closes the connection from the server
});

y con un cliente básico

"use strict";
const WebSocket = require("ws");
let ws = new WebSocket("ws://localhost:8080");
ws.onopen = () => {
    console.log("opened");
};
ws.onmessage = (m) => {
    console.log(m.data);
};
ws.onclose = () => {
    console.log("closed");
};

obtendrás:

d:/example/node client
opened
something
closed

De acuerdo con la documentación de ws, debe llamar websocket.close() para terminar una conexión.

let server = new WebSocketServer(options);
server.on('connection', ws => {
  ws.close(); //terminate this connection
});
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *