新闻详情

新闻详情

首页 / 资讯中心 / 详情

如何在不依赖 sticky sessions 的情况下用 @socket.io/cluster-engine 横向扩展 Socket.IO 多进程

发布时间:2026/9/9 21:43:07来源:尧图网络
如何在不依赖 sticky sessions 的情况下用 @socket.io/cluster-engine 横向扩展 Socket.IO 多进程
如何在不依赖 sticky sessions 的情况下用 socket.io/cluster-engine 横向扩展 Socket.IO 多进程【免费下载链接】socket.ioBidirectional and low-latency communication for every platform项目地址: https://gitcode.com/gh_mirrors/so/socket.io当你把 Socket.IO 服务拆成多个 Node.js 进程单机多 worker或多台机器各跑一个服务后默认的engine.io引擎要求负载均衡层做 sticky sessions同一个 Engine.IO 会话的每次 HTTP 请求都必须落到同一个进程否则连接会断开。socket.io/cluster-engine是官方提供的集群引擎它扩展了engine.io自带的引擎让各进程之间通过 IPC 通道或 Redis pub/sub检查会话是否在其他 worker 上存在并把数据包转发给拥有该会话的 worker从而横向扩展时不再需要 sticky sessions。本文基于仓库中的两个官方示例给出可直接执行的部署路径Node.js cluster 单机多 worker主路径以及 Redis 跨进程同步的可选分支。准备条件以 examples/cluster-engine-node-cluster/package.json 为准示例使用的依赖与版本为{ type: module, dependencies: { socket.io/cluster-adapter: ^0.2.2, socket.io/cluster-engine: ^0.1.0, socket.io: ^4.7.5, socket.io-client: ^4.7.5 } }注意示例包本身是type: module所以下面的服务端代码按 ESM 编写。安装引擎的方式来自 packages/socket.io-cluster-engine/README.mdnpm i socket.io/cluster-engine主路径只用到 Node.js 内置的cluster模块不需要 Redis、Docker 或负载均衡器是验证“无 sticky sessions 也能工作”的最短路径。主路径Node.js cluster 下多 worker 共享同一端口完整实现见 examples/cluster-engine-node-cluster/server.js。主进程primary负责 fork worker 并建立集群内部的连接每个 worker 各自创建 HTTP server 和 Socket.IOServer绑定到同一个端口3000。import cluster from node:cluster; import process from node:process; import { availableParallelism } from node:os; import { setupPrimary as setupPrimaryEngine, NodeClusterEngine, } from socket.io/cluster-engine; import { setupPrimary as setupPrimaryAdapter, createAdapter, } from socket.io/cluster-adapter; import { createServer } from node:http; import { Server } from socket.io; if (cluster.isPrimary) { console.log(Primary ${process.pid} is running); const numCPUs availableParallelism(); // fork workers for (let i 0; i numCPUs; i) { cluster.fork(); } setupPrimaryEngine(); setupPrimaryAdapter(); // needed for packets containing Buffer objects (you can ignore it if you only send plaintext objects) cluster.setupPrimary({ serialization: advanced, }); cluster.on(exit, (worker, code, signal) { console.log(worker ${worker.process.pid} died); }); } else { const httpServer createServer((req, res) { res.writeHead(404).end(); }); const engine new NodeClusterEngine(); engine.attach(httpServer, { path: /socket.io/, }); const io new Server({ adapter: createAdapter(), }); io.bind(engine); io.on(connection, (socket) { socket.on(hello, () { socket.broadcast.emit(hello, socket.id, process.pid); }); }); // workers will share the same port httpServer.listen(3000); console.log(Worker ${process.pid} started); }各步骤的作用与条件setupPrimaryEngine()即socket.io/cluster-engine导出的setupPrimary在主进程中建立 cluster 内部的同步通道这是移除 sticky sessions 要求的关键调用setupPrimaryAdapter()与createAdapter()来自socket.io/cluster-adapter让广播类操作跨 worker 生效。上面示例中socket.broadcast.emit会在其他 worker 上生效依赖的就是这对调用cluster.setupPrimary({ serialization: advanced })源码注释说明它用于携带Buffer的数据包只发纯文本对象时可以忽略worker 里new NodeClusterEngine()engine.attach(httpServer, { path: /socket.io/ })io.bind(engine)path是 Socket.IO 挂载路径客户端连接 URL 需与之匹配示例客户端用ws://localhost:3000/httpServer.listen(3000)在每个 worker 中执行cluster模式下多个 worker 可以共享同一端口。注意 README 中给出的最小示例不含 adapter只 fork worker 并在主进程调用setupPrimary()如果你要演示跨 worker 的广播需要像上面的完整示例一样同时接上socket.io/cluster-adapter。结果验证确认不同 worker 之间互相同步运行方式来自 examples/cluster-engine-node-cluster/README.md# run the server $ node server.js # run the client $ node client.js客户端来自 examples/cluster-engine-node-cluster/client.js创建 3 个连接到ws://localhost:3000/的 socket每 2 秒emit(hello)并打印收到的广播import { io } from socket.io-client; const CLIENTS_COUNT 3; for (let i 0; i CLIENTS_COUNT; i) { const socket io(ws://localhost:3000/, { // transports: [polling], // transports: [websocket], }); socket.on(connect, () { console.log(connected as ${socket.id}); }); socket.on(disconnect, (reason) { console.log(disconnected due to ${reason}); }); socket.on(hello, (socketId, workerId) { console.log(received hello from ${socketId} (worker: ${workerId})); }); setInterval(() { socket.emit(hello); }, 2000); }判断连接是否成功每个客户端打印connected as socket.id之后周期性打印received hello from socketId (worker: pid)其中 worker 标识是收到方所在进程的 PID上面服务端代码中process.pid。由于没有任何 sticky sessions3 个客户端会被分配到不同 worker如果它们都能稳定收到彼此的广播说明 IPC 转发和跨 worker 广播都在工作。客户端连接串末尾的transports注释行可以用来对照引擎文档中提到的升级机制当客户端从 HTTP long-polling 开始连接时引擎会延迟连接以允许客户端升级让最终的 WebSocket 连接落在拥有该会话的 worker 上。因此分别取消polling/websocket注释重跑客户端两种传输方式都应保持连接不断开——这是判断引擎是否正常工作的一条可核对路径。可选分支跨机器扩展时用 Redis 替代 IPC当进程分布在不同机器上、IPC 通道不可用时RedisEngine用 Redis pub/sub 做同样的同步。完整实现见 examples/cluster-engine-redis/server.js其 README 在 examples/cluster-engine-redis/README.md。这个示例的拓扑与主路径不同3 个 Socket.IO 服务分别监听3001、3002、3003另有一个代理监听3000随机把每个请求转发到其中一个服务——也就是刻意不做 sticky sessions 的代理用来验证多服务部署下引擎依然可用。启动步骤副作用说明docker compose up -d会在后台启动一个 Redis 7 容器并占用6379端口examples/cluster-engine-redis/compose.yaml 只定义了这一个服务# start the redis server $ docker compose up -d # run the server $ node server.js # run the client $ node client.js核心代码与主路径相同只是引擎换成RedisEngine每个服务各自持有 pub/sub 客户端const pubClient createClient(); const subClient pubClient.duplicate(); await Promise.all([pubClient.connect(), subClient.connect()]); const engine new RedisEngine(pubClient, subClient); engine.attach(httpServer, { path: /socket.io/, }); const io new Server({ adapter: createAdapter(pubClient, subClient), }); io.bind(engine);这里createAdapter(pubClient, subClient)来自socket.io/redis-adapter依赖版本^8.3.0跨服务的广播依赖它。验证方式与主路径一致客户端连的是代理端口3000观察connected as ...和携带服务端口3001/3002/3003的hello广播多个随机落到不同服务的客户端仍能互相收到消息。如果单机内既有 cluster 又要跨机器引擎 README 的 “Node.js cluster Redis” 小节给出组合写法主进程在连上 Redis 后调用setupPrimaryWithRedis(pubClient, subClient)在 fork worker 之后worker 侧仍然使用NodeClusterEngine。引擎选项与限制socket.io/cluster-engine提供三个引擎选项来自 packages/socket.io-cluster-engine/README.md 的 Options 表NameDescriptionDefault valueresponseTimeoutThe maximum waiting time for responses from other nodes, in ms.1000 msnoopUpgradeIntervalThe delay between two noop packets when the client upgrades, in ms.200 msdelayedConnectionTimeoutThe maximum waiting time for a successful upgrade, in ms.300 ms适用边界按 README 的 “How it works” 说明Node.js 路径的 worker 间通信依赖 IPC 通道即 Node.jsclusterfork 出的子进程独立进程如各自启动的多个 Node 进程或容器必须走 Redis 路径cluster.setupPrimary({ serialization: advanced })只对包含Buffer的包必要纯文本对象场景可省略本引擎只解决 Engine.IO 传输层的多进程同步应用层的跨进程广播、房间同步仍需搭配对应的 adapter示例中分别为socket.io/cluster-adapter和socket.io/redis-adapter否则broadcast只在单个进程内生效。完成验证后主路径可以直接作为单机多核扩展的部署形态需要跨机器时切换到 Redis 分支验证方式多客户端跨节点互发hello保持不变。【免费下载链接】socket.ioBidirectional and low-latency communication for every platform项目地址: https://gitcode.com/gh_mirrors/so/socket.io创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

