Hapi.js WebSocket 实战:@hapi/nes 完全指南

Hapi 通过官方 nes 插件提供 WebSocket 能力:连接管理、广播、订阅发布一体。本文讲解 nes 配置、连接追踪、认证集成与多客户端广播。

最佳实践
应用接口与数据存储连接插画

Hapi 的 WebSocket 官方方案是 @hapi/nes 插件:注册后获得连接管理、路径订阅(subscription)与广播 API,与 Hapi 的认证体系原生集成。相比裸 ws 库,nes 的发布/订阅模型让实时功能的代码量少一半。

为什么是 nes 而不是裸 ws

Hapi 的插件哲学延伸到实时层:nes 把"连接、订阅、广播"抽象为 Hapi 式声明 API——客户端订阅路径、服务端按路径发布,认证直接复用 Hapi 的 auth 策略。相比自己用 ws 库管理 clients 集合,业务代码清爽得多。

安装与基础配置

npm install @hapi/hapi @hapi/nes
const Hapi = require('@hapi/hapi');
const Nes = require('@hapi/nes');

const server = Hapi.server({ port: 3000 });

await server.register(Nes);

// 声明订阅路径
server.subscription('/feed/{topic}');

// 发布消息(任何路由/handler 中调用)
server.publish('/feed/news', { title: '快讯', time: Date.now() });

客户端用 nes 的 JS 客户端库连接并 client.subscribe('/feed/news', handler)——发布订阅语义开箱即用。

连接追踪与错误处理

server.events.on('connection', (socket) => {
  server.log(['ws'], `新连接 ${socket.id}`);
});

server.events.on('disconnection', (socket) => {
  server.log(['ws'], `连接断开 ${socket.id}`);
});

nes 自动管理连接生命周期与重连协商(客户端内置重连逻辑)。连接级状态(用户身份、订阅记录)挂在 socket 对象上,随断开自动清理。

广播与定向投递

// 全量广播
server.broadcast({ type: 'announcement', text: '系统维护通知' });

// 按订阅路径投递(最常用)
server.publish('/feed/sports', payload);

// 按过滤器精细控制:订阅时带参数
server.subscription('/users/{id}', {
  filter: (path, message, options) => message.visibleTo.includes(options.credentials.user.id),
});

filter 函数让"谁该收到这条消息"成为声明式规则——通知系统的核心逻辑不过如此。

认证集成

nes 连接走 Hapi 握手管线:配置 auth 选项后,WebSocket 连接建立时即完成认证,socket.auth.credentials 可用。按路径控制订阅权限(auth: { mode: 'required' } 加 onSubscribe 钩子)——未登录用户连公开频道、登录用户订阅私有频道,权限模型与 HTTP API 完全一致。

观察长连接的生命周期

Hapi.js WebSocket 实战上线后,HTTP 握手成功率不能代表消息传输质量。应用需要额外记录在线连接数、消息处理耗时、断连原因和重连次数,再经 DataKit 指标或日志采集接入观测云。APM 用来观察已插桩的握手与消息处理依赖;每条 WebSocket 消息通常需要自行埋点,避免将长连接生命周期直接当作普通请求耗时。

接入文档:Prometheus 指标采集 · 日志采集 · Node.js APM 接入。

常见问题(FAQ)

Q:nes 和 Socket.IO 怎么选?

都在 Hapi 生态时选 nes(框架原生、认证打通);需要跨框架客户端生态(各种语言客户端库)选 Socket.IO。nes 的客户端主要覆盖 JS。

Q:nes 支持多实例部署吗?

支持:nes 有 Redis 广播适配器(nes 的 broadcast 选项配置 Redis),多实例间消息互通。连接本身仍需负载均衡的 sticky session。

Q:前端不用 nes 客户端能连吗?

nes 协议基于 WebSocket 但有自有帧格式,官方客户端最省心;浏览器场景也可以用原生 WebSocket 连接但需自行处理协议细节——评估后多数团队直接用官方客户端。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台