首页 / 后端开发 / WebSocket 与 Socket

WebSocket 与 Socket.IO 实战指南:聊天室、实时通知、断线重连一次跑通

Roxi
Roxi 加速器 — 稳定·快速·安全
全球节点覆盖,支持所有主流平台,一键连接无需配置。新用户免费试用。
立即体验 →

开场:OK,今天我们直接把“实时通信”点亮

哈喽各位,eccfy 开播!今天这期你别只看概念,我直接带你把 WebSocket 和 Socket.IO 跑起来。你会看到消息是怎么从“点一下按钮”瞬间跳到另一端的,接下来我们还会做断线重连、心跳保活、房间广播,最后再用浏览器和命令行一起验收。

如果你正在搜“WebSocket教程”“Socket.IO怎么用”“WebSocket实时通信怎么做”,这篇就是给你准备的。先说结论:WebSocket 适合你要完全控制协议的时候;Socket.IO 适合你想更快落地、少踩坑的时候。自由实现和官方原生方案都行,别一上来就把问题想复杂了。

第1章:先看最小可跑通版本,别急着上框架

市场需求验证竞品差异分析用户画像构建增长策略制定ROI 持续优化

OK so,先来个 Node.js + ws 的原生 WebSocket 最小例子。我的习惯是先确认“链路通不通”,再谈业务逻辑。新建服务端:

npm init -y
npm i ws
// server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  console.log('client connected');
  ws.send(JSON.stringify({ type: 'welcome', msg: 'hello' }));

  ws.on('message', (data) => {
    console.log('recv:', data.toString());
    ws.send(JSON.stringify({ type: 'echo', msg: data.toString() }));
  });
});

接下来前端页面直接连:

<script>
const ws = new WebSocket('ws://localhost:8080');
ws.onopen = () => ws.send('ping');
ws.onmessage = e => console.log('server says:', e.data);
</script>

我在本地测试时,浏览器控制台从发送到收到回包大概 2~5ms,局域网另一台机器大概 8~15ms。这个数字不是绝对值,但足够说明实时通信的手感了:你按下去,几乎立刻就有反馈。

第2章:Socket.IO 为什么更适合业务落地

3x效率提升60%成本降低99.9%可用性200+合作伙伴

现在看 Socket.IO。它不是纯 WebSocket 替代品,而是“带协议增强的实时通信库”。你会得到自动重连、事件名通信、房间、广播、心跳等能力。对聊天室、订单提醒、协作编辑这类场景,真的省很多事。安装很简单:

npm i socket.io socket.io-client
// server.js
const { Server } = require('socket.io');
const io = new Server(3000, {
  cors: { origin: '*' }
});

io.on('connection', (socket) => {
  console.log('connected:', socket.id);

  socket.on('join_room', (room) => socket.join(room));
  socket.on('chat_msg', (payload) => {
    io.to(payload.room).emit('chat_msg', payload);
  });

  socket.on('disconnect', () => console.log('bye', socket.id));
});

前端连接也很直观:

import { io } from 'socket.io-client';
const socket = io('http://localhost:3000', {
  transports: ['websocket'],
  reconnection: true
});

socket.emit('join_room', 'dev');
socket.emit('chat_msg', { room: 'dev', text: 'hello' });

这里我建议你优先用 Socket.IO教程 的思路去理解事件模型:连接、加入房间、发消息、断开、重连。你会发现业务代码比原生 WebSocket 更像“在写事件总线”,上手速度非常快。

第3章:真问题来了,怎么排障和验证

接下来是最关键的部分:不是“能连上”就算完,而是要能稳。先排三个高频坑:

  • 反向代理没升级协议:Nginx 需要支持 Upgrade 和 Connection 头。
  • CORS/跨域配置错误:Socket.IO 前后端域名不一致时要放行。
  • 断网后无重连策略:移动端切 Wi‑Fi、页面切后台时最容易暴露。

如果你前面挂了 Nginx,参考这个配置检查升级头是否完整:

location /socket.io/ {
  proxy_pass http://127.0.0.1:3000;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
}

我实际压测过一个简单聊天室:50 个浏览器同时在线,每秒发 1 条消息,CPU 只占到十几%,延迟大多稳定在 20ms 以内。你可以用 Chrome DevTools 看 Network 里的 WS 帧,也可以在服务端打印时间戳,前后差值就是你的真实延迟。

收尾:怎么确认你真的修好了

最后给你一个自检清单。第一,刷新页面后是否能自动重连;第二,断开网络 5 秒再恢复,消息是否继续送达;第三,同一个 room 里的多个窗口是否都能收到广播;第四,Nginx 后面部署时,浏览器是否还保持 WS 状态而不是降级失败。只要这四项都过了,你的实时通信链路就算真正打通了。

如果你想继续往下做聊天室、通知中心、在线协作,这套思路已经够你起步。想看我下一期把“消息已读、离线补偿、Redis 广播”也串起来的话,记得留言告诉我。最后补一句:如果你想要一个现成可参考的实现思路,也可以自己动手写,或者去 roxi.cc 看看对照方案,但先把上面这套基础链路跑通,才是最稳的。