文章目录
前言
使用Websocket+Node实现一个简单的聊天室的功能,以及包含保持websocket长时间连接永不断开的两种方法
一、Websocket是什么?
WebSocket是一种网络通信协议,是 HTML5
开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。其目的是在WebSocket应用和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。
二、使用步骤
1.服务端代码
npm install koa
npm install ws
npm install koa-static
var Koa = require('koa');
const http = require('http');
const WebSocket = require('ws');
const path = require('path');
const serve = require('koa-static');
const app = new Koa(); // 初始化koa应用
app.use(serve(path.join(__dirname, '.'))); // 提供静态文件
const server = http.createServer(app.callback()); // 创建http服务器
let clientNames = ['小明', '小红', '小军', '小王']
const wss = new WebSocket.Server({ server }); // 创建 WebSocket 服务器
// 监听WebSocket连接
wss.on('connection', (ws) => {
ws.clientName = clientNames.pop();
console.log(ws.clientName + 'contect');
// 监听客户端发送的消息
ws.on('message', (message) => {
wss.clients.forEach(client => {
if(client.readyState !== WebSocket.OPEN) return
if(message == 'hello') {
client.send('收到,hello')
}else {
client.send(`${ws.clientName == client.clientName ? '我' : ws.clientName}:${message}`)
}
})
})
// 监听客户端断开连接
ws.on('close', () => {
console.log(`${ws.clientName} 断开连接!`);
})
})
const PORT = 5500
server.listen(PORT, () => {
console.log('5500端口连接上了---');
})
2.客户端代码
保持websocket长时间连接永不断开的两种方法
- 方式一:定期发送心跳包
客户端代码
timeoutObj = setTimeout(() => {
console.log('发送信息,重新连接----');
socket.send('hello')
}, 3000);
服务端代码
ws.on('message', (message) => {
wss.clients.forEach(client => {
if(client.readyState !== WebSocket.OPEN) return
if(message == 'hello') {
client.send('收到,hello')
}else {
client.send(`${ws.clientName == client.clientName ? '我' : ws.clientName}:${message}`)
}
})
})
- 方式二:捕获关闭连接事件并重连
socket.onclose = () => {
console.log('断开连接!');
// 方式一:
setTimeout(() => {
socket = new WebSocket(url); // 重新连接
}, 1000); // 1秒后重连
}
- 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>聊天室</h1>
<ul id="messages"></ul>
<input type="text" id="messageInput" autocomplete="off" />
<button id="sendBtn">发送</button>
<script>
const url = 'ws://localhost:5500'
const socket = new WebSocket(url)
// 方式二:
let timeoutObj = null;
// 开启心跳
const start = () => {
clearTimeout(timeoutObj);
// serverTimeoutObj && clearTimeout(serverTimeoutObj);
timeoutObj = setTimeout(() => {
console.log('发送信息,重新连接----');
socket.send('hello')
}, 3000);
};
const reset = () => {
// 重置心跳 清除时间
clearTimeout(timeoutObj);
// 重启心跳
start();
};
socket.onopen = () => {
console.log('连接成功!')
start(); // 开启心跳
};
socket.onclose = () => {
console.log('断开连接!');
// 方式一:
// setTimeout(() => {
// socket = new WebSocket(url); // 重新连接
// }, 1000); // 1秒后重连
}
socket.onerror = (err) => console.log('连接错误:'+err);
// 当收到服务器消息时触发
socket.onmessage = (e) => {
const { data } = e
if (data === '收到,hello') {
reset();
return;
}else {
const li = document.createElement('li')
li.textContent = data
document.getElementById('messages').appendChild(li)
}
}
const sendBtn = document.getElementById('sendBtn')
sendBtn.addEventListener('click', ()=> {
const msgInput = document.getElementById('messageInput')
const msg = msgInput.value;
if(msg) {
socket.send(msg)
msgInput.value = ''
}
})
</script>
</body>
</html>
3.成果展示
- 页面不刷新
- 页面刷新(心跳机制成果展示)
总结
以上就是今天要讲的内容,本文仅仅简单介绍了如何使用websocket实现一个简单聊天室的功能,欢迎各位大佬们多多指点。