如何终止WebSocket连接?

m87*_*m87 12 javascript node.js

是否可以在不关闭整个服务器的情况下终止来自服务器的websocket连接?如果是的话,我该如何实现呢?

注意:我使用NodeJS作为后端和'ws'websocket模块.

Dam*_*nic 20

所以,因为文档中某种遗漏的关于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.
Run Code Online (Sandbox Code Playgroud)
  • 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();
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

软停机

如果你可以让自己等一会儿(但不是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);
Run Code Online (Sandbox Code Playgroud)

重要:正确执行close()方法将为事件发出1000紧密代码close,同时terminate()将发出异常关闭信号1006(MDN WebSocket Close事件).

  • 为什么我在这里找到这个解释而不是在文档中? (7认同)
  • 这个答案比我觉得选择的答案要好! (2认同)
  • 这个答案非常有用且富有洞察力。为我解决了一个主要的 Websocket 连接问题。 (2认同)

Mei*_*hes 12

如果要在不关闭服务器的情况下启动所有客户端,可以执行以下操作:

for(const client of wss.clients)
{
  client.close();
}
Run Code Online (Sandbox Code Playgroud)

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
});
Run Code Online (Sandbox Code Playgroud)

和一个基本的客户

"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");
};
Run Code Online (Sandbox Code Playgroud)

你会得到:

d:/example/node client
opened
something
closed
Run Code Online (Sandbox Code Playgroud)


Lew*_*wis 5

根据ws文档,您需要调用websocket.close()来终止连接。

let server = new WebSocketServer(options);
server.on('connection', ws => {
  ws.close(); //terminate this connection
});
Run Code Online (Sandbox Code Playgroud)