如何在 NW.js 桌面应用中使用 Socket.IO 连接 Node.js 服务器 2026/9/9 22:22:22

如何在 NW.js 桌面应用中使用 Socket.IO 连接 Node.js 服务器

如何在 NW.js 桌面应用中使用 Socket.IO 连接 Node.js 服务器 【免费下载链接】socket.io Bidirectional and low-latency communication for every platform 项目地址: https://gitcode.com/gh_mirrors/so/socket.io 要在 NW.js 桌面应用中和 Node.js 服务器做双向通信…

阅读更多 →
Qt实战指南:环境配置、崩溃定位与事件循环全解析 2026/9/9 22:22:22

Qt实战指南:环境配置、崩溃定位与事件循环全解析

写“QT高阶日记007”这期的时候,我手头正躺着一个工业上位机项目,界面要跑在Linux工控机上,天天面对的不只是界面设计,还有崩溃定位、交叉编译、事件循环这种绕不开的问题。跟群里几个搞Qt的老哥聊了一圈,发现大家踩的…

阅读更多 →
SRC挖洞前的准备工作,零基础也能搭好环境 2026/9/9 22:22:22

SRC挖洞前的准备工作,零基础也能搭好环境

系列导读:本文是《SRC漏洞挖掘系列》第2期。第1期我们聊了什么是SRC、它的基本价值,以及为什么授权范围比工具更重要——还没看过的朋友可以先补上那一篇。为什么你“挖不到洞”?可能问题出在起跑线上后台经常收到类似留言:“跟着…

