HTML5 WebSocket
WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
1.背景
在项目中需要实时收到推送的消息,就使用了websocket作为通信。
2.实现
1⃣️首先实现基础的websocket功能:
terminal() {
const envId = this.$route.params.envId;
const url = "连接的url";
this.socket(url);
},
socket(linkpath) {
const _self = this;
const ws = new WebSocket(linkpath);
ws.onerror = function() {
_self.$message.error(" 连接错误");
};
ws.onmessage = function(event) {
_self.message = _self.message + "<br>" + event.data;
};
ws.onopen = function() {
_self.message = "";
console.log("ws onopen ");
};
ws.onclose = function() {
// _self.$message.warning("连接已关闭 请重新打开");
console.log("ws close ");
};
},
2⃣️对于项目并不是只有一处使用websocket,这个时候就需要把方法抽离出来
/**
* 连接webSockect
* @param wsUrl: 连接地址
* callBack: 接收数据的函数
*/
export const connectWebSocket = (wsUrl, callBack) => {
const _self = this;
const ws = new WebSocket(wsUrl);
ws.onerror = function() {
connectWebSocket(wsUrl, callBack);
_self.$message.error(" 连接错误");
};
ws.onmessage = function(event) {
console.log(1111, event);
callBack();
};
ws.onopen = function() {
Constant.requireWebSocketCount = 0;
console.log("ws onopen");
};
ws.onclose = function() {
reconnect(wsUrl, callBack, 5, 1000);
// _self.$message.warning("连接已关闭 请重新打开");
console.log("ws close ");
};
};
好了,总算可以用了,在需要使用websocket的地方,直接调用connectWebSocket事件,只需要传入连接地址和接收数据的函数即可,因为我个项目不需要发送,所以只封装了接收函数。
但是问题来了,总是时不时的断开,然后就不能接收数据了,现在想实现断开之后自动重连,也算是实现长连接了。
3⃣️实现断开重连
网上也会有一些实现断开重连的第三方库,但是好像对vue都不是很友好,而恰恰我的项目就是vue的,只能自己手动封装一个了。
// import Constant from "./constant";
/**
* 连接webSockect
* @param wsUrl: 连接地址
* callBack: 接收数据的函数
*/
let requireWebSocketCount = 0;
export const connectWebSocket = (wsUrl, callBack = null) => {
let ws = null;
ws && ws.close();
ws = new WebSocket(wsUrl);
// Constant.requireWebSocketCount = 0;
ws.onerror = function() {
// connectWebSocket(wsUrl, callBack);
// console.log(" ws error");
};
ws.onmessage = function() {
// console.log(1111, event);
callBack && callBack();
};
ws.onopen = function() {
// console.log("ws onopen");
};
ws.onclose = function() {
reconnect(wsUrl, callBack);
// console.log("ws close ");
};
return ws;
};
/**
* 重接webSockect
* @param
* wsUrl: 连接地址
* callBack: 接收数据的函数
* reconnectDecay: 重连次数(断开连接时,尝试重连次数),整型(integer),默认5
* timeoutInterval: 连接延时 毫秒数,默认3秒
*/
export const reconnect = (wsUrl, callBack, reconnectDecay, timeoutInterval) => {
const count = !reconnectDecay ? 5 : reconnectDecay;
const timeOut = !timeoutInterval ? 3000 : timeoutInterval;
requireWebSocketCount += 1;
let requireWebSocket = "";
// console.log(requireWebSocketCount);
// console.log(requireWebSocketCount, count);
if (requireWebSocketCount < count) {
connectWebSocket(wsUrl, callBack);
requireWebSocket = setTimeout(() => {
// console.log("我执行了重启");
connectWebSocket(wsUrl, callBack);
clearTimeout(requireWebSocket);
}, timeOut);
} else {
// console.log(requireWebSocketCount);
// console.log("我已经重启五次了,不会再重启了");
}
};
export default {
connectWebSocket,
reconnect,
};
再次尝试,可以了,总算可以简单的实现websocket连接了,可以使用了,不知道还会不会出现一些其他bug,目前来说基本功能是有了。