zlpt_app/common/websocket/websocket.js

263 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;