是否可以在不关闭整个服务器的情况下终止来自服务器的websocket连接?如果是的话,我该如何实现呢?
注意:我使用NodeJS作为后端,并且' ws' websocket模块。
答案 0 :(得分:13)
因为有关ws.close()
和ws.terminate()
的文档中存在某些遗漏,我认为提供的答案中的解决方案在某些情况下不会优雅地关闭套接字,从而使它们保持挂起状态事件循环。
比较ws
包的下两个方法:
ws.close()
:初始化紧密握手,向对等方发送关闭帧并等待从对等方接收关闭帧,之后发送FIN数据包以尝试执行干净的套接字关闭。收到回答后,套接字被破坏。但是,有一个closeTimeout
只会在最坏的情况下销毁套接字,它可能会使套接字再保持30秒,从而阻止使用自定义超时正常退出:
// ws/lib/WebSocket.js:21
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
ws.terminate()
:强行销毁套接字而不关闭帧或fin数据包交换,并立即执行,不会超时。
考虑到以上所有因素,"硬着陆"情景如下:
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();
}
});
});
如果你可以让自己等一会儿(但不是30秒),你可以给你的客户一些时间作出回应:
// 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);
重要提示:正确执行close()
方法会为1000
事件发出close
近似代码,而terminate()
会发出异常关闭1006
{1}}(MDN WebSocket Close event)。
答案 1 :(得分:9)
如果你想在不关闭服务器的情况下踢掉所有客户端,你可以这样做:
for(const client of wss.clients)
{
client.close();
}
如果你想特别寻找一个,你也可以过滤wss.clients
。如果您想将客户端作为连接逻辑的一部分(即它发送错误数据等),您可以这样做:
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
});
并使用基本客户
"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");
};
你会得到:
d:/example/node client
opened
something
closed
答案 2 :(得分:2)
根据ws documentation,您需要致电websocket.close()
以终止连接。
let server = new WebSocketServer(options);
server.on('connection', ws => {
ws.close(); //terminate this connection
});
答案 3 :(得分:1)
Jus以这种方式使用ws.close()
var socketServer = new WebSocketServer();
socketServer.on('connection', function (ws) {
ws.close(); //Close connecton for connected client ws
});
&#13;
答案 4 :(得分:0)
如果您使用var client = net.createConnection()
创建套接字,则可以使用client.destroy()
销毁套接字。
ws
应该是:
var server = new WebSocketServer();
server.on('connection', function (socket) {
// Do something and then
socket.close(); //quit this connection
});