You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js使用ws库开发WebSocket服务端 关闭事件缺少自定义原因

问题原因分析

    1. ws库的close事件回调第二个参数reason默认是Buffer类型,直接打印如果没有转字符串会显示为Buffer对象而非可读文本,若浏览器确实未传递则为空Buffer。
    1. WebSocket协议规定关闭原因的字符串长度不能超过123字节,超出的话会被直接丢弃。
    1. 你当前的关闭逻辑绑定在onunload/页面关闭事件中,出于性能和安全限制,绝大多数浏览器会主动丢弃页面卸载阶段WebSocket.close调用传入的自定义code和reason,直接使用默认关闭码关闭连接,不会传递自定义内容。

解决方案

1. 常规关闭场景(非页面卸载时主动触发关闭)

先将服务端收到的reason转为UTF-8字符串即可正常读取,修改服务端onSocketClose回调:

function onSocketClose(code, reason) {
  // 将Buffer转为UTF-8字符串
  const reasonStr = reason.toString('utf8');
  console.log("Closing open web socket", code, reasonStr);
  console.log("Closed web socket.");
}

2. 页面卸载场景的兼容处理

浏览器限制无法通过close方法传递自定义reason,改为在关闭连接前先主动发送一条携带关闭原因的消息,服务端暂存该原因后再处理关闭逻辑:
修改客户端closeSocket方法:

function closeSocket(reason) {
  if (reason) {
    console.info("Closing socket due to:", reason);
  } else {
    reason = "Unknown reason";
  }
  // 连接处于打开状态时先发送关闭原因
  if (webSocket.readyState === WebSocket.OPEN) {
    webSocket.send(JSON.stringify({
      type: 'socketClose',
      reason: reason
    }));
  }

  webSocket.onclose = function (ev) {
    console.info("Websocket closed.");
  };

  webSocket.close(1001, reason);
}

修改服务端逻辑,暂存对应连接的关闭原因:

wss.on("connection", function (ws) {
  // 存储当前连接的自定义关闭原因
  let customCloseReason = '';
  
  ws.on("message", function (data) {
    try {
      const msg = JSON.parse(data.toString());
      if (msg.type === 'socketClose') {
        customCloseReason = msg.reason;
      }
    } catch (e) {}
    console.log("received: %s", data);
  });

  function onSocketClose(code, reason) {
    // 优先取自定义的关闭原因,没有再用协议传递的
    const finalReason = customCloseReason || reason.toString('utf8');
    console.log("Closing open web socket", code, finalReason);
    console.log("Closed web socket.");
  }

  ws.on("close", onSocketClose);
});

内容的提问来源于stack exchange,提问作者Daniele Tentoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:15:03