小程序版:
// socket已经连接成功
var socketOpen = false
// socket已经调用关闭function
var socketClose = false
// socket发送的消息队列
var socketMsgQueue = []
// 判断心跳变量
var heart = ''
// 心跳失败次数
var heartBeatFailCount = 0
// 终止心跳
var heartBeatTimeOut = null;
// 终止重新连接
var connectSocketTimeOut = null;
// 心跳信息
var connectFailTimes = 0
var webSocket = {
/**
* 创建一个 WebSocket 连接
* @param {options}
* url String 是 开发者服务器接口地址,必须是 wss 协议,且域名必须是后台配置的合法域名
* header Object 否 HTTP Header , header 中不能设置 Referer
* method String 否 默认是GET,有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
* protocols StringArray 否 子协议数组 1.4.0
* success Function 否 接口调用成功的回调函数
* fail Function 否 接口调用失败的回调函数
* complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行)
*/
connectSocket: function(options) {
wx.showLoading({
title: '',
mask: true,
})
socketOpen = false
socketClose = false
this.webSocketClose = false
socketMsgQueue = []
wx.connectSocket({
url: 'wss://aqm.runde.pro/wss',
success: function(res) {
if (options) {
// 成功回调
options.success && options.success(res);
}
},
fail: function(res) {
if (options) {
// 失败回调
options.fail && options.fail(res);
}
}
})
},
/**
* 通过 WebSocket 连接发送数据
* @param {options}
* data String / ArrayBuffer 是 需要发送的内容
* success Function 否 接口调用成功的回调函数
* fail Function 否 接口调用失败的回调函数
* complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行)
*/
sendSocketMessage: function(options) {
if (socketOpen) {
wx.sendSocketMessage({
data: options.msg,
// data: JSON.stringify(options),
success: function(res) {
if (options) {
options.success && options.success(res);
}
},
fail: function(res) {
if (options) {
options.fail && options.fail(res);
}
}
})
} else {
socketMsgQueue.push(options)
}
},
/**
* 关闭 WebSocket 连接。
* @param {options}
* code Number 否 一个数字值表示关闭连接的状态号,表示连接被关闭的原因。如果这个参数没有被指定,默认的取值是1000 (表示正常连接关闭)
* reason String 否 一个可读的字符串,表示连接被关闭的原因。这个字符串必须是不长于123字节的UTF-8 文本(不是字符)
* fail Function 否 接口调用失败的回调函数
* complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行)
*/
closeSocket: function(options) {
if (connectSocketTimeOut) {
clearTimeout(connectSocketTimeOut);
connectSocketTimeOut = null;
}
socketClose = true;
var self = this;
self.stopHeartBeat();
wx.closeSocket({
success: function(res) {
console.log('WebSocket 已关闭!');
if (options) {
options.success && options.success(res);
}
},
fail: function(res) {
if (options) {
options.fail && options.fail(res);
}
}
})
},
// 收到消息回调
onSocketMessageCallback: function(msg) {
},
// 开始心跳
startHeartBeat: function() {
console.log('socket开始心跳')
var self = this;
heart = 'heart';
self.heartBeat();
},
// 结束心跳
stopHeartBeat: function() {
console.log('socket结束心跳')
var self = this;
heart = '';
if (heartBeatTimeOut) {
clearTimeout(heartBeatTimeOut);
heartBeatTimeOut = null;
}
if (connectSocketTimeOut) {
clearTimeout(connectSocketTimeOut);
connectSocketTimeOut = null;
}
},
// 心跳
heartBeat: function() {
var self = this;
if (!heart) {
return;
}
self.sendSocketMessage({
// msg: JSON.stringify({
// 'msg_type': 'heart'
// }),
msg: JSON.stringify({
"act": "app_heartbeat"
}),
success: function(res) {
console.log('socket心跳成功');
if (heart) {
heartBeatTimeOut = setTimeout(() => {
self.heartBeat();
}, 7 * 1000);
}
},
fail: function(res) {
console.log('socket心跳失败');
if (heartBeatFailCount > 2) {
// 重连
self.connectSocket();
}
if (heart) {
heartBeatTimeOut = setTimeout(() => {
self.heartBeat();
}, 7 * 1000);
}
heartBeatFailCount++;
},
});
}
}
// 监听WebSocket连接打开事件。callback 回调函数
wx.onSocketOpen(function(res) {
connectFailTimes = 0
console.log('WebSocket连接已打开!')
wx.hideLoading();
// 如果已经调用过关闭function
if (socketClose) {
webSocket.closeSocket();
} else {
socketOpen = true
for (var i = 0; i < socketMsgQueue.length; i++) {
webSocket.sendSocketMessage(socketMsgQueue[i])
}
socketMsgQueue = []
webSocket.startHeartBeat();
}
})
// 监听WebSocket错误。
wx.onSocketError(function(res) {
connectFailTimes++
console.log('WebSocket连接打开失败,请检查!', res)
})
// 监听WebSocket接受到服务器的消息事件。
wx.onSocketMessage(function(res) {
console.log('收到服务器内容:' + res.data)
webSocket.onSocketMessageCallback(res.data)
})
// 监听WebSocket关闭。
wx.onSocketClose(function(res) {
console.log('WebSocket 已关闭!')
webSocket.webSocketClose = true;
if (connectFailTimes <= 3) {
if (!socketClose) {
clearTimeout(connectSocketTimeOut)
connectSocketTimeOut = setTimeout(() => {
webSocket.connectSocket();
}, 3000);
}
} else {
wx.hideLoading()
wx.showModal({
title: '',
content: '服务器异常,请重新登录',
})
clearTimeout(connectSocketTimeOut)
}
})
module.exports = webSocket;
网页版:
function sesWebSocket(wsurl) {
this.connectURL = wsurl || "";
this.time = 10*1000; //心跳时间
this.heartMsg = ""; //心跳发送内容
this.timeoutObj = null;
this.serverTimeoutObj = null;
this.reconnectTime = null;
this.isDestroy = false;
this.onopen = function(event) {
// 自定义WSC连接事件:服务端与前端连接成功后触发
console.log(event)
};
this.onmessage = function(event) {
// 自定义WSC消息接收事件:服务端向前端发送消息时触发
console.log(event)
};
this.onerror = function(event) {
// 自定义WSC异常事件:WSC报错后触发
console.log(event)
};
this.onclose = function(event) {
// 自定义WSC关闭事件:WSC关闭后触发
console.log(event)
};
this.webSocketObj = new WebSocket(wsurl);
}
sesWebSocket.fn = sesWebSocket.prototype = {
create: function(obj) {
if(obj) {
$.extend(true, this, obj);
}
var websocket = this.webSocketObj;
var currentThis = this;
websocket.onopen = function(evnt) {
console.log('已连接')
currentThis.onopen(evnt);
};
websocket.onmessage = function(evnt) {
// console.log('收到服务器内容:'+evnt)
currentThis.onmessage(evnt);
};
websocket.onerror = function(evnt) {
console.log('连接出错')
currentThis.onerror(evnt);
};
websocket.onclose = function(evnt) {
console.log('连接已关闭')
currentThis.onclose(evnt);
currentThis.aaa();
};
this.reconnectTime = currentThis.reconnectTime;
},
aaa: function() {
if(!this.isDestroy) {
this.isDestroy = true;
this.webSocketObj.close();
var c = this;
this.reconnectTime = setTimeout(function() {
c.reconnect();
}, c.time)
}
},
destroy: function() {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
clearTimeout(this.reconnectTime);
this.isDestroy = true;
this.webSocketObj.close();
},
heartStart: function(time, msg) {
if(this.webSocketObj.readyState != 1) {
return false;
}
if(time) {
this.time = time;
}
if(msg) {
this.heartMsg = msg;
}
var self = this;
this.timeoutObj = setTimeout(function() {
self.webSocketObj.send(msg);
self.serverTimeoutObj = setTimeout(function() {
self.reconnect();
}, self.time)
}, this.time);
this.serverTimeoutObj = self.serverTimeoutObj;
},
heartReset: function() {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
var time = this.time;
var msg = this.heartMsg;
this.heartStart(time, msg);
},
reconnect: function() {
if(this.timeoutObj) {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
}
var wsurl = this.connectURL;
this.webSocketObj = new WebSocket(wsurl);
this.isDestroy = false;
this.create();
},
}
var $sesWebSocket = function(wsurl) {
return new sesWebSocket(wsurl);
}
sesWebSocket.export = function(fn) {
jQuery.extend(sesWebSocket.prototype, fn);
}
var websock = null;
var global_callback = null;
var serverPort = '5000'; //webSocket连接端口
function getWebIP(){
var curIP = window.location.hostname;
return curIP;
}
function initWebSocket(){ //初始化weosocket
//ws地址
var wsuri = "ws://" +getWebIP()+ ":" + serverPort;
websock = new WebSocket(wsuri);
websock.onmessage = function(e){
websocketonmessage(e);
}
websock.onclose = function(e){
websocketclose(e);
}
websock.onopen = function () {
websocketOpen();
}
//连接发生错误的回调方法
websock.onerror = function () {
console.log("WebSocket连接发生错误");
}
}
// 实际调用的方法
function sendSock(agentData,callback){
global_callback = callback;
if (websock.readyState === websock.OPEN) {
//若是ws开启状态
websocketsend(agentData)
}else if (websock.readyState === websock.CONNECTING) {
// 若是 正在开启状态,则等待1s后重新调用
setTimeout(function () {
sendSock(agentData,callback);
}, 1000);
}else {
// 若未开启 ,则等待1s后重新调用
setTimeout(function () {
sendSock(agentData,callback);
}, 1000);
}
}
//数据接收
function websocketonmessage(e){
global_callback(JSON.parse(e.data));
}
//数据发送
function websocketsend(agentData){
websock.send(JSON.stringify(agentData));
}
//关闭
function websocketclose(e){
console.log("connection closed (" + e.code + ")");
}
function websocketOpen(e){
console.log("连接成功");
}
initWebSocket();
export{sendSock}