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

Fastify Websocket如何获取当前已连接的客户端?

解决Fastify WebSocket无法获取已连接客户端的问题

针对你遇到的fastify.websocketServer.clients始终显示0个连接的问题,核心原因是@fastify/websocket v7.x版本调整了内部API结构,旧的引用路径不再有效,以下是具体解决方案:

1. 修正WebSocket服务器实例的引用路径

在@fastify/websocket v7+版本中,fastify.websocketServer已不再指向实际的ws.Server实例,正确的访问路径是fastify.websocket.server。

修改你的sendGeneralNotification函数:

export const sendGeneralNotification = function (type, payload) {
  const websocketServer = fastify.websocket.server;
  websocketServer.clients.forEach((client) => {
    // 仅向已完成握手、连接状态为开放的客户端发送消息
    if (client.readyState === 1) {
      client.send(JSON.stringify({ type, payload }));
    }
  });
};

2. 自定义连接管理(更可靠的方案)

如果需要精准追踪用户与连接的对应关系,建议自行维护一个连接集合,避免依赖ws.Server内置的clients(它可能包含未完成握手的连接):

// 全局维护用户-连接映射:key为userId,value为该用户的所有socket连接集合
const userConnections = new Map();

fastify.get(
  "/websocket",
  { websocket: true },
  (connection, req) => {
    const userToken = req.query?.userToken || req.request?.query?.userToken;
    let userId = null;
    
    if (userToken) {
      userId = userIdToken(userToken);
      connection.socket.userId = userId;
      
      // 将连接加入映射
      if (!userConnections.has(userId)) {
        userConnections.set(userId, new Set());
      }
      userConnections.get(userId).add(connection.socket);
    }

    connection.socket.on("message", (message) => {
      console.log("Web Socket - message", parseMessage(message));
    });

    // 连接断开时从映射中移除
    connection.socket.on("close", () => {
      if (userId && userConnections.has(userId)) {
        const sockets = userConnections.get(userId);
        sockets.delete(connection.socket);
        // 若用户无活跃连接,清理映射项
        if (sockets.size === 0) {
          userConnections.delete(userId);
        }
      }
    });
  }
);

之后你可以通过userConnections.size获取在线用户数,或者针对特定用户发送消息:

// 给指定用户发送通知
export const sendUserNotification = function (userId, type, payload) {
  const sockets = userConnections.get(userId);
  if (sockets) {
    sockets.forEach(client => {
      if (client.readyState === 1) {
        client.send(JSON.stringify({ type, payload }));
      }
    });
  }
};

关键说明

  • @fastify/websocket v7版本重构了内部实现,废弃了fastify.websocketServer属性,改用fastify.websocket.server访问底层ws.Server实例。
  • 内置的clients集合可能包含未完成握手的连接,因此必须检查readyState === 1(表示连接已开放)再发送消息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:20:33