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
相关产品推荐
相关产品推荐

