宁语之溪 - WebSocket
type: channel
link: https://nyzx.de/tag/websocket/
items: WebSocket 推送如何服务竞赛态势

WebSocket 推送如何服务竞赛态势
type: item
date: 2023-11-25T16:38:00+08:00
description: 竞赛平台的前台页面有一类信息，不适合一直靠手动刷新获取：当前任务、答题记录、分数排名、指挥官指令，以及比赛进行过程中的一些变化。现在是 2023 年 11 月，我正在参与竞赛三期接口开发，也开始处理 WebSocket 推送相关的修改。当前最明确的一项工作，是将红蓝对抗任务分配的 WebSocket 推送调整为只针对被分配任务的战队用户推送。这项修改让我更清楚地看到，实时推送不只是“把消息发出去”。消息应该发给真正需要它的用户，推送内容也应该和当前任务、战队以及比赛状态对应起来。为什么需要实时推送如果页面上的状态变化只能依靠定时刷新，用户看到的内容可能会有延迟。对于普通的信息展示，这种延迟有时可以接受；但在竞赛过程中，任务分配、答题提交、分数排名和指挥操作之间存在先后关系，页面是否及时更新会直接影响使用过程。WebSocket 的一个常见用途，就是在客户端和服务端建立持续连接。连接建立后，服务端可以在有新事件时主动发送消息，而不必等客户端再次发起请求。我对 WebSocket 的理解主要来自项目修改和资料学习。它并不是自动解决实时通信问题的按钮，仍然需要考虑连接对象、消息内容、推送时机和异常情况。推送给谁比推送出去更重要红蓝对抗的任务分配场景中，不同战队承担的任务并不相同。如果一条任务消息被所有参赛用户收到，页面就可能出现不属于当前战队的信息，也会增加前端判断和过滤的工作。因此，现在的修改方向是：将任务分配的 WebSocket 推送改为针对被分配任务的战队用户推送。可以把这个过程抽象成：任务发生变化 -> 找到任务对应的战队 -> 找到战队中的目标用户 -> 只向目标连接推送消息这段流程是对工作内容的概念化表达，不是项目中的实际代码或完整实现。它帮助我理解了一个重要问题：实时消息的范围应该和业务对象的范围保持一致。在公开资料中，类似场景通常会把连接和用户标识放在服务端维护的映射关系里，再根据业务对象找到目标连接。伪代码可以写成下面这样：connections[userId] = websocket onTaskAssigned(task, teamId): for userId in members(teamId): send(connections[userId], task)这只是通用示例，实际项目还需要处理连接断开、重复登录、权限变化和消息发送失败等情况。项目内部的连接管理和消息格式属于不公开的实现细节，本文不展开。消息和接口需要一起设计在 11 月的工作中，WebSocket 修改并不是孤立进行的。同期还在调整比赛列表、比赛信息、任务详情、任务分配、答题记录、成绩总分排名和指挥官指令等接口。这些接口负责查询或提交数据，WebSocket 则负责把部分变化更及时地通知到页面。两者之间需要使用相对一致的业务理解，否则就可能出现接口返回的是一套状态，推送消息表达的是另一套状态。例如，任务分配页面需要知道当前战队被分配了哪些任务，答题页面需要获取当前任务和提交记录，比赛结束后的详情页又需要展示成绩和排名。接口和推送虽然承担的职责不同，但都围绕比赛、战队、任务和成绩这些业务对象展开。在这个过程中，我也在关注接口文档，因为它同样重要。周报中多次记录了接口文档同步更新，下一阶段还要继续对三期新增接口进行测试、修改和补充。没有清晰的接口约定，前端页面很难稳定地使用实时消息。实时通信也需要鉴权和边界11 月的周报还记录了比赛鉴权方法优化，以及红蓝对抗和三国战模式权限验证问题的修改。这些内容和 WebSocket 推送放在一起看，会让我更容易理解实时通信的边界。建立连接不等于拥有所有比赛数据的访问权限。用户是谁、属于哪支战队、当前是否参加某场比赛、能够看到哪些任务，都应该和业务权限保持一致。因此，实时推送至少需要关注几个问题：连接属于哪个用户；用户属于哪个战队或阵营；当前消息对应哪场比赛和哪项任务；用户是否仍然具有查看或接收该消息的权限；连接断开或状态变化后，是否还应该继续推送。这些是我结合项目修改和公开资料形成的通用理解，并不代表我已经完成了整套实时通信架构；公开文章也不展开内部实现和敏感细节。从一个推送修改开始理解实时系统现在的工作并不是从零设计一个实时竞赛系统，而是在已有平台和三期功能上持续修改接口、测试流程和补充缺失内容。WebSocket 推送只是其中一项具体工作。但这项工作让我看到，实时系统的难点不只在连接技术本身，还在于业务范围的划分。推送给谁、什么时候推送、推送什么内容，以及用户收到消息后如何和页面数据结合，都会影响最终的使用体验。对我来说，WebSocket 的价值不是让所有页面都“自动刷新”，而是让真正需要及时知道变化的用户，在合适的时机收到与自己相关的信息。任务分配只向目标战队用户推送，就是一个很具体的例子。现在我…