WebSocket 技术允许开发人员在客户端和服务器之间建立一个持久的双向通信连接,极大地增强了应用程序的实时交互能力。利用 WebSocket,开发者可以实现即时消息传递、实时数据更新等功能。在前端,WebSocket 的使用相对简单,因为现代浏览器已经内置了支持 WebSocket 的 API。开发者只需创建一个 WebSocket 对象,即可开始向服务器发送和接收数据。
WS:简介
WS 是一个用于为 Node.js 创建 WebSocket 服务器的库。通过监听传入的连接请求并以字符串或字节缓冲区的形式响应原始消息。作为一个轻量级的WebSocket实现,ws
在性能方面表现优秀,尤其是在处理大量连接时。但ws
相对基础,缺少像自动重连、广播、分组等高级功能。相比于Socket.io
,二者还是有些区别:
- 目标和复杂度 :
ws
更专注于提供一个符合标准的、高性能的WebSocket实现,而Socket.io旨在提供一个无缝的、在所有平台上都能工作的实时通信解决方案。 - 功能与易用性 :Socket.io提供了许多开箱即用的功能,非常适合需要复杂实时交互的应用。相比之下,
ws
更适合那些寻求轻量级解决方案和对WebSocket协议有深入定制需求的开发者。 - 适用场景 :如果你在一个环境中工作,你知道WebSocket支持良好,并且你不需要额外的功能如自动重连或广播,那么
ws
可能是一个更好的选择。如果你需要确保应用在各种客户端都能正常工作,或者需要复杂的特性,如房间支持或广播消息,那么Socket.io可能更合适。
选择哪一个库,最终取决于你的项目需求、目标用户群体的技术环境、以及你希望投入到库管理和配置的精。
创建 Node.js 项目
- 创建项目目录: 打开终端或命令提示符,创建一个新的文件夹,然后进入该文件夹:
bash
mkdir websocket-example
cd websocket-example
npm init -y
npm install ws
- 创建 server.js: 创建一个 WebSocket 服务器来侦听来自客户端的连接和消息。
js
const WebSocket = require('ws');
// 创建一个 WebSocket 服务器
const wss = new WebSocket.Server({ port: 8080 });
console.log('WebSocket server started on port 8080.');
// 处理连接事件
wss.on('connection', (ws) => {
console.log('A new client connected.');
// 向客户端发送欢迎消息
ws.send('Welcome to the WebSocket server!');
// 处理客户端发送的消息
ws.on('message', (message) => {
console.log('Received: %s', message);
// 回传收到的消息给客户端
ws.send(`Echo: ${message}`);
// 模拟延迟后再发送消息给客户端
setTimeout(() => {
ws.send('Goodbye, server!');
}, 3000);
});
});
- 创建 client.js: 创建一个连接到服务器并与其交互的 WebSocket 客户端。
js
const WebSocket = require('ws');
// 创建一个 WebSocket 客户端连接至本地服务器
const ws = new WebSocket('ws://localhost:8080');
// 处理连接打开事件
ws.on('open', () => {
console.log('Connected to the server.');
// 向服务器发送消息
ws.send('Hello, server!');
});
// 处理从服务器接收到的消息
ws.on('message', (message) => {
const data = message.toString('utf8');
console.log('Received: ', data);
// 如果收到特定消息则关闭连接
if (data === 'Goodbye, server!') {
ws.close();
}
});
// 处理连接关闭事件
ws.on('close', () => {
console.log('Disconnected from the server.');
});
- 运行:
打开两个终端窗口,在第一个终端中,运行服务器:
bash
node server.js
在第二个终端中,运行客户端:
bash
node client.js
在服务器终端上,会看到:
bash
WebSocket server started on port 8080.
A new client connected.
received: Hello, server!
在客户端终端上,会看到:
bash
Connected to the server.
received: Welcome to the WebSocket server!
received: Echo: Hello, server!
// 3秒之后收到
received: Goodbye, server!
Disconnected from the server.
模拟点赞计数
- server.js
js
const WebSocket = require('ws');
// 创建一个 WebSocket 服务器,监听 8080 端口
const wss = new WebSocket.Server({ port: 8080 });
console.log('WebSocket server started on port 8080.');
let likeCount = 0;
// 处理连接事件
wss.on('connection', (ws) => {
console.log('A new client connected.');
// 向新连接的客户端发送初始点赞数
ws.send(JSON.stringify({ type: 'likeCount', count: likeCount }));
// 处理客户端发送的消息
ws.on('message', (message) => {
console.log('Received: %s', message);
try {
const data = JSON.parse(message);
// 检查消息类型并处理
if (data.type === 'like') {
// 增加点赞数
likeCount++;
// 广播更新后的点赞数给所有连接的客户端
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({ type: 'likeCount', count: likeCount }));
}
});
}
} catch (error) {
console.error('Error parsing JSON message:', error);
}
});
});
对于连接事件的处理: wss.on('connection', function connection(ws) { ... });
当有新的客户端连接到服务器时触发。
-
向客户端发送初始点赞数 :
ws.send(JSON.stringify({ type: 'likeCount', count: likeCount }));
当客户端连接成功后,向客户端发送当前的点赞数。 -
处理客户端发送的消息 :
ws.on('message', function incoming(message) { ... });
监听客户端发送的消息事件。 -
解析消息并处理 :
const data = JSON.parse(message);
解析客户端发送的 JSON 格式消息。 -
检查消息类型并增加点赞数 : 如果收到类型为
'like'
的消息,将点赞数likeCount
加一,并向所有连接的客户端广播更新后的点赞数。
- client.html
-
创建 WebSocket 客户端:
jsconst socket = new WebSocket('ws://localhost:8080');
在页面加载时,创建一个 WebSocket 客户端并连接到运行在
localhost:8080
上的 WebSocket 服务器。 -
处理从服务器接收到的消息:
jssocket.onmessage = function(event) { const data = JSON.parse(event.data); if (data.type === 'likeCount') { document.getElementById('likeCount').textContent = data.count; } };
监听 WebSocket 客户端收到消息的事件。当从服务器收到消息时,解析消息内容并根据消息类型更新页面上的点赞数显示。
-
处理按钮点击事件:
jsdocument.getElementById('likeButton').addEventListener('click', function() { socket.send(JSON.stringify({ type: 'like' })); });
监听页面上按钮的点击事件。当用户点击按钮时,向服务器发送一个代表点赞的消息。
完整代码如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Client</title>
</head>
<body>
<h1>WebSocket Like Example</h1>
<p>Like Count: <span id="likeCount">0</span></p>
<button id="likeButton">Like!</button>
<script>
// 创建 WebSocket 客户端连接至本地服务器
const socket = new WebSocket('ws://localhost:8080');
// 处理从服务器接收到的消息
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.type === 'likeCount') {
// 更新点赞数显示
document.getElementById('likeCount').textContent = data.count;
}
};
// 处理按钮点击事件,向服务器发送点赞消息
document.getElementById('likeButton').addEventListener('click', function() {
socket.send(JSON.stringify({ type: 'like' }));
});
</script>
</body>
</html>
- 页面上有一个标题
<h1>
和一个显示点赞数的<span>
元素,初始点赞数为0
。 - 有一个按钮
<button>
,点击这个按钮会向服务器发送一个代表点赞的消息。 - 当客户端收到来自服务器的点赞数更新消息时,页面会自动更新显示最新的点赞数。