125 lines
3.7 KiB
JavaScript
125 lines
3.7 KiB
JavaScript
class WebSocketClass {
|
||
constructor() {
|
||
// 用来设计单例模式的
|
||
this.instance = null;
|
||
// 用来保存 new WebSocket 的实例
|
||
this.ws = null;
|
||
// close 关闭,open 打开
|
||
this.status = 'close';
|
||
// 发送的心跳数值 ping 询问后端,pong 后端的响应
|
||
this.pingPong = 'ping';
|
||
this.callMessage = {
|
||
// SocketSystem: () => {},
|
||
// SocketUser: () => {},
|
||
};
|
||
this.connect();
|
||
}
|
||
|
||
static getInstance() {
|
||
if (!this.instance) {
|
||
this.instance = new WebSocketClass();
|
||
}
|
||
return this.instance
|
||
}
|
||
|
||
connect() {
|
||
this.ws = new WebSocket(config.checkSocket());
|
||
this.ws.onopen = e => {
|
||
this.status = 'open';
|
||
console.log(`连接成功`);
|
||
this.heartCheck();
|
||
this.onClose();
|
||
this.getMessage();
|
||
};
|
||
}
|
||
|
||
heartCheck() {
|
||
this.pingPong = 'ping';
|
||
this.pingInterval = setInterval(() => {
|
||
if (this.ws.readyState === 1) {
|
||
this.send({
|
||
type: "SocketHealthy",
|
||
action: null,
|
||
data: "ping"
|
||
}) // 客户端发送ping
|
||
}
|
||
}, 5000);
|
||
|
||
this.pongInterval = setInterval(() => {
|
||
if (this.pingPong === 'ping') {
|
||
this.closeHandle('服务器没有返回pong,重启webSocket');
|
||
}
|
||
console.log('收到服务器的 pong');
|
||
this.pingPong = 'ping';
|
||
}, 10000);
|
||
}
|
||
|
||
closeHandle(e = 'err') {
|
||
console.log(e)
|
||
if (this.status !== 'close') {
|
||
if (this.pingInterval !== undefined && this.pongInterval !== undefined) {
|
||
clearInterval(this.pingInterval);
|
||
clearInterval(this.pongInterval);
|
||
}
|
||
this.connect();
|
||
} else {
|
||
console.log(`websocket手动关闭,或者正在连接`);
|
||
}
|
||
}
|
||
|
||
getMessage() {
|
||
this.ws.onmessage = e => {
|
||
var res = JSON.parse(e.data);
|
||
switch (res.type) {
|
||
case "SocketHealthy":
|
||
// console.log("前端 健康检查:", res.data)
|
||
this.pingPong = 'pong';
|
||
break;
|
||
case "SocketUser":
|
||
// console.log("前端 用户消息:", res.data);
|
||
if (res.action == "to") {
|
||
this.callMessage["to"](res.data);
|
||
return;
|
||
} else if (res.action == "list") {
|
||
this.callMessage["userList"](res.data);
|
||
} else {
|
||
this.callMessage["SocketUser"](res.data);
|
||
}
|
||
break;
|
||
case "SocketSystem":
|
||
// console.log("前端 系统消息:", res.data)
|
||
this.callMessage["SocketSystem"](res.data)
|
||
break;
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
send(mes = null, callback = null, type = null) {
|
||
if (mes == null) {
|
||
if (callback != null) {
|
||
this.callMessage[type] = callback
|
||
}
|
||
} else {
|
||
if (callback != null) {
|
||
this.callMessage[type] = callback
|
||
}
|
||
this.ws.send(JSON.stringify(mes))
|
||
}
|
||
}
|
||
|
||
onClose() {
|
||
this.ws.onclose = (evt) => {
|
||
console.log("链接关闭: ", evt);
|
||
};
|
||
}
|
||
|
||
close() {
|
||
clearInterval(this.pingInterval);
|
||
clearInterval(this.pongInterval);
|
||
this.status = 'close';
|
||
this.ws.send('close');
|
||
this.ws.close();
|
||
console.log('close');
|
||
}
|
||
} |