Est-il possible de mettre fin à une connexion websocket à partir d'un serveur sans fermer le serveur en entier? Si c'est le cas, comment puis-je y parvenir?
Remarque: J'utilise NodeJS en tant que module back-end et 'ws' websocket.
Si vous voulez lancer tous les clients sans fermer le serveur, vous pouvez le faire:
for(const client of wss.clients)
{
client.close();
}
vous pouvez également filtrer wss.clients
également si vous souhaitez en rechercher un en particulier. Si vous souhaitez lancer un client dans le cadre de la logique de connexion (c'est-à-dire qu'il envoie des données incorrectes, etc.), vous pouvez procéder comme suit:
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
});
et avec un client de base
"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");
};
tu auras:
d:/example/node client
opened
something
closed
Donc, à cause d'une sorte d'omission dans la documentation concernant ws.close()
et ws.terminate()
, je pense que les solutions fournies dans les réponses fournies ne ferment pas les sockets correctement, dans certains cas, les gardant ainsi suspendues dans la boucle d'événement.
Comparez les deux méthodes suivantes du package ws
:
ws.close()
: Initialise la prise de contact étroite, envoie une image rapprochée à l'homologue et attend de recevoir une image rapprochée de l'homologue, après avoir envoyé le paquet FIN dans le but d'effectuer une fermeture de socket propre. Lorsque la réponse est reçue, le socket est détruit. Cependant, il existe une variable closeTimeout
qui ne détruit le socket que dans le pire des cas, et qui pourrait éventuellement conserver le socket pendant 30 secondes supplémentaires, empêchant ainsi la fermeture en douceur avec votre délai d'attente personnalisé:
// ws/lib/WebSocket.js:21
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
ws.terminate()
:Détruit de force le socket sans fermer les trames ni les échanges de paquets fin, et le fait instantanément, sans aucun délai.
Compte tenu de tout ce qui précède, le scénario "d'atterrissage brutal" serait le suivant:
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();
}
});
});
Vous pouvez laisser à vos clients le temps de répondre, si vous pouviez vous permettre d’attendre un moment (mais pas 30 secondes):
// 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);
Important: l'exécution correcte de la méthode close()
émettra le code 1000
close pour l'événement close
, tandis que terminate()
signalera une fermeture anormale avec 1006
( MDN WebSocket Close event ).
Selon la documentation de ws , vous devez appeler websocket.close()
pour mettre fin à une connexion.
let server = new WebSocketServer(options);
server.on('connection', ws => {
ws.close(); //terminate this connection
});
Jus utiliser ws.close () de cette façon
var socketServer = new WebSocketServer();
socketServer.on('connection', function (ws) {
ws.close(); //Close connecton for connected client ws
});
Si vous utilisez var client = net.createConnection()
pour créer le socket, vous pouvez utiliser client.destroy()
pour le détruire.
Avec ws
il devrait être:
var server = new WebSocketServer();
server.on('connection', function (socket) {
// Do something and then
socket.close(); //quit this connection
});