微信小程序使用原生WebSokcet實現斷線重連及數據拼接 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關 >

微信小程序使用原生WebSokcet實現斷線重連及數據拼接

發表時(shí)間:2021-3-31

發布人(rén):融晨科技

浏覽次數:86

以(yǐ)前做小程序爲(wéi / wèi)了(le/liǎo)應急找了(le/liǎo)個(gè)插件去鏈接WebSokcet,文章傳送門。

回過頭在(zài)新項目中再次使用時(shí)出(chū)現了(le/liǎo)些許問題,不(bù)一一贅述。遂決定好好用一下原生的(de)WebSokcet。


一、說(shuō)明

1.小程序原生的(de)WebSokcet沒有斷線重連機制,這(zhè)個(gè)是(shì)他(tā)的(de)不(bù)足之(zhī)處。

2.小程序新的(de)版本庫已經支持存在(zài)多個(gè) WebSokcet 連接。

官方說(shuō)明:基礎庫 1.7.0 之(zhī)前,一個(gè)微信小程序同時(shí)隻能有一個(gè) WebSocket 連接,如果當前已存在(zài)一個(gè) WebSocket 連接,會自動關閉該連接,并重新創建一個(gè) WebSocket 連接。基礎庫版本 1.7.0 及以(yǐ)後,支持存在(zài)多個(gè) WebSokcet 連接,每次成功調用 wx.connectSocket 會返回一個(gè)新的(de) SocketTask。

官方文檔地(dì / de)址:mp.weixin.qq.com/debug/


二、實際例子(zǐ):

首先你需要(yào / yāo)socket地(dì / de)址url: let url = 'wss://xxx.xxx.com/?'

注意:1.小程序管理後台添加socket域名的(de)時(shí)候不(bù)能出(chū)現端口;2.如果使用了(le/liǎo)appID,協議必須是(shì) wss;3.socket服務端映射的(de)端口僅支持 80 和(hé / huò) 443,和(hé / huò)公衆号一個(gè)尿性。

接下來(lái)放例子(zǐ):

1、socket.js

const app = getApp();
let url = 'wss://xxx.xxx.com/?xxx=xxx'
export const connect = function (cb) { // 定義一個(gè)方法
   wx.connectSocket({ // 創建一個(gè) WebSocket 連接
       url: url,
       fail (err) {
if (err) {
               console.log('%cWebSocket連接失敗', 'color:red', err)
               app.globalData.socketConnectFail = true // 定義一個(gè)全局變量,當鏈接失敗時(shí)改變變量的(de)值
}
}
})

   wx.onSocketOpen(function (res) { // 監聽WebSocket連接打開事件。
       console.log('WebSocket打開成功');
       wx.sendSocketMessage({ // 通過 WebSocket 連接發送數據,需要(yào / yāo)先 wx.connectSocket,并在(zài) wx.onSocketOpen 回調之(zhī)後才能發送。
           data: String2Base64(), // 用于(yú)訂閱的(de)參數,視具體情況而(ér)定
           success (data) {
               console.log('WebSocket發送消息:', data.errMsg)
},
           fail (err) {
               console.log('Err', err)
}
})

})

   wx.onSocketMessage(function (res) { // 監聽WebSocket接受到(dào)服務器的(de)消息事件。
       console.log('WebSocket接收到(dào)消息:', ArryBuffer2Json(res.data));
       cb(ArryBuffer2Json(res.data)); // 将接收到(dào)的(de)消息進行回調,如果是(shì)ArryBuffer,需要(yào / yāo)進行轉換
})

   wx.onSocketError(function (res) { // 監聽WebSocket錯誤。
       console.log('WebSocket連接打開失敗')
})

   wx.onSocketClose(function (res) { // 監聽WebSocket關閉。
       console.log('WebSocket關閉');
})
};

function ArryBuffer2Json (data) { // ArryBuffer轉換成Json
try {
var encodedString = String.fromCharCode.apply(null, new Uint8Array(data));
var decodedString = decodeURIComponent(atob(encodedString));
return JSON.parse(decodedString);
} catch (err) {
       console.log(err);
return false;
}
}


function String2Base64 () { // 用于(yú)訂閱的(de)參數,視具體情況而(ér)定
var packet = {};
   packet["cmd"] = "subscribe";
   packet["reqNo"] = "" + new Date().getTime();
   packet["params"] = {token: token, channelId: 'xcx', columnIds: "1"};
return stringToUint(JSON.stringify(packet))
}

function stringToUint (string) {
var string = base64_encode(encodeURIComponent(string)),
       charList = string.split(''),
       uintArray = [];
for (var i = 0; i < charList.length; i++) {
       uintArray.push(charList[i].charCodeAt(0));
}
return new Uint8Array(uintArray);
}

function base64_encode (str) { // base64轉碼
var c1, c2, c3;
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var i = 0, len = str.length, string = '';

while (i < len) {
       c1 = str.charCodeAt(i++) & 0xff;
if (i == len) {
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt((c1 & 0x3) << 4);
string += "==";
break;
}
       c2 = str.charCodeAt(i++);
if (i == len) {
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
string += base64EncodeChars.charAt((c2 & 0xF) << 2);
string += "=";
break;
}
       c3 = str.charCodeAt(i++);
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
string += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
string += base64EncodeChars.charAt(c3 & 0x3F)
}
return string
}


2、index.js

let openSocket = require('../../config/socket.js');
const app = getApp();
data: {
  motto: 'Hello World',
  articleData: []
},
onLoad: function () {
let that = this;
  openSocket.connect(function (data) { // WebSocket初始化連接
let result = data.data
if (result) {
          that.setData({articleData: [result].concat(that.data.articleData)}) // 将獲得的(de)socket推送消息拼接到(dào)當前文章列表的(de)最前面
}
});
if (app.globalData.socketConnectFail) { // WebSocket斷線重連
      setInterval(() => {
          openSocket.connect(function (data) {
let result = data.data
if (result) {
                  that.setData({articleData: [result].concat(that.data.articleData)})
}
});
}, 1000)
}
} 


3、app.js

globalData: {
  socketConnectFail: false
}

相關案例查看更多