From b9972e791ac76682e1428b6d1dd1a17e15428aad Mon Sep 17 00:00:00 2001 From: Stormeye Wu Date: Fri, 22 Mar 2019 09:40:48 +0800 Subject: [PATCH] =?UTF-8?q?[websocket][=E6=96=B0=E5=A2=9E]:=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E6=94=AF=E6=8C=81websocket?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.js | 140 +++++++++++++++++++++++++++++++++++++++++++ config/config.js | 7 +++ pages/index/index.js | 24 +++++--- utils/stomp.min.js | 8 +++ 4 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 utils/stomp.min.js diff --git a/app.js b/app.js index 1e3b73b..82fa50a 100644 --- a/app.js +++ b/app.js @@ -25,6 +25,8 @@ App({ globalData: { // token token: null, + // user openId + openId: null, // 渠道 sceneAddress: null, // location info @@ -41,6 +43,144 @@ App({ // 当前商场信息 market: { name: "陕西大悦城" + }, + // websocket + socketClient: null, + socketReceiver: function (e) { }, //收到消息回调 + }, + + // 初始化websocket + initSocket: function () { + let that = this; + // socket是否连接 + let socketConnected = false; + // 待发送的消息队列 + let messageQueue = []; + // 是否断线重连 + let reconnect = true; + + // 发送消息 + function sendSocketMessage(msg) { + // console.log(msg); + // 如果socket已连接则发送消息 + if (socketConnected) { + wx.sendSocketMessage({ + data: msg + }) + } else { + // socket没有连接将消息放入队列中 + messageQueue.push(msg); + } + } + + // 关闭连接 + function close() { + if (socketConnected) { + wx.closeSocket() + socketConnected = false; + } + } + + // 符合WebSocket定义的对象 + var ws = { + send: sendSocketMessage, + close: close } + + // 创建一个 WebSocket 连接 + function connect() { + wx.connectSocket({ + url: config.wsurl, + header: { + token: that.globalData.token //从服务端获取一个token,服务端验证token是否允许连接,案例中没做限制 + } + }) + } + connect(); + + // 监听 WebSocket 连接打开事件 + wx.onSocketOpen(function (res) { + console.log("WebSocket 连接成功") + socketConnected = true; + ws.onopen(); + // 连接成功后,将队列中的消息发送出去 + let queueLength = messageQueue.length + for (let i = 0; i < queueLength; i++) { + sendSocketMessage(messageQueue.shift()) + } + }) + + // 监听 WebSocket 接受到服务器的消息事件 + wx.onSocketMessage(function (res) { + ws.onmessage(res); + }) + + // 监听 WebSocket 错误事件 + wx.onSocketError(function (res) { + console.log("WebSocket 错误事件") + if (!socketConnected) { + // 断线重连 + if (reconnect) { + connect(); + } + } + }) + + // 监听 WebSocket 连接关闭事件 + wx.onSocketClose(function (res) { + console.log("WebSocket 连接关闭") + socketConnected = false; + // 断线重连 + if (reconnect) { + connect(); + } + }) + + const Stomp = require('/utils/stomp.min.js').Stomp; + + /** + * 定期发送心跳或检测服务器心跳 + * The heart-beating is using window.setInterval() to regularly send heart-beats and/or check server heart-beats. + * 可看stomp.js的源码(195,207,489行),由于小程序没有window对象,所以我们要调用小程序的定时器api实现 + */ + Stomp.setInterval = function (interval, f) { + return setInterval(f, interval); + }; + // 结束定时器的循环调用 + Stomp.clearInterval = function (id) { + return clearInterval(id); + }; + + const stompClient = Stomp.over(ws); + + that.globalData.socketClient = stompClient; + + stompClient.connect({}, function (callback) { + + // 订阅自己的 + stompClient.subscribe('/user/'+that.globalData.openId+'/message', function (message, headers) { + console.log('收到只发送给我的消息:', message); + that.globalData.socketReceiver(JSON.parse(message.body)); + // 通知服务端收到消息 + message.ack(); + }); + + stompClient.subscribe('/topic/1001A', function (message, headers) { + console.log('收到TOPIC的消息:', message); + that.globalData.socketReceiver(JSON.parse(message.body)); + // 通知服务端收到消息 + //message.ack(); + }); + + // 向服务端发送消息 + stompClient.send("/app/message", {}, JSON.stringify({ + 'msg': 'client: ' + that.globalData.openId + })); + }) + }, + + //统一发送消息 + sendSocketMessage: function (msg) { + this.globalData.socketClient.send("/app/message", {}, JSON.stringify(msg)); } }); diff --git a/config/config.js b/config/config.js index 823a6f9..af98893 100755 --- a/config/config.js +++ b/config/config.js @@ -10,6 +10,7 @@ if (Object.keys(extConfig).length == 0){ } var config = { url: configUrls, + wsurl: "ws://10.100.30.171:7100/W/ws", api: { /** * 接口用途:login @@ -253,6 +254,12 @@ var config = { */ queryAttendStatus:'/orderGroup/queryAttendStatus' }, + wsapi: { + /** + * + */ + + }, weapp: { AppId: weappId }, diff --git a/pages/index/index.js b/pages/index/index.js index bfb79ef..de68c92 100644 --- a/pages/index/index.js +++ b/pages/index/index.js @@ -148,18 +148,24 @@ Page({ userLogin: function (options) { console.log(1111,options,2222222222) var that = this; + // 获取系统信息 + wx.getSystemInfo({ + success: function (res) { + var name = res.model + // 检测是否为iphonex xs xr + // if (name.indexOf("iPhone X") > -1) { + // that.globalData.isIpx = true + //} + that.setData({ + systemInfo: JSON.stringify(res) + }) + } + }) // 登录 wx.login({ success: ({ code }) => { - wx.getSystemInfo({ - success: function(res) { - that.setData({ - systemInfo: JSON.stringify(res) - }) - } - }) var usrdata = { appId: config.weapp.AppId, code: code, @@ -186,7 +192,11 @@ Page({ that.setData({ showPages: true }) + console.log(res) app.globalData.token = res.data.token; + app.globalData.openId = res.data.openId; + // 初始化websocket + app.initSocket(); Http.setToken(res.data.token); if (options&&(options.couponChannelId || options.orderId)){ that.checkuerstatus(options); diff --git a/utils/stomp.min.js b/utils/stomp.min.js new file mode 100644 index 0000000..dd0b1fa --- /dev/null +++ b/utils/stomp.min.js @@ -0,0 +1,8 @@ +// Generated by CoffeeScript 1.7.1 +/* + Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0 + + Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/) + Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com) + */ +(function(){var t,e,n,i,r={}.hasOwnProperty,o=[].slice;t={LF:"\n",NULL:"\x00"};n=function(){var e;function n(t,e,n){this.command=t;this.headers=e!=null?e:{};this.body=n!=null?n:""}n.prototype.toString=function(){var e,i,o,s,u;e=[this.command];o=this.headers["content-length"]===false?true:false;if(o){delete this.headers["content-length"]}u=this.headers;for(i in u){if(!r.call(u,i))continue;s=u[i];e.push(""+i+":"+s)}if(this.body&&!o){e.push("content-length:"+n.sizeOfUTF8(this.body))}e.push(t.LF+this.body);return e.join(t.LF)};n.sizeOfUTF8=function(t){if(t){return encodeURI(t).match(/%..|./g).length}else{return 0}};e=function(e){var i,r,o,s,u,a,c,f,h,l,p,d,g,b,m,v,y;s=e.search(RegExp(""+t.LF+t.LF));u=e.substring(0,s).split(t.LF);o=u.shift();a={};d=function(t){return t.replace(/^\s+|\s+$/g,"")};v=u.reverse();for(g=0,m=v.length;gy;c=p<=y?++b:--b){r=e.charAt(c);if(r===t.NULL){break}i+=r}}return new n(o,a,i)};n.unmarshall=function(n){var i,r,o,s;r=n.split(RegExp(""+t.NULL+t.LF+"*"));s={frames:[],partial:""};s.frames=function(){var t,n,o,s;o=r.slice(0,-1);s=[];for(t=0,n=o.length;t>> "+r)}while(true){if(r.length>this.maxWebSocketFrameSize){this.ws.send(r.substring(0,this.maxWebSocketFrameSize));r=r.substring(this.maxWebSocketFrameSize);if(typeof this.debug==="function"){this.debug("remaining = "+r.length)}}else{return this.ws.send(r)}}};r.prototype._setupHeartbeat=function(n){var r,o,s,u,a,c;if((a=n.version)!==i.VERSIONS.V1_1&&a!==i.VERSIONS.V1_2){return}c=function(){var t,e,i,r;i=n["heart-beat"].split(",");r=[];for(t=0,e=i.length;t>> PING"):void 0}}(this))}if(!(this.heartbeat.incoming===0||o===0)){s=Math.max(this.heartbeat.incoming,o);if(typeof this.debug==="function"){this.debug("check PONG every "+s+"ms")}return this.ponger=i.setInterval(s,function(t){return function(){var n;n=e()-t.serverActivity;if(n>s*2){if(typeof t.debug==="function"){t.debug("did not receive server activity for the last "+n+"ms")}return t.ws.close()}}}(this))}};r.prototype._parseConnect=function(){var t,e,n,i;t=1<=arguments.length?o.call(arguments,0):[];i={};switch(t.length){case 2:i=t[0],e=t[1];break;case 3:if(t[1]instanceof Function){i=t[0],e=t[1],n=t[2]}else{i.login=t[0],i.passcode=t[1],e=t[2]}break;case 4:i.login=t[0],i.passcode=t[1],e=t[2],n=t[3];break;default:i.login=t[0],i.passcode=t[1],e=t[2],n=t[3],i.host=t[4]}return[i,e,n]};r.prototype.connect=function(){var r,s,u,a;r=1<=arguments.length?o.call(arguments,0):[];a=this._parseConnect.apply(this,r);u=a[0],this.connectCallback=a[1],s=a[2];if(typeof this.debug==="function"){this.debug("Opening Web Socket...")}this.ws.onmessage=function(i){return function(r){var o,u,a,c,f,h,l,p,d,g,b,m,v;c=typeof ArrayBuffer!=="undefined"&&r.data instanceof ArrayBuffer?(o=new Uint8Array(r.data),typeof i.debug==="function"?i.debug("--- got data length: "+o.length):void 0,function(){var t,e,n;n=[];for(t=0,e=o.length;t