竞赛平台的前台页面有一类信息,不适合一直靠手动刷新获取:当前任务、答题记录、分数排名、指挥官指令,以及比赛进行过程中的一些变化。
现在是 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 的价值不是让所有页面都“自动刷新”,而是让真正需要及时知道变化的用户,在合适的时机收到与自己相关的信息。任务分配只向目标战队用户推送,就是一个很具体的例子。
现在我还在继续测试三期新增接口、同步接口文档,并补充不同模式的流程测试。实时推送也不是独立完成后就结束了,它还需要放进比赛列表、任务分配、答题、排名和态势等完整流程中验证。