WS 与 Socket.IO:两大主流方案对比
在 Node.js 生态中,WebSocket 有两个最常用的库:ws 和 Socket.IO。它们的设计理念截然不同,选择时需要根据场景权衡。
ws 是对 WebSocket 原生协议的纯实现,没有做任何额外的封装。它的特点是极简、通用、性能极高。ws 的 npm 周下载量远超 Socket.IO,长期保持在 WebSocket 库下载量榜首。因为它只实现了协议本身,定制性非常强,适合需要精细控制 WebSocket 行为的场景,也适合学习 WebSocket 底层原理。
Socket.IO 在原生 WebSocket 之上做了大量封装,提供了自动重连、事件驱动通信、命名空间(Namespace)、房间(Room)、广播消息等开箱即用的功能。它的核心优势在于向下兼容——当浏览器不支持 WebSocket 时,会自动降级为 HTTP 长轮询。Socket.IO 同时提供了多种语言的服务端和客户端 SDK(Java、C++、Python、Go、Swift 等),跨语言生态非常好。
| 对比维度 | ws | Socket.IO |
|---|---|---|
| 协议支持 | 原生 WebSocket | WebSocket + HTTP 长轮询降级 |
| 性能 | 极高 | 略低(封装开销) |
| 功能丰富度 | 基础,需自行实现 | 开箱即用(重连/房间/广播) |
| npm 周下载量 | 更高 | 高 |
| 浏览器兼容 | 依赖原生支持 | 自动降级 |
| 跨语言支持 | 无(纯 JS) | 多语言 SDK |
| 学习价值 | 理解底层原理 | 快速开发业务 |
课程选择从 ws 开始学习,因为要深入理解 WebSocket 的原理,必须从最简的架构入手。理解了底层之后,再用 Socket.IO 就只是 API 层面的差异了。
搭建 WebSocket 服务端
使用 ws 创建服务端非常简单,只需要几行代码:
# 创建项目目录
mkdir server client
cd server
npm init -y
npm install ws
bash
// server/index.js
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 3000 })
wss.on('connection', (ws) => {
console.log('one client is connected')
ws.on('message', (message) => {
console.log('received:', message)
})
ws.send('message from server')
})
console.log('WebSocket server is running on ws://localhost:3000')
javascript
服务端的核心逻辑是:创建一个 WebSocket Server 实例,监听指定端口,然后在 connection 事件中处理每个新连接。每个连接进来后会获得一个 ws 对象,代表这个特定的客户端连接,可以通过它发送和接收消息。
创建浏览器端客户端
浏览器原生支持 WebSocket,不需要安装任何库:
<!-- client/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Client</title>
</head>
<body>
<h1>WebSocket Client</h1>
<script>
const ws = new WebSocket('ws://127.0.0.1:3000')
ws.onopen = function () {
console.log('client is connected to server')
ws.send('hello from client')
}
ws.onmessage = function (event) {
console.log('received:', event.data)
}
</script>
</body>
</html>
html
用 VS Code 的 Live Server 或者任何静态文件服务器打开这个 HTML 文件,浏览器就会自动建立 WebSocket 连接。可以在浏览器的开发者工具 Network 面板中看到 WS 类型的请求,点击后还能查看每条消息的发送和接收记录。
使用 ws 库创建 Node.js 客户端
ws 库的一个实用特性是它既可以作为服务端,也可以作为客户端在 Node.js 环境中使用。这在测试和微服务间通信时非常有用:
cd client
npm init -y
npm install ws
bash
// client/test.js
const WebSocket = require('ws')
const ws = new WebSocket('ws://127.0.0.1:3000')
ws.on('open', () => {
console.log('client is connected to server')
ws.send('hello from client to server')
})
ws.on('message', (message) => {
console.log('message:', message.toString())
})
javascript
需要注意浏览器端和 Node.js 端 API 的差异:浏览器端使用 ws.onopen、ws.onmessage 这种属性赋值方式,而 ws 库在 Node.js 端使用 ws.on('open', callback) 这种事件监听方式。这是初学者最容易混淆的地方。
启动测试流程
整个测试流程是:
- 在第一个终端中启动服务端:
node server/index.js - 用 Live Server 打开浏览器客户端,或者在新终端运行
node client/test.js - 观察两端的消息收发情况
服务端终端会打印出客户端连接的通知,浏览器控制台或 Node.js 客户端终端会打印出从服务端收到的消息。这就是一个最简单的双向实时通信应用。
↑