如何实现类PUBG在线用户匹配及问答对战功能
问答对战网站类PUBG匹配系统技术实现方案
1. 在线用户状态实时识别模块
- 在线状态实时通信基于WebSocket长连接实现,弃用高延迟的轮询方案。用户完成账号校验进入站点后,前端自动与服务端建立长连接,连接建立瞬间将用户ID、当前登录IP/地域、段位等基础信息写入Redis在线用户有序集合,集合Score值存用户最后一次心跳时间戳;连接主动断开(退出登录、关闭页面)时直接将用户移出在线集合,同时清理该用户在匹配队列、对局中的相关占位数据。
- 心跳间隔设为30秒,前端按固定间隔上报心跳包,服务端每次收到心跳就更新对应有序集合里的Score值;后台每20秒扫一次在线集合,连续2个心跳周期(60秒)没更新心跳的用户直接判定为离线,触发清理逻辑,避免离线用户占用匹配名额。
- 在线用户细分4种状态,存在Redis Hash结构中,状态变更实时更新:
idle(大厅空闲可匹配)、matching(匹配队列中)、gaming(对局进行中)、offline(离线),匹配逻辑仅筛选状态为matching的用户进入计算。
2. 匹配规则引擎实现
- 匹配队列采用Redis有序集合存储,用户点击「开始匹配」按钮后先做前置校验:当前状态必须为
idle、无未完成对局、账号无匹配封禁记录,校验通过后将用户ID、段位分、题目难度偏好、入队时间戳写入匹配集合,同时将用户状态更新为matching。 - 匹配调度任务固定1秒执行一次,核心逻辑用Lua脚本实现保证原子性,防止同个用户被重复匹配:
- 优先遍历队列中等待时长超过15秒的用户,逐步放宽匹配阈值:初始段位差限制为±100分,等待每多10秒段位差阈值放宽100分,最长等待阈值设为60秒,避免用户长时间匹配不到人流失。
- 按对局要求的人数凑组,匹配维度优先级为:段位差匹配度>题目难度偏好契合度>同运营商/地域(降低网络延迟)>等待时长,凑齐满足规则的满员组后,直接将组内所有用户从匹配队列中移除,进入对局拉起流程。
- 匹配兜底:用户等待时长达到60秒仍未凑齐真人玩家时,直接给用户前端推送提示,可选择加入AI bot填充的对局,或者退出匹配队列。
3. 匹配成功后的对局自动拉起逻辑
- 匹配组凑齐后,服务端直接生成全局唯一对局ID,初始化对局信息(参与用户列表、抽取的对应难度题目池、开局时间戳、对局状态
preparing)存入Redis,同时通过WebSocket给组内所有用户推送匹配成功消息,附带5秒进入对局的倒计时。 - 前端收到匹配成功消息后自动跳转至对局准备页,倒计时期间如果有用户主动退出、断开连接,服务端立刻解散当前准备组,将剩余仍在线的用户标记为高优先级重新塞回匹配队列头部,给所有用户推送对局解散提示。
- 倒计时结束后校验所有组内用户的在线状态、是否在对局准备页:
- 全员到齐则将对局状态更新为
playing,按规则逐次推送题目,正式开始对战; - 有用户未到齐则直接判定未到齐用户弃权,剩余满足最低开局人数的用户正常开局,人数不足最低要求时解散对局,剩余用户返回匹配队列。
- 全员到齐则将对局状态更新为
4. 高并发场景坑点规避
- 所有匹配、在线状态、临时对局的热数据全部存Redis做内存操作,不要直接查MySQL做计算,能把匹配全程延迟压到毫秒级,等对局正式结束后再把对局结果、用户数据变动持久化到MySQL做存档。
- WebSocket服务做集群部署时,用Redis Pub/Sub做跨节点消息广播,保证不同节点接入的用户能正常互通匹配、消息能准确推送到对应用户,不会出现节点间数据隔离导致的匹配失败。
- 所有匹配、进对局的操作必须做幂等校验,每个用户同一时间只能存在于一个匹配队列、一个对局中,避免高并发下出现同个用户同时进入多个对局的脏数据问题。
- 对局内的答题结果、积分变动、淘汰提示等实时交互数据全部走WebSocket推送,单条消息延迟控制在100ms以内就能达到和PUBG匹配接近的流畅体验。
内容的提问来源于stack exchange,提问作者Yeshwant Thota
相关产品推荐
相关产品推荐

