123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- class websocketUtil {
- is_open_socket = false;
- socketStatus = 0 //避免重复连接 0 无连接 1-9连接中 10 已连接
- url = '';
- data = '';
- uuid = '';
- timeout = 10000;
- heartbeatInterval = null;
- reconnectTimeOut = null;
- reconnectNum = 0 //重连次数
- msgQueue = []
- socketTask = null //ws对象
- netIsConnected = false
- netType = 'none'
- autoFlag = true
- constructor(url, uuid) {
- this.is_open_socket = false; //避免重复连接
- this.url = url; //地址
- this.data = null;
- this.uuid = getApp().globalData.uuid;
- //心跳检测
- this.timeout = 10000;
- this.heartbeatInterval = null; //检测服务器端是否还活着
- this.reconnectTimeOut = null; //重连之后多久再次重连
- // 监听网络状态变化
- let that = this;
- uni.onNetworkStatusChange((res) => {
- console.log('WebSocket NetStatus', res.isConnected);
- console.log('WebSocket NetStatus', res.networkType);
- that.netIsConnected = res.isConnected
- that.netType = res.networkType
- that.reconnectNum = 0
- if (that.autoFlag) this.reconnect()
- });
- try {
- uni.getNetworkType({
- success: (res) => {
- console.log('WebSocket getNetworkType', res.networkType);
- that.netType = res.networkType;
- that.netIsConnected = true;
- that.reconnect();
- }
- });
- // 有return ,则构造方法返回return的对象,没有,则返回new的对象
- // return this.hhh
- } catch (e) {
- console.log('连接初始化失败', e);
- }
- // try {
- // return this.connectSocketInit()
- // } catch (e) {
- // console.log('catch');
- // this.is_open_socket = false
- // this.reconnect();
- // }
- }
- //重新连接
- reconnect() {
- // 失败重连频率
- const reconnect_time = [3000, 3000, 3000, 3000, 10000, 10000, 10000, 20000, 20000, 50000]
- // 自身巡检频率
- let reconnect_timeout = 30000
- //停止发送心跳
- // this.heartbeatInterval && clearInterval(this.heartbeatInterval)
- this.reconnectTimeOut && clearTimeout(this.reconnectTimeOut)
- if (this.socketStatus < 10) {
- // 失败重连
- if (this.reconnectNum > 50) return;
- if (this.reconnectNum < reconnect_time.length) {
- reconnect_timeout = reconnect_time[this.reconnectNum]
- } else {
- reconnect_timeout = reconnect_time[reconnect_time.length - 1]
- }
- console.log("uniWebsocket 重新连接", this.socketStatus, this.reconnectNum, reconnect_timeout)
- this.reconnectNum = this.reconnectNum + 1
- this.reconnectTimeOut = setTimeout(() => {
- // 连接创建
- this.connectSocketInit();
- this.reconnect()
- }, reconnect_timeout)
- return;
- }
- console.log("uniWebsocket 自身巡检", this.socketStatus, this.reconnectNum, reconnect_timeout)
- // 自身巡检循环
- this.reconnectTimeOut = setTimeout(() => {
- // 连接创建
- this.connectSocketInit();
- this.reconnect()
- }, reconnect_timeout)
- //如果不是人为关闭的话,进行重连
- // if (!this.is_open_socket) {
- // this.reconnectTimeOut = setTimeout(() => {
- // this.connectSocketInit();
- // }, 3000)
- // }
- }
- generateSeq() {
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- const r = Math.random() * 16 | 0;
- const v = c === 'x' ? r : (r & 0x3 | 0x8);
- return v.toString(16);
- });
- }
- // 进入这个页面的时候创建websocket连接【整个页面随时使用】
- connectSocketInit() {
- if (!this.netIsConnected || this.netType == 'none') return
- if (this.socketStatus > 0) return
- // if(!url) return
- // if (this.is_open_socket) {
- // return null;
- // }
- this.heartbeatInterval && clearInterval(this.heartbeatInterval)
- this.socketStatus = 1;
- uni.onSocketError(function(res) {
- that.socketStatus = 0;
- console.log('WebSocket 连接错误!', that.socketStatus, res);
- });
- let that = this;
- uni.onSocketClose(function(res) {
- that.socketStatus = 0;
- that.restart();
- console.log('WebSocket 连接关闭!', res);
- });
- uni.onSocketOpen(function(res) {
- that.socketStatus = 10;
- console.log('WebSocket 连接打开!', res);
- });
- this.socketTask = uni.connectSocket({
- url: that.url,
- success: () => {
- that.socketStatus = 2;
- console.log("正准备建立websocket中...");
- return that.socketTask;
- },
- fail: (data) => {
- that.socketStatus = 0;
- console.log("websocket 建立失败...");
- },
- complete: (data) => {
- that.socketStatus = 3;
- console.log("websocket 建立完成...");
- }
- });
- this.socketTask.onOpen((res) => {
- console.log("WebSocket连接正常!");
- // clearTimeout(this.reconnectTimeOut)
- // clearInterval(this.heartbeatInterval)
- that.socketStatus = 10;
- that.reconnectNum = 0;
- that.is_open_socket = true;
- that.start();
- console.log("WebSocket连接正常!-start");
- // 注:只有连接正常打开中 ,才能正常收到消息
- that.socketTask.onMessage((res) => {
- let resdata = JSON.parse(res.data)
- //{"seq":"859a0fbd-05c5-4630-a160-e3cf284ad9c9","cmd":"login","response":{"code":200,"codeMsg":"{userId:'1',msg:'欢迎进入~'}","data":null}}
- console.log(resdata)
- if (resdata.cmd == "login") {
- if (resdata.response.codeMsg == "") {
- getApp().globalData.isLogin = 0;
- } else {
- getApp().globalData.isLogin = 1;
- console.log(resdata.response.codeMsg);
- getApp().globalData.userId = resdata.response.codeMsg;
- }
- uni.$emit('updateGroup', "") //重新加入群组,以便接收消息
- } else if (resdata.cmd == "msg") {
- uni.$emit('messageUpdate', resdata.response.data.msg)
- } else if (resdata.cmd == "sendMsg") {
- uni.$emit('messageSend', resdata.response)
- } else if (resdata.cmd == "heartbeat") {
- if (resdata.response.code == 1000) {
- that.toLogin();
- }
- }
- if (resdata.response.code != 200) {
- // console.log(res.data)
- }
- });
- })
- // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
- // uni.onSocketError((res) => {
- // console.log('WebSocket连接打开失败,请检查!');
- // this.is_open_socket = false;
- // this.reconnect();
- // });
- // 这里仅是事件监听【如果socket关闭了会执行】
- this.socketTask.onClose(() => {
- console.log("已经被关闭了")
- that.is_open_socket = false;
- that.reconnect();
- })
- }
- toLogin() {
- let that = this;
- that.send({
- seq: that.generateSeq(),
- cmd: "login",
- data: {
- "uuid": that.uuid,
- "appId": 101
- }
- });
- }
- //发送消息
- send(value) {
- value.seq = this.generateSeq();
- value = JSON.stringify(value)
- this.msgQueue.push(value);
- if (this.socketStatus < 10) {
- console.log("**********", "连接错误,消息发送失败", value);
- return;
- }
- let that = this;
- let msg = '';
- while (msg = this.msgQueue.shift()) {
- // 注:只有连接正常打开中 ,才能正常成功发送消息
- that.socketTask.send({
- data: msg,
- async success() {
- console.log('++++++++++', msg)
- // console.log("消息发送成功");
- },
- fail(e) {
- console.log("send-err:", e, msg);
- //errMsg sendSocketMessage:fail Error: SocketTask.readyState is not OPEN
- // {"errMsg":"sendSocketMessage:fail WebSocket is not connected"} at common/websocketUtil.js:111
- if (e.errMsg.includes("not OPEN") || e.errMsg.includes("fail WebSocket") || e.errMsg
- .includes("not connected")) {
- that.close()
- that.restart();
- console.log('is now reconnect');
- // console.log(`"${str}" 包含 "${substr}"`);
- } else {
- console.log('errMsg', e.errMsg)
- // console.log(`"${str}" 不包含 "${substr}"`);
- }
- }
- });
- }
- // 注:只有连接正常打开中 ,才能正常成功发送消息
- // let that = this;
- // this.socketTask.send({
- // data: JSON.stringify(value),
- // async success() {
- // // console.log("消息发送成功");
- // },
- // fail(e) {
- // console.log("send-err:", e);
- // // {"errMsg":"sendSocketMessage:fail WebSocket is not connected"} at common/websocketUtil.js:111
- // if (e.errMsg.includes("fail WebSocket") || e.errMsg.includes("not connected")) {
- // uni.closeSocket();
- // that.reconnect();
- // console.log('is now reconnect');
- // // console.log(`"${str}" 包含 "${substr}"`);
- // } else {
- // console.log('errMsg', e.errMsg)
- // // console.log(`"${str}" 不包含 "${substr}"`);
- // }
- // }
- // });
- }
- getStatus() {
- return this.socketStatus
- }
- //开启心跳检测
- start() {
- let that = this;
- if (this.heartbeatInterval != null) {
- clearInterval(this.heartbeatInterval);
- }
- console.log("WebSocket连接正常!-start2");
- that.send({
- seq: that.generateSeq(),
- cmd: "login",
- data: {
- "uuid": that.uuid,
- "appId": 101
- }
- });
- this.heartbeatInterval = setInterval(() => {
- // console.log("heart",that.timeout);
- //{"seq":"1565336219141-266129","cmd":"login","data":{"userId":"马远","appId":101}}
- if (that.socketStatus >= 10) {
- that.send({
- seq: that.generateSeq(),
- cmd: "heartbeat",
- data: {
- "userId": getApp().globalData.userId,
- "appId": 101
- }
- });
- }
- }, that.timeout)
- }
- /**
- * 重新打开链接
- */
- restart() {
- if (this.socketStatus >= 10) {
- console.log("连接已打开");
- return;
- }
- console.log("restart")
- this.autoFlag = true
- this.reconnect()
- }
- /**
- * 关闭链接
- */
- close() {
- console.log("关闭连接")
- if (this.socketStatus < 10) {
- console.log("连接未打开");
- return;
- }
- console.log("清理定时")
- // heartbeatTimeOut && clearTimeout(heartbeatTimeOut)
- this.heartbeatInterval && clearInterval(this.heartbeatInterval)
- this.reconnectTimeOut && clearTimeout(this.reconnectTimeOut)
- this.autoFlag = false
- this.socketStatus = 0;
- this.socketTask.close()
- console.log("正式关闭")
- }
- // stop() {
- // uni.closeSocket();
- // }
- //外部获取消息
- getMessage(callback) {
- console.log("message", this.socketTask);
- if (this.socketTask != null) {
- this.socketTask.onMessage((res) => {
- return callback(res)
- })
- }
- }
- }
- module.exports = websocketUtil
|