微信小程式使用 Websocket
阿新 • • 發佈:2018-12-27
基本思路是:
- 全域性維護一個SocketTask物件,用來表示websocket連線,判斷是否斷線,作為重連的依據。
- 同時定義一個全域性callback回撥函式,每個頁面初始化的時候更新這個回撥函式,那麼在每個頁面中收到返回訊息就會執行當前頁面邏輯。
- 維護一個訊息佇列,所有訊息請求會首先判斷連線是否可用,如果可用直接發訊息,否則將訊息push到這個佇列中。
- 在app.js的onShow()函式中判斷連線是否連上,如果沒有連上就會觸發websocket連線
- SocketTask物件的onOpen()負責從訊息佇列中取出請求訊息,併發送這個請求訊息
- SocketTask物件的onMessage()負責接收返回訊息,並呼叫每個頁面自己定義的回撥函式
- SocketTask物件的onClose()監聽函式中,觸發websocket連線
下面是app.js程式碼:
let socketMsgQueue = [] let isLoading = false App({ globalData: { userInfo: null, localSocket: {}, callback: function () {} }, onLaunch: function (options) { // 展示本地儲存能力 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) const updateManager = wx.getUpdateManager() updateManager.onUpdateReady(function () { updateManager.applyUpdate() }) let that = this // 登入 wx.login({ success: res => { // 傳送 res.code 到後臺換取 openId, sessionKey, unionId } }) // 獲取使用者資訊 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已經授權,可以直接呼叫 getUserInfo 獲取頭像暱稱,不會彈框 wx.getUserInfo({ success: res => { // 可以將 res 傳送給後臺解碼出 unionId this.globalData.userInfo = res.userInfo // 由於 getUserInfo 是網路請求,可能會在 Page.onLoad 之後才返回 // 所以此處加入回撥以防止這種情況 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) }, showLoad() { if(!isLoading) { wx.showLoading({ title: '請稍後...', }) isLoading = true } }, hideLoad() { wx.hideLoading() isLoading = false }, initSocket() { let that = this that.globalData.localSocket = wx.connectSocket({ // url: 'wss://test.enzhico.net/app' url: 'wss://mapp.enzhico.net/app' }) that.showLoad() that.globalData.localSocket.onOpen(function (res) { console.log('WebSocket連線已開啟!readyState=' + that.globalData.localSocket.readyState) that.hideLoad() while (socketMsgQueue.length > 0) { var msg = socketMsgQueue.shift(); that.sendSocketMessage(msg); } }) that.globalData.localSocket.onMessage(function(res) { that.hideLoad() that.globalData.callback(res) }) that.globalData.localSocket.onError(function(res) { console.log('readyState=' + that.globalData.localSocket.readyState) }) that.globalData.localSocket.onClose(function (res) { console.log('WebSocket連線已關閉!readyState=' + that.globalData.localSocket.readyState) that.initSocket() }) }, //統一發送訊息 sendSocketMessage: function (msg) { if (this.globalData.localSocket.readyState === 1) { this.showLoad() this.globalData.localSocket.send({ data: JSON.stringify(msg) }) } else { socketMsgQueue.push(msg) } }, onShow: function(options) { if (this.globalData.localSocket.readyState !== 0 && this.globalData.localSocket.readyState !== 1) { console.log('開始嘗試連線WebSocket!readyState=' + this.globalData.localSocket.readyState) this.initSocket() } } })
下面是某個頁面的onshow()函式:
onShow: function () { var that = this app.globalData.callback = function (res) { let resData = JSON.parse(res.data) let data = resData.result if (resData.method == 'list') { that.setData({ total: parseInt(data.allAmount), amount: data.orderNum, jdcAmount: parseInt(data.jdcAmount), jszAmount: parseInt(data.jszAmount), list: data.list || [] }) if(data.list == 0) { that.setData({ isEmpty: true }) } that.getNumber(resData.result.allAmount) that.setAmount() } else if (resData.method == 'notify') { // 伺服器推送訊息,省略具體邏輯 } } setTimeout(function () { app.sendSocketMessage({ method: 'list' }) }, 300) },
https://www.xncoding.com/2017/12/15/weixin/ma-websocket.html