没有账号系统,如何实现房间、身份与断线重连

1226 字
6 分钟
没有账号系统,如何实现房间、身份与断线重连

“洛一把”没有用户账号,却仍然需要知道刷新后的玩家是谁、该回到哪个座位,以及掉线前有多少分。

解决办法不是把昵称当身份,而是在加入房间时签发一组临时凭据,让“方便人类识别的名字”和“机器可验证的身份”分开。

房间码只负责定位房间#

房间码由六位大写易读字符组成,并排除容易混淆的 0/O/1/I。创建时随机生成,如果已经存在就重新生成。

房间码适合口头分享,但它不是密码。知道房间码只能尝试加入等待中的房间,不能冒充已有玩家。

创建或加入成功后,服务端返回:

  • playerId:房间内部的随机玩家 ID;
  • resumeToken:高熵恢复令牌;
  • code:房间码。

客户端把这些信息保存在本机。之后建立 WebSocket 或刷新重连时携带恢复令牌,服务端才能把新连接重新绑定到原玩家。

昵称不能承担身份职责#

昵称限制为 1—12 个字符,并且房间内不能重复。这个限制是为了显示和交流,不是为了安全。

如果重连只提交昵称,任何知道房间码的人都可以在原玩家掉线后抢占其积分。恢复令牌则把“用户友好的名字”和“机器可验证的身份”分开了。

等待阶段和比赛阶段采用不同离线规则#

等待阶段的目标是顺利坐满。普通玩家主动离开,或者断线超过十秒,席位就可以释放,让其他人加入。

比赛开始后房间锁定。掉线玩家的席位、得分和答题记录会保留到整场结束,新玩家不能替换参赛者。否则一次网络波动就可能让陌生人继承原玩家的位置。

房主掉线时先等待十秒;仍未恢复,则把房主权限转给当前在线且加入最早的玩家。比赛进行中不依赖房主推进,但等待房间必须始终有人能够开始游戏。

所有玩家都离线后,房间继续保留三十分钟,给移动网络切换、页面刷新和设备短暂休眠留下恢复窗口。超过保留时间才清理持久状态。

一个 WebSocket 不等于一个玩家#

浏览器可能重复连接,也可能旧连接尚未完全关闭,新连接已经建立。因此服务端维护的是“连接到玩家 ID”的映射,而不是把连接对象直接当玩家。

玩家是否在线,取决于是否仍有任何有效连接指向该 ID。断开一条旧连接时,如果同一玩家已经建立新连接,不能误把玩家标记成离线。

客户端连接流程保持简单:

  1. 根据房间码读取本地身份;
  2. 使用恢复令牌建立 WebSocket;
  3. 连接成功后发送 sync
  4. 收到服务端状态后校准时钟;
  5. 断开时显示“正在重连”;
  6. 等待 1.5 秒后重新连接。

页面不自行合并增量事件,而是反复接收服务端投影的房间快照。房间人数最多四人,完整快照体积可控,却能显著降低客户端状态错乱的概率。

状态同步也承担超时恢复#

线上运行后,曾经出现过房间停在 0 秒却没有结算的情况。仅仅重连并重新发送旧状态不能解决问题,因为房间仍然认为自己处于游戏中。

后来 sync 被升级成状态机的恢复入口:服务端收到同步请求时,会先使用当前时间执行一次 tick,补做已经到期的提示、结算或下一轮,再广播新状态。

客户端也会在校准时间超过截止时间 500 毫秒后发送一次兜底同步。它不能在本地直接结算,但可以唤醒权威状态机。

这条机制非常实用:重连不应该只恢复网络连接,还应该推动已经落后的服务端状态追上现实时间。

这套房间系统解决了什么#

在没有账号和数据库用户表的前提下,系统仍然实现了:

  • 房间内唯一玩家;
  • 刷新后恢复原席位;
  • 断线不丢分;
  • 不重复创建玩家;
  • 房主自动转移;
  • 游戏开始后禁止替补;
  • 有期限的房间恢复。

它不适合长期社交关系和跨设备账号同步,但非常适合一次性、低门槛、通过链接邀请朋友加入的小型网页游戏。

项目仓库:LonakoBc/luo-yi-ba
在线试玩:luo-yi-ba.pages.dev

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
没有账号系统,如何实现房间、身份与断线重连
https://lonako-blog.bocchi0708.workers.dev/posts/post2026-8-15-1/
作者
Lonako
发布于
2026-08-15
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Lonako
Hello, I'm Lonako !
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
站点统计
文章
13
分类
7
标签
35
总字数
19,588
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.16.3
文章许可
CC BY-NC-SA 4.0