[{"data":1,"prerenderedAt":247},["ShallowReactive",2],{"work-\u002Fworks\u002Fsocket-server":3,"work-surround-\u002Fworks\u002Fsocket-server":238},{"id":4,"title":5,"body":6,"cover":221,"date":222,"demo":223,"description":224,"draft":225,"extension":226,"featured":227,"meta":228,"navigation":227,"path":229,"repo":223,"seo":230,"stack":231,"stem":236,"updated":223,"__hash__":237},"works\u002Fworks\u002Fsocket-server.md","Socket Server - Rust 实时通信服务端",{"type":7,"value":8,"toc":209},"minimark",[9,13,21,26,37,40,69,72,75,78,85,88,102,109,112,115,122,125,131,134,141,152,158,161,181,184,187,190,193,200,203,206],[10,11,12],"p",{},"这不是一个只演示“连接成功、收发消息”的聊天室 Demo，而是一套面向真实业务的实时通信底座：既处理长连接和房间广播，也把身份、历史消息、断线恢复、水平扩展与运维观测放进同一套设计里。",[10,14,15,16,20],{},"项目当前版本为 ",[17,18,19],"code",{},"0.1.0","，服务兼容 Socket.IO v4，可用于在线协作、互动直播、客服会话、消息通知等需要低延迟双向通信的场景。",[22,23,25],"h2",{"id":24},"一套服务两条通道","一套服务，两条通道",[10,27,28,29,32,33,36],{},"服务启动后会同时开放两个入口：HTTP API 默认监听 ",[17,30,31],{},"5000"," 端口，负责账号、房间、历史消息、回放控制与指标；Socket.IO 默认监听 ",[17,34,35],{},"5001"," 端口，负责在线连接、实时事件与心跳。",[10,38,39],{},"两条通道共享同一组业务服务和安全规则：",[41,42,43,51,57,63],"ul",{},[44,45,46,50],"li",{},[47,48,49],"strong",{},"PostgreSQL"," 保存用户、房间、成员关系、消息、刷新令牌和 Socket Key。",[44,52,53,56],{},[47,54,55],{},"Redis"," 管理会话与在线状态，并承担限流计数、回放协调和跨节点 Pub\u002FSub。",[44,58,59,62],{},[47,60,61],{},"Tokio"," 驱动连接、后台清理和消息回放等异步任务。",[44,64,65,68],{},[47,66,67],{},"Axum + socketioxide"," 分别承载 HTTP 管理面与 Socket.IO 实时面。",[10,70,71],{},"这种拆分让常规查询继续使用清晰的 REST 接口，让实时消息走长连接，同时避免维护两套身份与权限逻辑。",[22,73,74],{"id":74},"从在线消息到断线恢复",[10,76,77],{},"项目实现了公开房间、私有房间和一对一会话。客户端加入房间后，消息会先经过身份、成员关系、类型、大小和频率检查，再写入 PostgreSQL，并通过 Socket.IO 广播给在线成员。",[10,79,80,81,84],{},"一对一消息使用稳定的会话标识聚合同一对用户的消息，多设备会话可以同时收到投递。客户端掉线后，可通过 ",[17,82,83],{},"after_id"," 游标补拉房间消息或私聊消息，避免把“在线推送成功”误当成可靠交付。",[10,86,87],{},"项目还提供了两种容易混淆但用途不同的回放能力：",[41,89,90,96],{},[44,91,92,95],{},[47,93,94],{},"断线补偿","按消息 ID 分页返回缺失内容，解决客户端重新上线后的数据缺口。",[44,97,98,101],{},[47,99,100],{},"时间轴回放","按原消息间隔重新广播，可设置倍速，并支持暂停、继续和停止，适合复盘互动过程；回放消息带有明确标记，且不会再次写入数据库。",[10,103,104],{},[105,106],"img",{"alt":107,"src":108},"实时消息投递与断线恢复","\u002Fimages\u002Fworks\u002Fsocket-server\u002Frealtime-message-flow.svg",[22,110,111],{"id":111},"跨节点实时链路",[10,113,114],{},"单机广播依赖当前进程内的 Socket.IO 房间，多实例部署则通过自研的 Redis 实时事件总线扇出房间消息、私聊、全局通知和凭证撤销事件。每个环境使用独立频道命名空间，减少测试、预发布与生产之间串流的风险。",[10,116,117,118,121],{},"Redis Pub\u002FSub 本身是至多一次投递。订阅发生中断并恢复时，服务端会向客户端发送 ",[17,119,120],{},"server_resync_required","，提示它通过游标主动拉取缺失消息。这一设计没有掩盖基础设施的交付语义，而是把实时性与可恢复性拆开处理。",[10,123,124],{},"时间轴回放的所有权和控制状态也写入 Redis，同一房间不会被多个节点同时启动回放。暂停、继续和停止操作更新共享控制状态，执行任务轮询响应，让不同节点看到一致的回放状态。",[10,126,127],{},[105,128],{"alt":129,"src":130},"分布式时间轴回放","\u002Fimages\u002Fworks\u002Fsocket-server\u002Fdistributed-replay.svg",[22,132,133],{"id":133},"安全不是最后再加的中间件",[10,135,136,137,140],{},"HTTP 与 Socket 连接都支持 JWT；面向受控系统集成时，还可使用数据库管理的 ",[17,138,139],{},"socket_key","。Key 只保存 SHA-256 摘要，禁用或删除后会向所有节点广播撤销事件，断开仍在使用该凭证的会话。",[10,142,143,144,147,148,151],{},"项目在服务端重新确定用户身份，不信任请求体里的 ",[17,145,146],{},"user_id","。房间更新、删除和时间轴回放由房主或管理员控制；普通用户只能修改自己的有限资料，也只能删除自己发送的消息。密码或账户状态变化会递增 ",[17,149,150],{},"auth_version","，使旧 JWT 与旧 Socket 会话立即失效。",[10,153,154],{},[105,155],{"alt":156,"src":157},"鉴权与会话撤销","\u002Fimages\u002Fworks\u002Fsocket-server\u002Fauth-session-lifecycle.svg",[10,159,160],{},"其他安全默认值包括：",[41,162,163,166,169,172,175,178],{},[44,164,165],{},"bcrypt 密码哈希，并校验成本参数范围。",[44,167,168],{},"JWT 密钥与内部 API 密钥必须独立且不少于 32 个字符。",[44,170,171],{},"生产环境拒绝通配 CORS 和默认 Redis 频道前缀。",[44,173,174],{},"HTTP 与可写 Socket 事件共享用户级限流；Redis 不可用时降级为本地内存限流。",[44,176,177],{},"Prometheus 指标接口需要内部密钥，避免直接暴露运行信息。",[44,179,180],{},"历史默认管理员已由数据库迁移禁用，首位管理员必须显式创建。",[22,182,183],{"id":183},"可观测与运行维护",[10,185,186],{},"服务使用结构化 tracing 记录请求与异常，Prometheus 指标覆盖活跃连接、收发消息、消息大小、请求耗时和错误数量。进程支持 Ctrl+C 与 Unix 终止信号下的优雅停机，并定时清理过期消息和刷新令牌。",[10,188,189],{},"仓库同时提供 PostgreSQL 迁移、Linux 配置、Nginx 示例、服务控制脚本与便携构建脚本。",[22,191,192],{"id":192},"自动化验证",[10,194,195,196,199],{},"在本次整理时，",[17,197,198],{},"cargo test --locked"," 的默认测试集通过了 29 项单元测试和 6 项集成测试。测试覆盖配置安全、JWT、密码哈希、权限边界、事件序列化、回放标记、会话解析、房间流程与 Socket 事件等行为。",[22,201,202],{"id":202},"这个项目解决了什么",[10,204,205],{},"Socket Server 最有价值的部分，不是事件数量，而是把实时系统的关键问题放进主链路：身份如何撤销、消息缺口如何恢复、多节点如何广播、权限如何收口、服务如何被观察。",[10,207,208],{},"它将实时投递、持久历史、游标补偿、跨节点广播、凭证撤销和运行指标组合成一套完整服务。相比一份只展示 Happy Path 的实时通信示例，这套实现更接近业务系统真正需要的通信基础设施。",{"title":210,"searchDepth":211,"depth":211,"links":212},"",3,[213,215,216,217,218,219,220],{"id":24,"depth":214,"text":25},2,{"id":74,"depth":214,"text":74},{"id":111,"depth":214,"text":111},{"id":133,"depth":214,"text":133},{"id":183,"depth":214,"text":183},{"id":192,"depth":214,"text":192},{"id":202,"depth":214,"text":202},"\u002Fimages\u002Fworks\u002Fsocket-server\u002Fproject-cover.svg","2025-09-22",null,"基于 Rust、Axum 与 Socket.IO 构建的实时通信后端，覆盖统一鉴权、房间与私聊、消息回放、跨节点投递和运行指标。",false,"md",true,{},"\u002Fworks\u002Fsocket-server",{"title":5,"description":224},[232,61,233,234,49,55,235],"Rust","Axum","Socket.IO","Prometheus","works\u002Fsocket-server","dKgFa2zuiV-vTMJMxzo4-FVQQ9nwA7tOa0Hb0w8tFJU",[239,243],{"title":240,"path":241,"stem":242,"children":-1},"logstream — 终端日志追踪工具","\u002Fworks\u002Flogstream-cli","works\u002Flogstream-cli",{"title":244,"path":245,"stem":246,"children":-1},"月相小组件","\u002Fworks\u002Fmoon-phase-widget","works\u002Fmoon-phase-widget",1787046421831]