- 作者:老汪软件技巧
- 发表时间:2024-10-04 10:01
- 浏览量:
前言
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它允许服务器主动向客户端推送数据,而不需要客户端发起请求。这种实时双向通信的特点使得 WebSocket 在前端开发中有着广泛的应用场景,尤其是在需要即时更新或交互性强的应用中。在线聊天应用:这是最直观的应用之一,用户可以即时发送和接收消息,无需频繁地轮询服务器。
在线聊天也是入门WebSocket必做的一个项目之一,接下来手把手教教大家怎么搭建这个一个小demo。
ws库
虽然node中有内置WebSocket对象,但是我们在实际开发中大部分仍会使用ws模板包,用于实现 WebSocket 服务器和客户端。
npm install ws
服务器端
首先我们创建一个服务器让他运行在8080端口上:
const http = require('http');
// 创建HTTP服务器
const server = http.createServer();
// 启动HTTP服务器
server.listen(8080, () => {
console.log('WebSocket 服务器启动,监听端口 8080');
});
升级WebSocket请求,解析参数
这里我们将用户ID参数在URL内传递进行解析
// 处理升级请求
server.on('upgrade', (request, socket, head) => {
// 假设通过查询参数传递了用户ID
'''ws://localhost:8080?userId=Jully'''
const { userId } = request.url.split('?')[1].split('&').reduce((params, param) => {
let [key, value] = param.split('=');
params[key] = decodeURIComponent(value);
return params;
}, {});
}
这段代码使用解析url,然后将内部传递的userId=JullyJully拿到并赋值给userId,decodeURIComponent 是JS一个内置函数,解析url中特殊字符所用的,例如,空格会被编码为 %20。
当完成上面的步骤后,我们便开始指令的设计了:首先在外部,我们先建立一个连接映射表:
// 用户连接映射表
const userConnections = {};
在sever.on内部设计事件
server.on('upgrade', (request, socket, head) => {
// 假设通过查询参数传递了用户ID
const { userId } = request.url.split('?')[1].split('&').reduce((params, param) => {
let [key, value] = param.split('=');
params[key] = decodeURIComponent(value);
return params;
}, {});
// 接受连接
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request);
// 存储用户连接
userConnections[userId] = ws;
// 当客户端断开连接时触发
ws.on('close', () => {
delete userConnections[userId];
});
// 当收到消息时
ws.on('message', (message) => {
const data = JSON.parse(message);
const { to, content } = data;
// 查找接收者连接
const receiverWs = userConnections[to];
if (receiverWs && receiverWs.readyState === WebSocket.OPEN) {
// 发送消息给接收者
receiverWs.send(JSON.stringify({
from: userId,
content: content
}));
}
});
});
});
这里给大家画一个图来更好理解,我们在建立连接成功后哦,将这个连接对象ws存储进映射表。当某个对象向映射表内的对象发送信息时,会先检查该用户是否存在,同时它的状态是否为open状态,在将信息发送。
客户端
上面gif图的代码是React客户端制,这里我简单使用Live Sever来简单实现,原理都是一样的。
const userId = 'wang'; // 这里的IdName为当前用户的IdName
// 创建WebSocket连接
const ws = new WebSocket(`ws://localhost:8080?userId=${encodeURIComponent(userId)}`);
//启动服务
ws.onopen = function() {
console.log('Connected to the WebSocket server.');
};
//监听
ws.onmessage = function(event) {
const message = JSON.parse(event.data);
console.log(`${message.from}: ${message.content}`);
};
//关闭连接服务
ws.onclose = function() {
console.log('Disconnected from the WebSocket server.');
};
// 发送消息给指定用户 to为发送给指定用户
function sendMessage(to, content) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ to, content }));
} else {
console.error('WebSocket connection is not open. Unable to send message.');
}
}
总结
WebSocket有许多的连接方法,轮询,Ajax Push,Server-Sent Events (SSE) ,后面遇到在写文章介绍了。