
即时通讯后端前端【免费下载链接】Rocket.ChatThe Secure CommsOS™ for mission-critical operations项目地址https://gitcode.com/GitHub_Trending/ro/Rocket.Chat点击查看免费下载本文基于 Rocket.Chat 仓库中 presence-service 变更日志 及其对应源码系统梳理rocket.chat/presence-service微服务的职责边界、启动链路与核心能力重点剖析两个里程碑级变更v0.5.0 引入的统一 Presence 引擎优先级 claim 系统与 v0.6.0 加入的 FIPS 合规模式。读完本文你将掌握该服务的运行原理、在线状态判定规则、状态过期与恢复机制以及 FIPS 模式下的部署与校验方法并能在 ee/apps/presence-service 与 ee/packages/presence 源码中找到对应的实现证据。一、presence-service 是什么微服务架构中的在线状态中枢Rocket.Chat 以单体加可选微服务的形态部署presence-service是其中负责用户在线状态presence的独立服务。它通过 core-services 暴露的IPresence接口对外提供能力接口定义见 IPresence.ts涵盖以下核心方法连接生命周期newConnection、updateConnection、removeConnection、removeLostConnections、setConnectionStatus状态声明setStatus、setActiveState、endActiveState、clearActiveState运维观测toggleBroadcast、getConnectionCount、getPeakConnections、resetPeakConnections。从实现上看presence-service本身只是一个轻量壳真正的状态计算逻辑位于工作区包rocket.chat/presencepackage.json版本 0.3.x中。服务入口 service.ts 的启动流程清晰展示了其依赖链const { db, client } await getConnection(); // 连接 MongoDB startTracing({ service: presence-service, db: client }); // 启动链路追踪 registerServiceModels(db, await getTrashCollection()); // 注册服务端模型 await cronJobs.start(db); // 启动定时任务 api.setBroker(startBroker()); // 建立消息代理TCP/NATS const { Presence } await import(rocket.chat/presence); // 延迟加载 Presence 服务 api.registerService(new Presence()); // 注册为微服务 await api.start();入口同时用polka暴露了/health健康检查端点通过api.nodeList()验证服务节点可达后返回ok异常则返回 500。服务默认监听端口为环境变量PORT或 3031见 service.ts。本地开发可通过 package.json 中的ms脚本直接运行TRANSPORTER${TRANSPORTER:-TCP} MONGO_URL${MONGO_URL:-mongodb://localhost:3001/meteor} ts-node --files src/service.ts默认使用 TCP 传输器、连接本地 MongoDB。TRANSPORTER环境变量支持切换为 NATS 等其他代理实现依赖中同时声明了moleculer与nats。二、统一 Presence 引擎基于优先级的 claim 系统CHANGELOG 中 v0.5.0PR #40274记录了一项关键架构变更Adds the backend foundation for a unified presence engine with a priority-based claim system (internal manual external), status expiration, and previous state restore.这为在线状态计算引入了声明claim模型其核心实现位于 presenceEngine.ts。2.1 三种声明源与优先级在线状态不再只是一个布尔值而是由多个来源争夺的显示结果。引擎定义了三种声明来源statusSource及固定优先级// Priority: internal manual external (lower number higher priority). // System states (like auto-away) are not listed here and have the lowest priority. const PRIORITY { internal: 1, manual: 2, external: 3 }; const NO_PRIORITY 4;internal优先级 1系统内部状态例如语音/视频通话中通话中On a call这类由系统发起的声明manual优先级 2用户手动设置的显式意图例如专注中休假中external优先级 3外部系统如日历应用写入的状态未声明来源如系统自动 Away优先级最低4。优先级数字越小越高当高优先级声明到达时当前显示的声明会被暂存stash到previousState字段从而在声明结束后能够恢复。2.2 状态判定规则processPresenceprocessPresence(user, sessions, claimUpdate)是引擎的纯函数入口返回需要写入数据库的$set/$unset字段。其判定逻辑由测试 presenceEngine.spec.ts 完整覆盖关键规则如下无声明时状态完全由 DDP 会话决定——至少一个会话为 ONLINE 则显示 ONLINE全部会话为 AWAY 则显示 AWAYstatusDefault为 BUSY 时即使连接 ONLINE 也显示 BUSYstatusDefault为 OFFLINE隐身时保持 OFFLINE。会话归约reduceConnections保证 ONLINE 优先、其次取第一个非 OFFLINE 状态。最终显示规则computeStatus连接状态为 OFFLINE 时始终显示 OFFLINE连接现实优先statusDefault为 ONLINE 时回落到连接状态否则以statusDefault为准。离线用户的声明限制离线用户只能被 manual 来源修改状态external/internal 声明会被拒绝resolveIntent返回 null。机器人/应用用户无连接时人回落到 OFFLINE而type为bot/app或拥有bot角色的服务用户保留其声明状态对应测试见 presenceEngine.spec.ts。2.3 previousState 暂存与恢复当高优先级或同优先级的新声明到达时旧声明被完整暂存含statusDefault、statusText、statusSource、statusExpiresAt、statusIdendActive时若previousState未过期则恢复否则重置为 ONLINE。manual 声明特殊处理manual 是用户显式意图永不暂存并会清除任何排队中的声明。内部声明还支持statusId身份标识与堆叠并发语音/视频声明可以按任意顺序结束older-first 丢暂存、newest-first 恢复单槽位中第三个并发 internal 声明会驱逐最旧的。这些行为均有对应测试佐证presenceEngine.spec.ts。2.4 状态过期statusExpiresAt声明可以携带statusExpiresAt过期时间。服务层 Presence.ts 中setActiveState校验过期时间必须是未来日期非法或过去时间直接抛错过期处理由presence-status-expiration定时任务驱动processExpiredStatuses消费Users.findExpiredStatuses()游标setupNextExpiration通过cronJobs.addAtTimestamp精确调度到下一次过期时刻见 Presence.ts写库时使用statusExpiresAt/previousState作为条件守卫guard防止多个 presence 实例并发处理同一过期事件时互相覆盖见 Presence.ts。2.5 连接管理与陈旧连接回收服务通过UsersSessions集合维护每个用户的会话连接列表并由 PresenceReaper.ts 周期清理每 1 分钟运行一次找出connections._updatedAt超过staleThresholdMs默认 5 分钟的陈旧连接按batchSize默认 500批量$pull删除删除时同时校验_updatedAt cutoffDate防止竞态删除后通过回调触发对应用户的 presence 重算见 Presence.ts 中handleReaperUpdates。此外服务还监听watch.instanceStatus事件与节点断连事件当某个实例节点消失时调用removeLostConnections(nodeID)清理该实例遗留的连接并刷新受影响用户状态Presence.ts。2.6 服务层方法语义Presence.spec.ts 印证了公开方法的语义约定setStatus(userId, status, text?, expiresAt?)手动设置状态当status ONLINE且无文本时等价于clearActiveState清除所有声明回落到连接驱动有文本时则建立 manual 声明ONLINE 加空字符串文本同样触发 clearsetActiveState应用声明并携带statusSource无连接时写入statusDefault但显示 OFFLINE状态在重连后生效endActiveState恢复 previousState无暂存则重置 ONLINEclearActiveState重置为 ONLINE 并清空statusSource、statusExpiresAt、previousState、statusId。2.7 状态文本规范化状态文本经 normalizeStatusText.ts 处理先trim()再去尾截断最大长度STATUS_TEXT_MAX_LENGTH 120字符。三、FIPS 合规模式v0.6.0CHANGELOG 中 v0.6.0PR #39324记录单体与全部微服务ddp-streamer、account-service、authorization-service、presence-service、queue-worker、omnichannel-transcript均可通过 Node.js/OpenSSL FIPS 强制 FIPS 合规密码学并提供专用 FIPS Docker 镜像FIPS 模式需要包含新fips模块的许可证FIPS 状态会写入服务器日志与统计数据。3.1 启动时的强制校验presence-service 的 FIPS 校验逻辑位于 fips.ts代码极简但语义明确import crypto from crypto; crypto.setFips(true); if (!crypto.getFips()) { throw new Error(FIPS mode was not enabled after crypto.setFips(true)); } console.log(FIPS COMPLIANCE CHECK: YES);即显式开启 FIPS 模式若开启失败如底层 OpenSSL 不支持 FIPS 模块则直接抛错拒绝启动并打印FIPS COMPLIANCE CHECK: YES确认校验通过。3.2 FIPS Docker 镜像构建链FIPS 镜像的构建定义在 ee/apps/Dockerfile 中标准镜像阶段release-standard基于node:24.15.0-alpine3.23FIPS 阶段release-fips基于rocketchat/dhi-node:24.15.0-alpine3.23-fips加固 Node 镜像并设置LIBCmusl以保证原生模块预编译二进制加载正确FIPS 镜像的启动命令显式叠加两层保障CMD [node, --force-fips, --require, ./src/fips.js, src/service.js]--force-fips由 Node 层面强制 FIPS 合规--require ./src/fips.js再执行进程内的二次校验二者形成双保险。3.3 FIPS 部署配置仓库根目录的 docker-compose-ci.fips.yml 定义了完整的 FIPS 部署拓扑rocketchat 单体、account-service、authorization-service、presence-service、ddp-streamer-service、queue-worker-service、omnichannel-transcript-service 全部构建release-fips目标并发布为*-fips后缀的镜像如presence-service:${DOCKER_TAG}-fips。需要说明的是FIPS 模式要求许可证包含fips模块CHANGELOG 原文明确这一点属于授权能力而非纯粹的开源特性实际启用前需确认许可证范围。四、版本发布节奏与依赖管理CHANGELOG 还展示了该服务的发布工程实践对理解微服务版本管理很有参考价值双轨发布每个版本几乎都同时存在稳定版如0.6.1与预发布版0.6.1-rc.0采用 Changesets 风格管理先发-rc系列再收敛为正式版依赖同步升级每次发布都会批量升级一批工作区依赖从记录可见其稳定依赖集包括rocket.chat/model-typings、rocket.chat/models、rocket.chat/core-services、rocket.chat/core-typings、rocket.chat/presence、rocket.chat/cron、rocket.chat/network-broker以及rocket.chat/tracing、rocket.chat/logger等v0.4.53 起——它们共同构成服务的运行底座工程化清理v0.6.1PR #41763将rocket.chat/string-helpers替换为rocket.chat/tools属于工具函数包收敛v0.4.53PR #38989升级 ESLint 配置更早版本还记录了 Meteor 与 Node 运行时升级PR #35181 升级至 Meteor 3.1.2 / Node 20.13.1PR #33596 升级至 Meteor 3.0.4 / Node 20.18.0以及 Apps-Engine 的 Deno 运行时PR #31821等平台级变更。五、运维与可观测性要点结合源码与变更记录presence-service 的运维关注点可归纳为健康检查GET /health依赖api.nodeList()节点发现异常时返回 500端口默认 3031可用PORT覆盖连接容量MAX_CONNECTIONS 200见 Presence.ts——无许可证时连接数超过 200 会通过设置Presence_broadcast_disabled自动关闭状态广播unlimited-presence或scalability许可证模块可解除该限制license.module事件监听见 Presence.ts观测指标getConnectionCount、getPeakConnections提供连接数与峰值统计FIPS 判定FIPS 镜像启动日志中的FIPS COMPLIANCE CHECK: YES是合规校验的直观依据同时 FIPS 状态也会上报至服务器日志与统计信息CHANGELOG v0.6.0 描述。六、小结从 CHANGELOG.md 的两条主线变更出发可以看到 presence-service 的演进脉络v0.5.0 让在线状态从简单的连接计数升级为带优先级的声明仲裁系统internal manual external支持过期与暂存恢复v0.6.0 则把服务纳入 FIPS 合规体系通过双保险启动校验与专用镜像满足对密码学合规有要求的部署场景。想要深入理解这套机制建议按以下路径阅读源码先读 presenceEngine.ts 掌握判定规则再用 presenceEngine.spec.ts 的测试用例逐条验证边界行为最后回到 Presence.ts 看服务层如何把引擎结果落库、广播与调度。赞分享即时通讯后端前端【免费下载链接】Rocket.ChatThe Secure CommsOS™ for mission-critical operations项目地址https://gitcode.com/GitHub_Trending/ro/Rocket.Chat点击查看免费下载相关推荐OpenClaw 网关 Presence 在线状态机制解析从实例列表到 system-presence 的完整实现OpenClaw 网关 Presence 在线状态机制解析从实例列表到 system presence 的完整实现 Presence在线状态是 OpenC人工智能AI Agent即时通讯后端本地部署语音为什么选择ImGui-SFML游戏与应用UI开发的高效解决方案为什么选择ImGui SFML游戏与应用UI开发的高效解决方案 ImGui SFML是一个强大的库它允许开发者在SFML框架中无缝集成Dear ImGuiUI库/组件游戏开发图形学基于 Supabase Realtime Presence 与 Auth 构建 Next.js 在线用户状态应用基于 Supabase Realtime Presence 与 Auth 构建 Next.js 在线用户状态应用 本文基于开源仓库 supabase 中 exa后端前端数据库上一篇文本补丁应用策略diff-match-patch容错机制深度解析下一篇form-create文件上传组件从基础上传到断点续传创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考