最近在开发一个多人在线骰子游戏项目时,我第一次真正深入接触 WebSocket。

以前学前端的时候,我一直觉得:

  • 登录用 HTTP

  • 获取数据用 HTTP

  • 提交表单用 HTTP

好像整个项目都离不开 HTTP。

直到开始做实时对战游戏,我才发现:

HTTP 根本解决不了所有问题。

为什么需要 WebSocket?

想象这样一个场景:

玩家 A 创建房间。

玩家 B 通过房间号加入。

玩家 C 进入房间。

玩家 D 准备开始游戏。

如果使用传统 HTTP:

前端只能不断轮询:

setInterval(() => {
  fetch('/room/status')
}, 1000)

每秒请求一次服务器。

这样会产生几个问题:

1. 数据不实时

如果轮询间隔是 1 秒:

玩家 B 已经进入房间,

但玩家 A 可能需要等待 1 秒后才能看到。

2. 请求浪费

即使房间什么都没发生:

前端仍然在不断发送请求。

3. 多人场景压力大

如果:

  • 1000 个房间

  • 每个房间 4 个人

那么服务器会收到大量无意义请求。

因此就需要 WebSocket。

WebSocket 到底是什么?

第一次接触的时候我一直没理解。

后来我把它理解成:

HTTP 是打电话。

每次有事:

  • 拨号

  • 通话

  • 挂断

下一次再重新拨号。

而 WebSocket 更像是:

建立一个微信群。

连接成功后:

服务器和客户端一直保持连接。

任何一方有消息:

直接发送。

无需重新建立连接。

所以它特别适合:

  • 在线聊天

  • 多人游戏

  • 实时排行榜

  • 股票行情

  • 在线协同编辑

这些实时场景。

我项目中的 WebSocket 流程

在我的骰子游戏里:

创建房间

房主调用接口:

POST /match/create

返回:

{
  "roomId": "123456"
}

随后连接:

ws://server/room/123456

加入房间频道。


玩家加入房间

玩家输入房间号:

POST /match/join

加入成功后:

同样连接:

ws://server/room/123456

这样所有玩家都在同一个频道。


房间状态同步

有人进入房间:

服务器推送:

{
  "type": "player_join",
  "player": {
    "id": 2,
    "name": "Tom"
  }
}

所有客户端收到消息:

socket.onmessage = (event) => {
  const data = JSON.parse(event.data)
}

然后更新玩家列表。

无需刷新页面。

我遇到的第一个坑:疯狂重连

这个问题折磨了我很久。

现象:

控制台不断打印:

WebSocket Connected
WebSocket Closed
WebSocket Connected
WebSocket Closed

疯狂循环。

后来排查发现:

React 的 useEffect 依赖写错了。

类似这样:

useEffect(() => {
  connect()
}, [players])

而 players 又会被 WebSocket 消息更新。

于是:

收到消息
↓
players变化
↓
effect重新执行
↓
关闭旧连接
↓
建立新连接
↓
再次收到消息
↓
继续循环

最终形成无限重连。

这是我第一次真正意识到:

React 状态更新和 WebSocket 生命周期之间存在强关联。

第二个坑:连接成功了,但消息收不到

当时我以为:

连接成功 = 功能正常。

后来发现:

并不是。

可能出现:

WebSocket OPEN

但实际上:

  • 加入了错误房间

  • 房间号传错

  • 用户身份错误

结果:

连接虽然存在,

却永远收不到真正的数据。

所以后来我都会验证:

socket.send({
  type: 'ping'
})

确认服务器确实能正常响应。

我对 WebSocket 的理解

以前我觉得:

WebSocket 是一个高级技术。

后来发现:

它本质上只是解决一个问题:

让服务器主动通知客户端。

如果项目不需要实时性:

HTTP 完全够用。

如果项目涉及:

  • 多人协作

  • 在线聊天

  • 实时游戏

那么 WebSocket 基本是必选项。

总结

这次开发多人骰子游戏,我最大的收获不是学会了 WebSocket API。

而是真正理解了:

前端不仅仅是在写页面。

当项目开始涉及多人协作、实时通信、状态同步时,

就必须开始理解客户端、服务器以及连接生命周期之间的关系。

WebSocket 对我来说不再只是一个技术名词。

它是我第一次真正接触实时系统开发的起点。

而那些连接失败、无限重连、消息丢失的坑,

也成了这次项目里最深刻的学习经历。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