使用 WebSockets 构建实时应用
轮询对你的应用不利。
我曾经用 AJAX 轮询构建过一个聊天组件。我设置应用每秒向服务器请求一次新消息。虽然能运行,但速度很慢。UI 感觉有延迟。服务器负担过重。大多数请求返回的都是空数据。这感觉就像在尝试用小勺子往浴缸里注水。
WebSockets 改变了这一切。
与其进行不断的请求,不如开启一个持久连接。这实现了数据的双向流动。服务器可以立即向客户端推送数据,客户端也可以立即向服务器发送数据。
为什么要使用 WebSockets?
• 延迟从数百毫秒降低到数十毫秒。 • 服务器负载变得可预测。 • 通过消除重复的 HTTP 标头,你可以节省带宽。 • 它适用于聊天、实时通知和多人游戏。
工作原理:
连接始于一个 HTTP 升级请求。如果服务器同意,它会发送一个 101 状态码。之后,你使用的是原始的二进制或文本协议。不再有 Cookie 或标头来拖慢你的速度。
需要避免的常见陷阱:
- 连接中断:网络会出故障。你必须实现类似指数退避(exponential backoff)的重试策略。
- 内存泄漏:用户离开时务必关闭你的 Socket。僵尸连接会消耗服务器内存。
- 消息循环:在广播消息时,跳过原始发送者。否则,用户会看到两次自己的消息。
- 空闲连接:某些代理会关闭静默连接。使用 ping/pong 心跳机制来保持 Socket 活跃。
不要再不停地询问服务器是否有变化了。开始保持一条线路畅通,以便在需要时随时进行通信。
你的挑战:
找一个基础的聊天示例。添加一个“正在输入...”的指示器。将其部署到 Render 或 Fly.io 等托管平台。一旦你看到该指示器在没有轮询的情况下实时移动,你就进阶了。