阅读更多 →
Altium Designer实战:从软件安装到封装库与模板体系搭建 2026/9/9 22:22:22

Altium Designer实战:从软件安装到封装库与模板体系搭建

简介:这份资源是Altium Designer实战教程的配套资料包,面向想从零绘制STM32最小系统板并完成工厂打板的电子爱好者及初学者。教程基于AD17展开,其他版本亦可参考学习,覆盖原理图设计、封装制作、PCB布局到打板下单全流程。压缩包共…

阅读更多 →
安卓手机U盘传输全攻略:OTG、权限与格式问题详解 2026/9/9 22:22:22

安卓手机U盘传输全攻略:OTG、权限与格式问题详解

前几天有朋友问我:手机里存了两千多张照片和几个视频,想一次性拷到U盘里给爸妈,到底怎么弄最省事。我回了句“用OTG线插U盘,文件管理器复制就行”,结果他第二天跟我说插上没反应,文件管理器里也找不到U盘。…

阅读更多 →
Ansible 自定义模块如何处理错误?直接 raise 异常与 fail_json 的正确用法 2026/9/9 22:19:21

Ansible 自定义模块如何处理错误?直接 raise 异常与 fail_json 的正确用法

Ansible 自定义模块如何处理错误?直接 raise 异常与 fail_json 的正确用法 【免费下载链接】ansible Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy and maintain. Automate everything from c…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