一、什么是 WebSocket

在学习 WebSocket 之前,我一直使用的是普通的 HTTP 请求。

HTTP 的特点是:

客户端请求一次
服务端返回一次
然后连接断开

例如:

  • 登录

  • 获取用户信息

  • 获取商品列表

  • 提交表单

这些都适合使用 HTTP。

但是,当项目开始涉及:

  • 聊天室

  • 多人联机

  • 实时消息

  • 游戏同步

  • 在线状态

这类“实时通信”功能时,HTTP 就会变得不够方便。

因为 HTTP 需要不断轮询:

客户端不停请求服务器
问:有没有新消息?

这种方式:

  • 浪费性能

  • 延迟高

  • 实时性差

于是就有了 WebSocket。


二、WebSocket 的核心理解

WebSocket 本质上是:

客户端与服务器建立一个长连接
双方可以持续实时通信

与 HTTP 最大的区别:

HTTP WebSocket
请求一次断开 建立后持续连接
客户端主动请求 双方都可主动发送
不适合实时通信 非常适合实时通信

WebSocket 建立连接后:

客户端可以发消息给服务端
服务端也可以主动发消息给客户端

这一点对于实时系统非常重要。


三、WebSocket 建立连接的真实过程

一开始我以为:

new WebSocket()

就是直接建立 websocket 连接。

后来才真正理解:

WebSocket 一开始其实也是 HTTP 请求

只是它会进行“协议升级”。

整体流程如下:

浏览器
↓
发起 HTTP 请求
↓
请求头包含:Upgrade: websocket
↓
服务器同意升级
↓
HTTP 协议升级为 WebSocket
↓
双方进入长连接状态

服务端会返回:

101 Switching Protocols

表示:

协议升级成功

从这一刻开始:

客户端与服务器就进入持续通信状态

四、为什么 WebSocket 特别适合游戏

因为游戏很多信息都需要:

实时同步

例如:

  • 玩家移动

  • 技能释放

  • 血量变化

  • 房间准备

  • 骰子结果

  • 排行榜变化

这些都需要服务器主动通知其他玩家。

如果使用 HTTP:

客户端需要不停轮询

体验会非常差。

而 WebSocket:

服务器可以实时广播

因此非常适合:

  • 棋牌游戏

  • MOBA

  • 房间对战

  • 在线聊天

  • 实时协作


五、我对 WebSocket 最大的理解

学习过程中,我对 WebSocket 最大的理解是:

WebSocket 本质上就是:
“实时消息通道”

客户端和服务端:

不断互相发送消息

真正重要的不是 WebSocket 本身。

而是:

消息协议设计

例如:

{
    "type": "player_move",
    "data": {
        "user_id": 1,
        "x": 100,
        "y": 200
    }
}

这里:

  • type 表示消息类型

  • data 表示具体数据

前端收到后:

根据 type 执行对应逻辑

例如:

  • 播放移动动画

  • 更新玩家坐标

  • 显示聊天消息

  • 更新 UI

因此:

后端负责“状态”
前端负责“表现”

这是我学习 WebSocket 后非常重要的一个理解。


六、FastAPI 中的 WebSocket

我使用的是:

FastAPI + WebSocket

路由示例:

@router.websocket("/ws/match/{match_id}/{user_id}")
async def match_websocket(
    websocket: WebSocket,
    match_id: int,
    user_id: int
):

当前端连接:

new WebSocket(
    "ws://127.0.0.1:8000/ws/match/1001/1"
)

FastAPI 会:

  1. 接收 websocket 请求

  2. 创建 WebSocket 对象

  3. 进入 websocket 路由

  4. 建立长连接

随后:

await websocket.accept()

表示:

服务器同意建立 websocket 连接

七、ConnectionManager 的理解

在学习过程中,我自己实现了一个:

ConnectionManager

它本质上是:

WebSocket 连接管理器

主要负责:

  • 保存在线连接

  • 广播消息

  • 管理频道

  • 用户断线处理

例如:

self.connections = {
    user_id: websocket
}

用于保存:

哪个用户对应哪个 websocket 连接

而:

self.channels = {
    "match:1001": {1,2,3}
}

则表示:

某个对局频道里有哪些玩家

这个设计让我真正理解了:

房间 = 频道
对局 = 频道
队伍 = 频道

这其实已经非常接近真实游戏服务器的架构。


八、广播机制的理解

多人联机最核心的部分之一:

广播

例如:

玩家1移动后:

{
    "type": "player_action",
    "data": {
        "action": "move",
        "x": 100,
        "y": 200
    }
}

服务端收到后:

广播给同一个房间中的其他玩家

其他客户端收到后:

更新玩家位置

整个过程本质上就是:

客户端发送动作
↓
服务端同步状态
↓
广播给其他客户端
↓
客户端更新画面

这也是联机游戏最核心的思想。


九、心跳机制的理解

WebSocket 是长连接。

但有时候:

客户端断网

连接并不会立刻断开。

因此需要:

心跳检测

例如:

客户端定时发送:

{
    "type": "ping"
}

服务端返回:

{
    "type": "pong"
}

如果长时间没有收到:

说明连接可能已经断开

这是很多实时系统都必须具备的功能。


十、我目前对 WebSocket 的总结

学习 WebSocket 后,我最大的感受是:

WebSocket 不只是一个通信技术
而是一种“实时系统思维”

真正重要的包括:

  • 连接管理

  • 消息协议

  • 广播机制

  • 在线状态

  • 房间系统

  • 心跳检测

  • 状态同步

尤其是在多人游戏中:

WebSocket 只是“通信通道”
真正核心的是:
如何设计消息与同步逻辑

目前我也正在继续学习:

  • 游戏状态同步

  • 帧同步

  • Redis 广播

  • 分布式 websocket

  • 多人房间架构

WebSocket 对于实时系统开发来说,确实是非常重要的一部分。


十一、结语

通过这段时间学习 WebSocket,我对:

  • 实时通信

  • 多人联机

  • 游戏同步

  • 服务端广播

都有了更深的理解。

相比只停留在:

send("hello")

我现在更关注:

整个实时系统是如何协作的

后面也会继续深入学习:

  • FastAPI

  • Redis

  • 游戏服务器架构

  • WebSocket 分布式

  • 联机同步优化

希望这篇文章也能帮助刚开始学习 WebSocket 的同学建立整体理解。

更多推荐