如何实现NATS客户端连接或断开时的事件发布?
实现NATS客户端连接/断开状态通知的方案
一、直接在客户端监听NATS内置事件
NATS WebSocket客户端本身提供了连接状态相关的事件,你可以直接在浏览器端监听这些事件,主动向指定主题发布状态消息:
- 连接成功:监听
connect事件,触发后向client.status.connected主题发布消息,带上客户端唯一标识(比如生成UUID) - 断开连接:监听
disconnect、close或error事件,向client.status.disconnected主题发布消息 - 重连成功:可选监听
reconnect事件,发布重连通知
示例代码:
import { connect } from 'nats.ws'; async function initNATS() { const nc = await connect({ servers: 'ws://your-nats-server:8080', }); const clientId = crypto.randomUUID(); // 生成客户端唯一标识 // 连接成功时发布上线通知 nc.on('connect', () => { nc.publish('client.status.connected', JSON.stringify({ clientId, timestamp: Date.now() })); }); // 断开连接时发布下线通知 nc.on('disconnect', () => { nc.publish('client.status.disconnected', JSON.stringify({ clientId, timestamp: Date.now() })); }); // 连接彻底关闭时的处理(避免publish失败) nc.on('close', () => { try { nc.publish('client.status.disconnected', JSON.stringify({ clientId, timestamp: Date.now() })); } catch (err) { console.log('连接已关闭,无法发布下线通知'); } }); // 订阅状态主题,接收其他客户端的状态变化 const statusSub = nc.subscribe('client.status.*'); (async () => { for await (const msg of statusSub) { const statusData = JSON.parse(msg.data); const statusType = msg.subject.split('.')[2]; console.log(`客户端 ${statusData.clientId} ${statusType}`, statusData); } })(); } initNATS();
二、通过NATS服务器插件实现(需服务器权限)
如果需要服务器主动推送全量客户端的连接状态,可借助NATS的服务器扩展能力:
- 用Go语言编写NATS服务器插件,监听服务器内部的
client_connected和client_disconnected事件 - 将这些事件转发到公开主题(比如
system.client.status),所有客户端订阅该主题即可接收全局状态变化 - 注意:这种方式需要你有权限部署和配置自定义NATS服务器
三、客户端心跳+状态追踪(轻量级替代)
如果无法修改NATS服务器配置,可自行实现心跳机制:
- 每个客户端定期(如每5秒)向
client.heartbeat主题发布心跳消息,附带clientId和时间戳 - 客户端订阅心跳主题,维护一个在线客户端列表,超过10秒未收到某客户端心跳则标记为离线
- 这种方式无需服务器改动,但需要客户端自行处理状态过期与清理
内容的提问来源于stack exchange,提问作者zoran
相关产品推荐
相关产品推荐

