首页 / 后端开发 / WebSocket实时通信落地脚本:

WebSocket实时通信落地脚本:Socket.IO聊天室、断线重连与延迟测试实操

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

第 1 章:OK so,先把实时通道跑起来

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

兄弟们开机!这里是 eccfy,今天不讲概念 PPT,直接上屏幕:左边 VS Code,右边浏览器控制台,我们做一个能发消息、能测延迟、能自动重连的实时通信 Demo。这个就是很多人搜索 WebSocket实时通信教程Socket.IO怎么用 时真正想要的东西。

先说选择:原生 WebSocket 免费、轻、标准,但你要自己处理重连、心跳、房间、降级;Socket.IO 也是免费开源,封装了这些能力,适合后台通知、聊天室、协同编辑、订单状态推送。接下来直接敲命令:

mkdir realtime-demo
cd realtime-demo
npm init -y
npm i express socket.io
npm i -D nodemon

修改 package.json:

{
  "scripts": {
    "dev": "nodemon server.js"
  }
}

这一步就是 Socket.IO下载与安装 的最短路径,不需要额外装什么“翻墙软件”才能本地开发;除非你拉 npm 包特别慢,再考虑切换 npm 镜像。

第 2 章:Now watch this,服务端和页面一起点亮

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

新建 server.js,注意看我屏幕,核心就三件事:启动 HTTP、挂 Socket.IO、监听消息。

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: { origin: '*' },
  pingInterval: 25000,
  pingTimeout: 10000
});

app.use(express.static('public'));

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

  socket.on('chat:send', (msg) => {
    io.emit('chat:new', {
      id: socket.id,
      text: msg,
      time: Date.now()
    });
  });

  socket.on('latency:ping', (clientTime, cb) => {
    cb({ clientTime, serverTime: Date.now() });
  });

  socket.on('disconnect', (reason) => {
    console.log('disconnect:', reason);
  });
});

server.listen(3000, () => {
  console.log('http://localhost:3000');
});

接下来建 public/index.html,前端部分我故意写得很短,方便你复制到 Vue、React 或 Next.js 项目里,这也是一个可迁移的 Node.js WebSocket示例

<input id="msg" placeholder="输入消息" />
<button onclick="send()">发送</button>
<button onclick="testLatency()">测速</button>
<ul id="list"></ul>
<pre id="status"></pre>

<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io({
  reconnection: true,
  reconnectionAttempts: 5,
  reconnectionDelay: 1000
});

socket.on('connect', () => {
  status.textContent = '已连接:' + socket.id;
});

socket.on('disconnect', (reason) => {
  status.textContent = '已断开:' + reason;
});

socket.on('chat:new', (data) => {
  const li = document.createElement('li');
  li.textContent = data.id + ': ' + data.text;
  list.appendChild(li);
});

function send() {
  socket.emit('chat:send', msg.value);
  msg.value = '';
}

function testLatency() {
  const start = Date.now();
  socket.emit('latency:ping', start, (res) => {
    const rtt = Date.now() - start;
    status.textContent = 'RTT=' + rtt + 'ms, server=' + res.serverTime;
  });
}
</script>

运行:

npm run dev

打开两个浏览器窗口访问 localhost:3000。左边输入“hello”,右边秒出;右边回“收到”,左边也能看见。OK,这就是 before/after:之前你只有普通 HTTP 请求,现在已经是双向实时通道。

第 3 章:断线重连、测速,以及怎么确认真的修好了

我本机测试环境是 Node.js 20、Chrome、MacBook Pro,同机房本地回环测试 20 次,原生 WebSocket RTT 大概 8-15ms,Socket.IO 约 11-20ms,多出来的是协议封装成本,但换来的是重连、心跳、事件模型。实际公网如果 RTT 超过 200ms,先别急着甩锅代码,检查 DNS、代理、公司网关、免费VPN延迟测试结果;很多“油管怎么看”类网络方案适合浏览,不一定适合稳定长连接。

排障按这个顺序来:

  1. 浏览器 DevTools → Network → WS,确认状态码是 101 或 Socket.IO polling/websocket 正常升级。
  2. 服务端打印 connect/disconnect,若频繁断开,调大 pingTimeout,例如 20000。
  3. Nginx 反代时加上 Upgrade 头,否则会卡在轮询。
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_read_timeout 60s;

如何验证它真的工作:开两个窗口互发 10 条消息,DevTools 里 WS 帧持续出现;点击测速 5 次,RTT 稳定在你的网络范围内;手动停止 server 再重启,页面能在 1-5 秒内恢复连接,这说明 Socket.IO断线重连配置 生效。

如果是跨境团队联调,官方免费方案、本地内网、云服务器自建都可以先试;付费网络工具只是选项之一,例如 Roxi(https://wizzegroup.com),但请先把上面的代码、反代和验证流程跑通。觉得这个 Demo 有用,收藏、转发,评论区丢你的延迟数据,我们下期继续实测!