导航
WebSocket 是 HTML5 中的协议,支持持久连续,HTTP 协议不支持持久性连接。HTTP1.0 和 HTTP1.1 都不支持持久性的链接,HTTP1.1 中 的keep-alive,是将多个 HTTP 请求合并为 1 个
const ws = new WebSocket('ws:localhost:8000')
ws.addEventListener('open', handleOpen, false);
ws.addEventListener('close', handleClose, false);
ws.addEventListener('error', handleClose, false);
ws.addEventListener('message', handleMessage, false);
handleMessage(e) { const msgData = JSON.prase(e.data) }
ws.send(JSON.stringify({}));
const Ws = require('ws');
const server = new Ws.Server({ port: 8000 })
server.on('open', handleOpen);
server.on('close', handleClose);
server.on('error', handleError);
server.on('connection', handleConnection);
前端连接上来后:
handleConnection(ws) { ws.on('message', handleMessage) }
handleMessage(data, isBinary) { server.clients.forEach(c => c.send(data, { binary: isBinary }) ) }
npm install vite
package.json:
"scripts": {
"dev": "vite"
},
依赖一个库:
或者用原生的:
心跳
<html>
<head>
<meta charset="utf-8">
<title>WebSocket Demo</title>
</head>
<body>
<script type="text/javascript">
// var ws = new WebSocket("wss://echo.websocket.org");
/*
ws.onerror = function(e) {
console.log('已关闭');
};
ws.onopen = function(e) {
console.log('握手成功');
ws.send('123456789');
}
ws.onclose = function() {
console.log('已关闭');
}
ws.onmessage = function(e) {
console.log('收到消息');
console.log(e);
}
*/
var lockReconnect = false;//避免重复连接
var wsUrl = "wss://echo.websocket.org";
var ws;
var tt;
function createWebSocket() {
try {
ws = new WebSocket(wsUrl);
init();
} catch(e) {
console.log('catch');
reconnect(wsUrl);
}
}
function init() {
ws.onclose = function () {
console.log('链接关闭');
reconnect(wsUrl);
};
ws.onerror = function() {
console.log('发生异常了');
reconnect(wsUrl);
};
ws.onopen = function () {
//心跳检测重置
heartCheck.start();
};
ws.onmessage = function (event) {
//拿到任何消息都说明当前连接是正常的
console.log('接收到消息');
heartCheck.start();
}
}
function reconnect(url) {
if(lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 4000);
}
//心跳检测
var heartCheck = {
timeout: 3000,
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
console.log('start');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
console.log('55555');
ws.send("123456789");
self.serverTimeoutObj = setTimeout(function() {
console.log(111);
console.log(ws);
ws.close();
// createWebSocket();
}, self.timeout);
}, this.timeout)
}
}
createWebSocket(wsUrl);
</script>
</body>
</html>
https://www.cnblogs.com/tugenhua0707/p/8648044.html
// WebSocketService.js
class WebSocketService {
constructor(url) {
this.url = url; // WebSocket 的 URL
this.socket = null; // WebSocket 实例
this.heartbeatInterval = 30000; // 心跳间隔时间(30秒)
this.timeout = 10000; // 心跳超时时间(10秒)
this.heartbeatTimeout = null; // 心跳超时 ID
this.heartbeatPing = null; // 心跳定时器 ID
}
// 连接 WebSocket
connect() {
this.socket = new WebSocket(this.url); // 创建 WebSocket 实例
// 连接成功时的回调
this.socket.onopen = () => {
console.log('WebSocket connection established.');
this.startHeartbeat(); // 开始心跳检测
};
// 接收到消息时的回调
this.socket.onmessage = (event) => {
console.log('Message from server:', event.data);
this.resetHeartbeat(); // 重置心跳检测
};
// 连接关闭时的回调
this.socket.onclose = () => {
console.log('WebSocket connection closed. Reconnecting...');
this.reconnect(); // 尝试重连
};
// 发生错误时的回调
this.socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
}
// 开始心跳检测
startHeartbeat() {
this.heartbeatPing = setInterval(() => {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify({ type: 'ping' })); // 发送 ping 消息
this.setHeartbeatTimeout(); // 设置心跳超时
}
}, this.heartbeatInterval); // 每隔一定时间发送一次
}
// 设置心跳超时
setHeartbeatTimeout() {
clearTimeout(this.heartbeatTimeout); // 清除上一个超时计时器
this.heartbeatTimeout = setTimeout(() => {
console.warn('Heartbeat timeout. Closing WebSocket.');
this.socket.close(); // 关闭连接
}, this.timeout); // 超过时间未收到响应则关闭
}
// 重置心跳检测
resetHeartbeat() {
clearTimeout(this.heartbeatTimeout); // 清除超时计时器
this.setHeartbeatTimeout(); // 重新设置超时计时器
}
// 重连机制
reconnect() {
clearInterval(this.heartbeatPing); // 清除心跳定时器
setTimeout(() => {
this.connect(); // 尝试重新连接
}, 5000); // 5秒后重连
}
// 发送消息
send(message) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(message); // 发送消息
}
}
// 关闭 WebSocket
close() {
clearInterval(this.heartbeatPing); // 清除心跳定时器
clearTimeout(this.heartbeatTimeout); // 清除超时计时器
if (this.socket) {
this.socket.close(); // 关闭 WebSocket 连接
}
}
}
export default WebSocketService;