263 lines
7.2 KiB
JavaScript
263 lines
7.2 KiB
JavaScript
import base from "@/common/config/domain.js"
|
||
class websocketUtil {
|
||
constructor(token, time) {
|
||
this.token = token;
|
||
this.is_open_socket = false; //避免重复连接
|
||
// this.url = url; //地址
|
||
// this.data = null;
|
||
this.reconnect_time=6000;//意外断开超过多少秒重连
|
||
//心跳检测
|
||
this.timeout = time; //多少秒执行检测
|
||
this.sendheartInterval = null; //心跳发送计时器
|
||
this.reconnectTimeOut = null; //重连之后多久再次重连计时器
|
||
this.onHeartInterval = null; //心跳检测计时器
|
||
this.heart_nownum=0;//心跳最新
|
||
this.heart_oldnum=0;//上次心跳
|
||
this.offline_time=0;//断开的毫秒数
|
||
this.need_reconnect=false;//监听到关闭后,是否需要重连
|
||
this.ac_close=false;//是否主动关闭 如果是主动断开不会自动重连,需要手动调用connectSocketInit
|
||
this.is_reconnect=false;//是否正在重连
|
||
|
||
try {
|
||
return this.connectSocketInit();
|
||
} catch (e) {
|
||
// console.log("catch");
|
||
this.is_open_socket = false;
|
||
this.socketReconnect();
|
||
}
|
||
}
|
||
|
||
// 初始化websocket链接
|
||
connectSocketInit() {
|
||
this.heart_nownum=0;//心跳最新
|
||
this.heart_oldnum=0;//上次心跳
|
||
this.offline_time=0;
|
||
// console.log("this.sendheartInterval",this.sendheartInterval);
|
||
|
||
if(this.reconnectTimeOut){
|
||
clearTimeout(this.reconnectTimeOut);
|
||
this.reconnectTimeOut=null;
|
||
}
|
||
//停止发送心跳
|
||
if(this.sendheartInterval){
|
||
clearInterval(this.sendheartInterval);
|
||
this.sendheartInterval=null;
|
||
}
|
||
//停止监听心跳
|
||
if(this.onHeartInterval){
|
||
clearInterval(this.onHeartInterval);
|
||
this.onHeartInterval=null;
|
||
}
|
||
|
||
if(this.socketTask){
|
||
this.socketTask=null;
|
||
}
|
||
let url = `${base.wsUrl}/websocket/socketServer.do?token=${this.token}`; //地址
|
||
// console.log("链接地址",url);
|
||
this.socketTask = uni.connectSocket({
|
||
url: url,
|
||
success: () => {
|
||
console.log("正准备建立websocket中...");
|
||
// uni.showLoading({
|
||
// title:"创建连接中..."
|
||
// })
|
||
// 返回实例
|
||
return this.socketTask;
|
||
},
|
||
fail:(res)=>{
|
||
console.log("创建websocket失败...",res);
|
||
}
|
||
});
|
||
this.socketTask.onOpen((res) => {
|
||
console.log("WebSocket连接成功!");
|
||
uni.hideLoading();
|
||
this.is_open_socket = true;
|
||
this.need_reconnect=false;//监听到关闭后,是否需要重连
|
||
this.ac_close=false;//是否主动关闭
|
||
this.is_reconnect = false;
|
||
//开始发送心跳
|
||
this.start();
|
||
// 开启检测心跳
|
||
this.onHeart();
|
||
|
||
//监听接受消息
|
||
this.socketTask.onMessage((res) => {
|
||
// console.log('websocket接受到的消息',res);
|
||
let dJson = res.data;
|
||
|
||
let data = JSON.parse(dJson);
|
||
// console.log('websocket接受res.data',data);
|
||
// data.msg = data.msg ? JSON.parse(data.msg) : data.msg;
|
||
data.msg = data.msg;
|
||
|
||
if(data.opt == 'HEALTH'){
|
||
//接受心跳
|
||
// console.log('接受心跳成功');
|
||
this.heart_nownum++;
|
||
}else{
|
||
// console.log("接受到的数据", data);
|
||
// 发射事件到页面
|
||
// console.log("data--------------",data,data.opt);
|
||
uni.$emit(data.opt, data.msg);
|
||
}
|
||
|
||
});
|
||
|
||
});
|
||
|
||
// 监听关闭链接
|
||
this.socketTask.onClose((res) => {
|
||
console.log("WebSocket关闭链接!",res);
|
||
this.is_reconnect = false;
|
||
|
||
//服务器重启导致websocket关闭
|
||
this.socketTask=null;
|
||
// if(!this.ac_close || this.need_reconnect){
|
||
// //监听到不是主动断开 或者 需要主动重连的
|
||
// this.is_open_socket = false;
|
||
// this.socketReconnect();
|
||
// }
|
||
|
||
});
|
||
//监听链接错误
|
||
this.socketTask.onError((err) => {
|
||
console.log("WebSocket错误!",err);
|
||
// console.log("this.ac_close",this.ac_close);
|
||
// console.log("this.need_reconnect",this.need_reconnect);
|
||
|
||
if(!this.ac_close || this.need_reconnect){
|
||
//监听到不是主动断开 或者 需要主动重连的
|
||
this.is_open_socket = false;
|
||
this.is_reconnect = false;
|
||
this.socketReconnect();
|
||
}
|
||
});
|
||
}
|
||
|
||
//发送消息
|
||
send(value) {
|
||
// console.log("value",value);
|
||
// 注:只有连接正常打开中 ,才能正常成功发送消息
|
||
this.socketTask.send({
|
||
data: value,
|
||
success:(res)=> {
|
||
// console.log("消息发送成功",res);
|
||
},
|
||
fail:(res)=>{
|
||
// console.log("消息发送失败",res);
|
||
}
|
||
|
||
});
|
||
}
|
||
//重新连接
|
||
socketReconnect() {
|
||
if(this.is_reconnect || this.is_open_socket) return;//正在重连 或者已连接 截断
|
||
this.is_reconnect=true;
|
||
this.ac_close=false;//重置是否主动断开,方便重连后判断
|
||
// console.log("开始重连")
|
||
// console.log('is_open_socket',this.is_open_socket);
|
||
//停止发送心跳
|
||
if(this.sendheartInterval){
|
||
clearInterval(this.sendheartInterval);
|
||
this.sendheartInterval=null;
|
||
}
|
||
//停止监听心跳
|
||
if(this.onHeartInterval){
|
||
clearInterval(this.onHeartInterval);
|
||
this.onHeartInterval=null;
|
||
}
|
||
//链接是关闭状态下
|
||
if (!this.is_open_socket) {
|
||
// uni.showLoading({
|
||
// title:"重接中..."
|
||
// })
|
||
this.reconnectTimeOut = setTimeout(() => {
|
||
this.connectSocketInit();
|
||
}, 1000);
|
||
}
|
||
}
|
||
//关闭websocket
|
||
close(ac_close=true){
|
||
if(!this.is_open_socket) return;//链接未链接成功下,不能主动关闭
|
||
// console.log("主动断开")
|
||
//停止发送心跳
|
||
if(this.sendheartInterval){
|
||
clearInterval(this.sendheartInterval);
|
||
this.sendheartInterval=null;
|
||
}
|
||
//停止监听心跳
|
||
if(this.onHeartInterval){
|
||
clearInterval(this.onHeartInterval);
|
||
this.sendheartInterval=null;
|
||
}
|
||
//是否主动断开
|
||
this.ac_close=ac_close;
|
||
// console.log("主动关闭",this.ac_close)
|
||
if(this.socketTask){
|
||
this.socketTask.close({
|
||
success:(res)=>{
|
||
console.log('主动关闭返回1',res)
|
||
this.is_open_socket = false;
|
||
if(!this.ac_close || this.need_reconnect){
|
||
// console.log("主动关闭")
|
||
//监听到不是主动断开 或者 需要主动重连的
|
||
this.socketReconnect();
|
||
}
|
||
},
|
||
fail:(res)=>{
|
||
// console.log('主动关闭返回2')
|
||
}
|
||
});
|
||
}else{
|
||
//服务器关闭导致没有websocket
|
||
this.reconnectTimeOut = setTimeout(() => {
|
||
this.connectSocketInit();
|
||
}, 1000);
|
||
}
|
||
}
|
||
//开启心跳检测
|
||
start() {
|
||
this.sendheartInterval = setInterval(() => {
|
||
// let data = { healthCheck:'Y'};
|
||
let data = {
|
||
"opt":"HEALTH",
|
||
"msg":{"healthCheck":"Y"}
|
||
};
|
||
|
||
// console.log(this.data);
|
||
// console.log('发送心跳');
|
||
this.send(JSON.stringify(data));
|
||
}, this.timeout);
|
||
}
|
||
//监听心跳
|
||
onHeart(){
|
||
this.onHeartInterval = setInterval(() => {
|
||
if(this.heart_nownum>this.heart_oldnum){
|
||
// console.log("websocket正常",this.heart_nownum,this.heart_oldnum);
|
||
//正常连接中
|
||
this.heart_oldnum=this.heart_nownum;
|
||
// console.log("websocket正常",this.heart_oldnum);
|
||
|
||
|
||
// //测试
|
||
// if(this.heart_oldnum>5){
|
||
// this.close();
|
||
// }
|
||
}else{
|
||
console.log("心跳检测到websocket断开",this.heart_nownum,this.heart_oldnum);
|
||
this.offline_time+=this.timeout*2;
|
||
|
||
if(this.offline_time>=this.reconnect_time){
|
||
//开始重连
|
||
// console.log("需要重连-------");
|
||
this.need_reconnect=true;
|
||
this.close(false);
|
||
// this.socketReconnect();
|
||
}
|
||
}
|
||
}, this.timeout*2);
|
||
}
|
||
}
|
||
|
||
module.exports = websocketUtil;
|