封装后的websocket:
var webSocket = null;
var globalCallback = null;//定义外部接收数据的回调函数
// var lockReconnect = false; //避免ws重复连接
//心跳检测
// var heartCheck = {
// timeout: 5000, //1分钟发一次心跳
// timeoutObj: null,
// serverTimeoutObj: null,
// reset: function(){
// clearTimeout(this.timeoutObj);
// clearTimeout(this.serverTimeoutObj);
// return this;
// },
// start: function(){
// var self = this;
// this.timeoutObj = setTimeout(function(){
// //这里发送一个心跳,后端收到后,返回一个心跳消息,
// //onmessage拿到返回的心跳就说明连接正常
// webSocket.send("ping");
// console.log("ping!")
// self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
// webSocket.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
// }, self.timeout)
// }, this.timeout)
// }
// };
// function reconnect(url) {
// if(lockReconnect) return;
// lockReconnect = true;
// setTimeout(function () {//没连接上会一直重连,设置延迟避免请求过多
// initWebSocket(url);
// lockReconnect = false;
// }, 5000);
// }
//初始化websocket
function initWebSocket(url) {
if ("WebSocket" in window) {
webSocket = new WebSocket(url);//创建socket对象
console.log(webSocket);
} else {
alert("该浏览器不支持websocket!");
}
//打开
webSocket.onopen = function() {
// heartCheck.reset().start();//心跳检测重置
webSocketOpen();
};
//收信
webSocket.onmessage = function(e) {
// heartCheck.reset().start();//拿到任何消息都说明当前连接是正常的
console.log("收到消息啦:" + e.data);
// if(e.data!='pong'){
// let data = JSON.parse(e.data);
// }
webSocketOnMessage(e);
};
//关闭
webSocket.onclose = function(e) {
// reconnect(wsUrl);
// reconnect(url);
webSocketClose(e);
};
//连接发生错误的回调方法
webSocket.onerror = function() {
// reconnect(wsUrl);
// reconnect(url);
console.log("WebSocket连接发生错误");
};
}
//连接socket建立时触发
function webSocketOpen() {
//在此次定义好需要传过去的数据,先发送一个数据过去,data为与后端协议的数据类型
const data = {
type: "CONNECT",
// token: sessionStorage.getItem("token") || ""
token: localStorage.getItem("token") || ""
};
sendSock(data, function() {});//调用发送数据的函数
console.log("WebSocket连接成功");
}
//客户端接收服务端数据时触发,e为接受的数据对象
function webSocketOnMessage(e) {
// const data = JSON.parse(e.data);//根据自己的需要对接收到的数据进行格式化
const data = e.data;
console.log("e.dataaaaa", data);
globalCallback(data);//将data传给在外定义的接收数据的函数,至关重要。
/*在此函数中还可以继续根据项目需求来写其他东西。 比如项目里需要根据接收的数据来判断用户登录是否失效了,此时需要关闭此连接,跳转到登录页去。*/
}
//发送数据
function webSocketSend(data) {
console.log("e.data>>>", data);
// setTimeout(() => {
// webSocket.send(JSON.stringify(data));
// }, 1000);
webSocket.send(JSON.stringify(data));//在这里根据自己的需要转换数据格式
// webSocket.send(data);//在这里根据自己的需要转换数据格式
}
//关闭socket
function webSocketClose(e) {
// CloseEvent.code: code是错误码,是整数类型
// CloseEvent.reason: reason是断开原因,是字符串
// CloseEvent.wasClean: wasClean表示是否正常断开,是布尔值。一般异常断开时,该值为false
console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)//打印断开原因
console.log(123,e)//打印断开原因
setTimeout(() => {
initWebSocket(e.currentTarget.url);
}, 1000);
//建立了多个socket,就做了一些判断。
// if (
// webSocket.readyState === 1 &&
// webSocket.url === "ws://1xx.xx.xx.xxx:8088/ws"
// ) {
// webSocket.close();//这句话是关键,一直没有真正的关闭socket
// console.log("对话连接已关闭");
// }
}
//在其他需要socket地方调用的函数,用来发送数据及接受数据
function sendSock(sendData,callback) {
// console.log("sendData>>>",sendData);
// console.log("callback>>>",callback);
// debugger;
globalCallback = callback;//此callback为在其他地方调用时定义的接收socket数据的函数,此关重要。
//此处先判断socket连接状态
//下面的判断主要是考虑到socket连接可能中断或者其他的因素,可以重新发送此条消息。
switch (webSocket.readyState) {
//CONNECTING:值为0,表示正在连接。
case webSocket.CONNECTING:
setTimeout(function() {
webSocketSend(sendData,callback);
// console.log("sendData",sendData);
// console.log("callback",callback);
}, 1000);
break;
//OPEN:值为1,表示连接成功,可以通信了。
case webSocket.OPEN:
webSocketSend(sendData);
// console.log("sendData1",sendData);
// console.log("callback1",callback);
break;
//CLOSING:值为2,表示连接正在关闭。
case webSocket.CLOSING:
setTimeout(function() {
webSocketSend(sendData,callback);
// console.log("sendData2",sendData);
// console.log("callback2",callback);
}, 1000);
break;
//CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
case webSocket.CLOSED:
setTimeout(function() {
initWebSocket(sendData,callback);
// console.log("sendData3",sendData);
}, 1000);
// do something
break;
default:
// this never happens
break;
}
}
//将初始化socket函数、发送(接收)数据的函数、关闭连接的函数export出去
export default {
initWebSocket,
webSocketClose,
sendSock,
};
在其他组件中调用:
export default {
name: "eveAlarmBox",
data() {
return {
depId: '', //部门id
wsUrl: "ws://217.177.257.301:10211?type=alarm:00&depId=",
wsType: "CONNECT",
tableData: [],
};
},
created(){
//获取用户登录的部门id
let userInfo = localStorage.getItem('userInfo');
this.depId = JSON.parse(userInfo).depid;
this.socketApi.initWebSocket(this.wsUrl + this.depId);
//data为和后端商量好的数据格式
const data = {
type: this.wsType,
msg: "心跳内容",
};
setTimeout(()=>{
this.websocketSend(data);
},1000);
},
methods:{
// 接收socket回调函数返回数据的方法,服务端返回的数据
getConfigResult(res) {
this.tableData.push(JSON.parse(res));
},
websocketSend(data) {
//data为要发送的数据,this.getConfigResult为回调函数,用于在此页面接收socket返回的数据。
this.socketApi.sendSock(data,this.getConfigResult);
},
},
// beforeRouteLeave(to, from, next) {
// //在离开此页面的时候主动关闭socket
// this.socketApi.webSocketClose();
// next();
// },
};
问题:为什么这个websocket会一分钟就断掉,是前端问题还是后端问题?注释掉的那个心跳代码感觉像是死循环,不太对;
需求:断掉后会重连,是要写心跳吗,怎么写这个心跳?请各位前端大佬帮帮忙
两个问题
你可以连我的websocket服务器测试呀。