前言
封裝websocket 實(shí)現(xiàn)斷線重連跟心態(tài)檢測(cè),使用的typeScript去封裝
一、服務(wù)端實(shí)現(xiàn)ws
在nodejs 安裝ws庫(kù)
1.引入庫(kù)
代碼如下(示例):
npm i ws
?服務(wù)端實(shí)現(xiàn)ws 創(chuàng)建一個(gè)server.js 文件 運(yùn)行ws服務(wù) ? node .\server.js?
// 引入模塊
const WebSocket = require("ws").Server;
const port = 3001;
// 創(chuàng)建服務(wù)器
const server = new WebSocket({ port }, () => {
console.log("websocket服務(wù)開啟");
});
const connectHandler = (ws) => {
console.log("客戶端連接");
// 監(jiān)聽客戶端出錯(cuò)
ws.on("error", errorHandler);
// 監(jiān)聽客戶端斷開鏈接
ws.on("close", closeHandler);
// 監(jiān)聽客戶端發(fā)來(lái)的消息
ws.on("message", messageHandler);
};
// 監(jiān)聽接收客戶端信息回調(diào)
// 注意:因?yàn)檫@里用到this的指向,因此用普通的函數(shù)
function messageHandler(data) {
console.log("messageHandler===>接收客戶端消息", JSON.parse(data));
const { ModeCode } = JSON.parse(data);
switch (ModeCode) {
case "message":
console.log("收到消息");
// 需要發(fā)送信息給客戶端以此說明連接成功
this.send(JSON.stringify(JSON.parse(data)));
break;
case "heart_beat":
console.log("心跳檢測(cè)");
// 需要發(fā)送信息給客戶端以此說明連接成功
this.send(JSON.stringify(JSON.parse(data)));
break;
}
}
// 監(jiān)聽客戶端出錯(cuò)回調(diào)
const errorHandler = (error) => {
console.log("errorHandler===>客戶端出錯(cuò)", error);
};
// 監(jiān)聽客戶端斷開連接回調(diào)
const closeHandler = (e) => {
console.log("closeHandler===>客戶端斷開??", e);
};
// 建立連接
server.on("connection", connectHandler);
客戶端實(shí)現(xiàn)websocket
創(chuàng)建一個(gè)socket.ts 文件
class Socket {
wsUrl;
constructor(wsUrl: any) {
this.wsUrl = wsUrl;
}
ModeCode = {
// websocket消息類型
MSG: "message", // 普通消息
HEART_BEAT: "heart_beat" // 心跳
};
ws: any = null;
webSocketState: boolean = false; // webSocket的連接狀態(tài)
heartBeat = {
// 心跳連接的時(shí)間設(shè)置
time: 5 * 1000, // 心跳時(shí)間間隔
timeout: 3 * 1000, // timeout:心跳超時(shí)間隔
reconnect: 10 * 1000 // 斷線重連時(shí)間
};
reconnectTimer: any = null; // 斷線重連時(shí)間器
/**
* 連接ws
*/
connectWebSocket() {
this.ws = new WebSocket(this.wsUrl);
this.init();
}
/*
* 心跳初始函數(shù)
* @param time:心跳時(shí)間間隔
*/
startHeartBeat(time: Number | string) {
setTimeout(() => {
this.ws.send(
JSON.stringify({
ModeCode: this.ModeCode.HEART_BEAT,
msg: new Date()
})
);
this.waitingServer();
}, time as any);
}
// 延時(shí)等待服務(wù)端響應(yīng),通過webSocketState判斷是否連線成功
waitingServer() {
this.webSocketState = false;
setTimeout(() => {
if (this.webSocketState) {
this.startHeartBeat(this.heartBeat.time);
return;
}
console.log("心跳無(wú)響應(yīng),已斷線");
try {
this.ws.close();
} catch (e) {
console.log("連接已關(guān)閉,無(wú)需關(guān)閉");
}
this.reconnectWebSocket();
}, this.heartBeat.timeout);
}
// 重連操作
reconnectWebSocket() {
this.reconnectTimer = setTimeout(() => {
this.reconnectWs();
}, this.heartBeat.reconnect);
}
//初始化
init() {
this.ws.addEventListener("open", () => {
this.webSocketState = true; //socket狀態(tài)設(shè)置為連接,做為后面的斷線重連的攔截器
this.heartBeat && this.heartBeat.time ? this.startHeartBeat(this.heartBeat.time) : ""; // 是否啟動(dòng)心跳機(jī)制
console.log("開啟");
});
this.ws.addEventListener("message", (e: any) => {
console.log(e.data, "eeeee");
const data = JSON.parse(e.data);
switch (data.ModeCode) {
case this.ModeCode.MSG: // 普通消息
console.log("收到消息" + data.msg);
break;
case this.ModeCode.HEART_BEAT: // 心跳
this.webSocketState = true;
console.log("收到心跳響應(yīng)" + data.msg);
break;
}
});
this.ws.addEventListener("close", (e: any) => {
this.webSocketState = false; // socket狀態(tài)設(shè)置為斷線
console.log("斷開了連接", e);
});
this.ws.addEventListener("error", (e: any) => {
this.webSocketState = false; // socket狀態(tài)設(shè)置為斷線
this.reconnectWebSocket(); // 重連
console.log("連接發(fā)生了錯(cuò)誤", e);
});
}
reconnectWs() {
if (!this.ws) {
// 第一次執(zhí)行,初始化
this.connectWebSocket();
}
if (this.ws && this.reconnectTimer) {
// 防止多個(gè)websocket同時(shí)執(zhí)行
clearTimeout(this.reconnectTimer);
this.ws.reconnectTimer = null;
this.connectWebSocket();
}
}
//發(fā)送數(shù)據(jù)
sendMessage(data: any) {
this.ws.send(JSON.stringify(data));
}
//在其他需要socket地方主動(dòng)關(guān)閉socket
closeWebSocket(e: any) {
console.log(e);
this.ws.close();
clearTimeout(this.reconnectTimer);
this.webSocketState = false;
}
}
export default Socket;
vue 頁(yè)面使用
//引用
import Scoket from "@/utils/socket";
const socket = new Scoket("ws://localhost:3001");
//發(fā)送消息
const onSend = () => {
console.log("onSend");
socket.sendMessage(message.value);
};
//連接ws
onMounted(() => {
socket.connectWebSocket();
});
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-805037.html
斷開ws服務(wù) 斷線? 啟動(dòng)服務(wù)后 自動(dòng)重連文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-805037.html
到了這里,關(guān)于websocket斷線重連&&心跳檢測(cè)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!