WebSocket 心跳检测、重连、订阅、退订、消息发送
Client,js
class WsClient {
constructor(url) {
// this.client=new WebSocket(url);
this.url = url;
this.isAlive = true;
this.ping = null;
this.heartbeatTimeout = null;
this.callbackMap = new Map();
this.connect();
}
// 连接
connect() {
this.client = new WebSocket(this.url);
this.client.onopen = (e) => {
// console.log('onopen')
this.heartbeat();
};
this.client.onmessage = (e) => {
// console.log('onmessage',e.data)
this.handleMessage(JSON.parse(e.data));
};
this.client.onerror = (e) => {
// console.log('onerror')
this.reconnect();
};
this.client.onclose = (e) => {
// console.log('onclose')
this.reconnect();
};
}
// 重连
reconnect() {
this.isAlive = false;
clearTimeout(this.heartbeatTimeout);
this.heartbeatTimeout = setTimeout(() => {
if (this.isAlive === false) {
this.client.close();
this.connect();
}
}, 20000 + 2000);
}
// 心跳检测
heartbeat() {
this.isAlive = true;
clearInterval(this.ping);
this.ping = setInterval(() => {
if(this.isAlive){
this.client.send(JSON.stringify({ type: "ping" }));
}
}, 30000);
}
// 发送消息
sendMessage(mesg) {
if (this.client && this.client.readyState === 1) {
this.client.send(mesg);
} else {
// webscoekt 连接尚未建立
setTimeout(() => {
this.sendMessage(mesg);
}, 1000);
}
}
// 订阅
subscribe(topic, callback) {
let calls = this.callbackMap.get(topic) || [];
calls.push(callback);
this.callbackMap.set(topic, calls);
// console.log("subscribe",topic,callback,calls);
}
// 退订
unSubscribe(topic, callback) {
let calls = this.callbackMap.get(topic) || [];
if (calls.length === 0) {
this.callbackMap.delete(topic);
} else {
calls = calls.filter((c) => {
return c != callback;
});
this.callbackMap.set(topic, calls);
}
// console.log("unSubscribe",topic,callback,calls);
}
// 处理 message
handleMessage(mesg) {
let { topic, data } = mesg;
if (topic) {
let calls = this.callbackMap.get(topic) || [];
// console.log(topic,data,calls);
calls.forEach((c) => {
c(data);
});
} else {
console.error(mesg);
}
}
}
let client = new WsClient("ws://localhost:18088");
let testCallback = (data) => {
console.log(data);
};
client.subscribe("test", testCallback);
client.unSubscribe("test", testCallback);
Server.js
const { WebSocketServer } =require('ws');
const wss = new WebSocketServer({ host:'0.0.0.0',port: 18088 });
wss.on('connection', function connection(ws) {
ws.on('message', function message(data) {
console.log('received: %s', data);
});
// ws.send('something');
console.log('connection');
});
setInterval(()=>{
wss.clients.forEach(c=>{
let data=JSON.stringify({
topic:'test',
data:{
name:"jiachao",
}
})
c.send(data);
})
},3000)
// console.log(wss);
本文作者:qfluck
本文链接:https://www.cnblogs.com/qfluck/p/16696588.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步