123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- 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 = 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)
- if (this.socketStatus < 10) {
- // 失败重连
- if (this.reconnectNum > 50) return;
- if (this.reconnectNum < this.reconnect_time.length) {
- reconnect_timeout = reconnect_time[this.reconnectNum]
- } else {
- reconnect_timeout = reconnect_time[this.reconnect_time.length - 1]
- }
- console.log("uniWebsocket 重新连接", this.socketStatus, this.reconnectNum, this.reconnect_timeout)
- this.reconnectNum = this.reconnectNum + 1
- this.reconnectTimeOut = setTimeout(() => {
- // 连接创建
- this.connectSocketInit();
- this.reconnect()
- }, reconnect_timeout)
- return;
- }
- console.log("uniWebsocket 自身巡检", socketStatus, 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.is_open_socket) {
- return null;
- }
- let that = this;
- this.socketTask = uni.connectSocket({
- url: this.url,
- success: () => {
- console.log("正准备建立websocket中...");
- // 返回实例
- return this.socketTask
- },
- });
- this.socketTask.onOpen((res) => {
- console.log("WebSocket连接正常!");
- clearTimeout(this.reconnectTimeOut)
- clearInterval(this.heartbeatInterval)
- this.is_open_socket = true;
- this.start();
- console.log("WebSocket连接正常!-start");
- // 注:只有连接正常打开中 ,才能正常收到消息
- this.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 == "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("已经被关闭了")
- this.is_open_socket = false;
- this.reconnect();
- })
- }
- toLogin() {
- let that = this;
- that.send({
- seq: that.generateSeq(),
- cmd: "login",
- data: {
- "uuid": that.uuid,
- "appId": 101
- }
- });
- }
- //发送消息
- send(value) {
- console.log("send-content:", value);
- value.seq = this.generateSeq();
- // 注:只有连接正常打开中 ,才能正常成功发送消息
- 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}"`);
- }
- }
- });
- }
- //开启心跳检测
- start() {
- let that = this;
- if (this.heartbeatInterval != null) {
- clearInterval(this.heartbeatInterval);
- }
- console.log("WebSocket连接正常!-start2");
- that.send({
- seq: that.generateSeq(),
- cmd: "login",
- data: {
- "skey": that.uuid,
- "appId": 101
- }
- });
- this.heartbeatInterval = setInterval(() => {
- // console.log("heart",that.timeout);
- //{"seq":"1565336219141-266129","cmd":"login","data":{"userId":"马远","appId":101}}
- that.send({
- seq: that.generateSeq(),
- cmd: "heartbeat",
- data: {
- "userId": getApp().globalData.userId,
- "appId": 101
- }
- });
- }, that.timeout)
- }
- stop() {
- uni.closeSocket();
- }
- //外部获取消息
- getMessage(callback) {
- this.socketTask.onMessage((res) => {
- return callback(res)
- })
- }
- }
- module.exports = websocketUtil
|