由于业务场景需要 写了个websocket
主要思想 :
处理websocket 在https 环境下需要心跳来维持的问题 ;
以及在默写特殊情况下 发错参数自动断开重连处理
和 生命周期结束或者需要自动销毁的处理
使用了class 进行编写业务场景需要的websocket;
import { baseWsUrl, baseWsUrl2 } from "./config";
export class UseWebsocket {
constructor(
url = null,
ws = null,
reconnect_current = 0,
reconnect_timer = null,
socket_open = false,
hearbeat_timer = null,
is_reonnect = true
) {
// 存储webSocket实例对象
this.ws = ws;
this.url = baseWsUrl+ url;
// 测试路径而已 正常用上面那条
// this.url = baseWsUrl2 ;
// 重连次数 我习惯设置3次
this.reconnect_count = 3;
// 当前重连次数
this.reconnect_current = reconnect_current;
// 是否自动重连
this.is_reonnect = is_reonnect;
// 开启标识
this.socket_open = socket_open;
// 心跳timer
this.hearbeat_timer = hearbeat_timer;
// 心跳发送频率
this.hearbeat_interval = 5000;
// 重连timer
this.reconnect_timer = reconnect_timer;
// 重连频率
this.reconnect_interval = 3000;
}
initSocket() {
if (!("WebSocket" in window)) {
console.log("浏览器不支持WebSocket");
return null;
}
if (this.ws) {
return this.ws;
}
console.log("执行前查看地址===>", this, this.url);
this.ws = new WebSocket(this.url);
this.ws.onclose = (e) => {
console.log("webSocket close 连接已断开", e, this);
// 当连接断开的时候 其实就是webSocket 报错的时候 就可以去掉心跳的timer拉 并且修改标识
clearInterval(this.hearbeat_timer);
this.socket_open = false;
if (this.is_reonnect) {
let _this = this;
this.reconnect_timer = setInterval(() => {
// console.log("执行重连222", _this, _this.reconnect_current);
// 超过重连次数 清除定时器timer 不在进行重连
if (_this.reconnect_current > _this.reconnect_count) {
clearInterval(_this.reconnect_timer);
// 释放对象
_this.ws = null;
return;
}
// 记录重连次数
_this.reconnect_current++;
_this.reconnect();
}, this.reconnect_interval);
}
};
this.ws.onmessage = (e, callback = null) => {
var params = JSON.parse(e.data);
console.log("webSocket message", params);
if (callback) {
callback(params);
}
};
this.ws.onopen = (e) => {
console.log(
"webSocket open 连接成功",
e,
this.reconnect_current,
this.ws
);
// 给服务端发送连接成功标识固定信息 看业务场景需要来定义
if (this.reconnect_current == 0) {
let data = {
action: 1,
message: null,
receivers: [],
sender: "2c4a004330c74102a5c30fea0e769d93",
};
this.sendMsg(data);
}
clearInterval(this.reconnect_timer);
this.reconnect_current = 0;
this.socket_open = true;
this.is_reonnect = true;
this.heartbeat();
};
this.ws.onerror = (e) => {
console.log("webSocket error WebSocket连接发生错误", e);
};
}
// 发送消息 this.ws.readyState == this.ws.OPEN这些你们打印一下实例的对象就知道为啥这样判断了
sendMsg(data, callback = null) {
//已开启
if (this.ws.readyState == this.ws.OPEN) {
// console.log("执行发送", data);
this.ws.send(JSON.stringify(data));
if (callback) {
callback();
}
// 正在开启状态,则等待1s后重新调用
} else if (this.ws.readyState == this.ws.CONNECTING) {
setTimeout(function () {
this.ws.send(JSON.stringify(data), callback);
}, 1000);
// 未开启,则等待1s后重新调用
} else {
this.initSocket();
setTimeout(function () {
this.ws.send(JSON.stringify(data), callback);
}, 1000);
}
}
// 心跳
heartbeat() {
if (this.hearbeat_timer) {
clearInterval(this.hearbeat_timer);
}
let _this = this;
this.hearbeat_timer = setInterval(() => {
var data = {
kind: 0, //请求类型 kind 0 心跳包
kindString: "heartBeat",
};
// console.log("里面==》", _this, JSON.stringify(data));
_this.sendMsg(data);
}, this.hearbeat_interval);
}
// 重连
reconnect() {
// 状态标识判断
if (this.ws && this.socket_open) {
this.ws.close();
}
this.ws = null;
console.log("执行重连===>", this);
this.initSocket();
}
// 主动销毁
destory() {
clearInterval(this.hearbeat_interval);
this.is_reonnect = false;
this.ws.close();
// 释放对象
this.ws = null;
}
}
大体先这样拉 大佬们不想写可以直接用 部分稍微优化一下就好了 后期我也会补充优化版本