您當前位置>首頁 » 新聞資訊 » 小(xiǎo)程序相(xiàng)關 >
微(wēi)信小(xiǎo)程序使用(yòng)原生(shēng)We$>σbSokcet實現(xiàn)斷線重連及數(shù)據拼接
發表時(shí)間(jiān):2021-3-31
發布人(rén):葵宇科(kē)技(jì)
浏覽次數(shù):89
以前做(zuò)小(xiǎo)程序為(wèi)了(le)應急找了( ∞₹le)個(gè)插件(jiàn)去(qù)鏈接WebSokcet,文φ ★(wén)章(zhāng)傳送門(mén)。
回過頭在新項目中再次使用(yòng)時(shí)出現(xiàn)了(le)些(xiē)許問(w≈↕èn)題,不(bù)一(yī)一(yī)贅述。遂決定好(hǎo)好(hǎo)用(yòng)一(yī''&)下(xià)原生(shēng)的(de)WebSokcet。α↑§
一(yī)、說(shuō)明(míng)
1.小(xiǎo)程序原生(shēng)的(de)WebSokcet沒有↓<(yǒu)斷線重連機(jī)制(zhì),這(zhè)個(gè)是(shì)γ₹↕他(tā)的(de)不(bù)足之處。
2.小(xiǎo)程序新的(de)版本庫已經支持存在多(duō)個(gè) WebSokcet 連φ↔↑接。
官方說(shuō)明(míng):基礎庫 1.7.0 之前,>☆一(yī)個(gè)微(wēi)信小(xiǎo)程序同時(s↑"hí)隻能(néng)有(yǒu)一(yī)個(gè) Web∏÷Socket 連接,如(rú)果當前已存在一(yī)個(gè) WebSocβ∑₩±ket 連接,會(huì)自(zì)動關閉該連接,并重新創建一(yī)個(gè) WebSoc• ₩ket 連接。基礎庫版本 1.7.0 及以後,支持存在多(σσduō)個(gè) WebSokcet 連接,每次成功© 調用(yòng) wx.connectSocket 會(huì)返回一β$≠(yī)個(gè)新的(de) SocketTask。
官方文(wén)檔地(dì)址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-socket.html#wxε¥♥closesocket
二、實際例子(zǐ):
首先你(nǐ)需要(yào)socket地(dì)址url: let url = 'wss:₩'₽δ//http://xxx.xxx.com/?xxx=xxx'
注意:1.小(xiǎo)程序管理(lǐ)後台添加socket域名的(de)時(shí)候∑"不(bù)能(néng)出現(xiàn)端口;2.如(rú•©λ≠)果使用(yòng)了(le)appID,協議(yì)必須是( ↕∞☆shì) wss;3.socket服務端映射的(de)端口僅支持 80 和(hé>¶✘) 443,和(hé)公衆号一(yī)個(gè)尿性。
接下(xià)來(lái)放(fàng)例子(zǐ):
1、socket.js
const app = getApp();
let url = 'wss://σ↓xxx.xxx.com/?xxx=xxx'
export$↓↔ const connect = function (cb) { // '✘≥定義一(yī)個(gè)方法
wx.connectSocket({ //λ•© 創建一(yī)個(gè) WebSocket 連接
±✘βurl: url,
fail (err) {γ∏
if (err) {
console.log('%cΩ±€₩WebSocket連接失敗', 'color:red', err)
©≤ app.globalData.socketConnectFail = •∏$true // 定義一(yī)個(gè)全局變量,當鏈接失敗時(shí)改變變量的(d÷<e)值
}
}
})
wx.onSo←£βφcketOpen(function (res) { // 監聽(tīng)We•™©bSocket連接打開(kāi)事(shì)件(jiàn)。
↑γ✔★ console.log('WebSocket打開(kāi)成功');
δ≈'≠ wx.sendSocketMessage({ // 通( αtōng)過 WebSocket 連接發送數(shù)據,需™§要(yào)先 wx.connectSocket,并在 wx.onSoc↕ε•ketOpen 回調之後才能(néng)發送。
∏δ data: String2Base64(), // 用(yòng)于訂閱的(de)參數(sh<♦ù),視(shì)具體(tǐ)情況而定
ε± success (data) {
cons§¥αole.log('WebSocket發送消息:', data.errMsg)$ ©≈
},
fail (err) {₽"♥
console.log('Err', err)
≤♣♥α}
})
})
wx.onSocketMessage(f£&←unction (res) { // 監聽(tīng)WebSocket接受到(dào)服£ "務器(qì)的(de)消息事(shì)件(jiàn)。
console.log(₹γ♦''WebSocket接收到(dào)消息:', Ar↕×☆ryBuffer2Json(res.data));
cb(Arry₹≠ Buffer2Json(res.data)); // ¥↑将接收到(dào)的(de)消息進行(xíng)回調,如(rú)果是(shì)ArryBu&✔αffer,需要(yào)進行(xíng)轉換
})
wx.onSocketError♠ Ω✘(function (res) { // 監聽(tīng)WebSocket錯(cuò)誤。
∏>
console.log('WebSocket連接打∏↕ε開(kāi)失敗')
})
wx.onSocketClose( π☆→function (res) { // 監聽(tīng)₽>✔WebSocket關閉。
console.log('We$₹bSocket關閉');
})
};
function ArryBuffer2Js®€on (data) { // ArryBuffer轉換成Json
try {
var ←>₽encodedString = String.fromCharπ±Code.apply(null, new Uint8Array(data));
var deγ↓codedString = decodeURIComponent(atob(encodedS♣ ↑tring));
return JSON.parse(decodedString);
} 'σcatch (err) {
console.log(err);
φ&♦return false;
}
}
fu↓÷nction String2Base64 () { // 用(yòng)于訂閱的(d¥♣εe)參數(shù),視(shì)具體(tǐ)情況而定
var packet = {};
σ∏↕σ packet["cmd"] = "subscribe";
packet["¥$ ∑reqNo"] = "" + new Date().getTime();
§ ₹ packet["params"] = {token:♦Ω token, channelId: 'xcx', col₩ umnIds: "1"};
return stringTε±₩oUint(JSON.stringify(packet))
}★δ
function stringToUint σ€£(string) {
var string = base64_♣©encode(encodeURIComponent(string)),
±≠☆≤ charList = string.split('±©'),
uintArray = [];
for (var i = 0; i &δ≤₽£lt; charList.length; i++) {
uin★ tArray.push(charList[i].charCodeAt(0));
}
retur★↔n new Uint8Array(uintArray);
}
function b↑₩ase64_encode (str) { // bas♦Ω★'e64轉碼
var c1, c2, c3;
var base64EncodeChλ↔←ars = "ABCDEFGHIJKLMNOPQRSTUVWXY©σZabcdefghijklmnopqrstuvwxyz012Ω♦₽3456789+/";
var i = 0, len = str.length, string ♥ γ™= '';
while (i < len) {
ε↔←✘ c1 = str.charCodeAt(i++) & 0xff;
if (i β®== len) {
string += base64E↕σncodeChars.charAt(c1 >> 2);
string += ✔↕↓base64EncodeChars.charAt(( ↕β♥c1 & 0x3) << 4);
♦©✘
string += "==";
break;
•♠ }
c2 = str.charCodeAt(i++);
if (i♦& == len) {
string += base64EncodeΩ©©Chars.charAt(c1 >> 2);
string += base64∏¶←₹EncodeChars.charAt(((c1 & 0x3) << 4) |∑↕ ((c2 & 0xF0) >> 4));
"
string += base64EncodeChars.charAt((c2 &a Ω§mp; 0xF) << 2);
string += "=";
break;
×φ
}
c3 = str.charCodeAt(i++);
string©∞✔ += base64EncodeChars.charAt(c1 >> 2↕&);
string += base64EncodeChaΩ§≠rs.charAt(((c1 & 0x3) << 4)α♠γ | ((c2 & 0xF0) >>↔<≈; 4));
string += base64EncodeChars.charAt(((c2 &÷™amp; 0xF) << 2) | ((c3 & 0x&₩&C0) >> 6));
string += base64EncodeChar≈φ"s.charAt(c3 & 0x3F)
}
return strin&g
}
2、index.js
let openSocket = require('../."ε÷./config/socket.js');
const app = g¥₹£'etApp();
data: {
motto: 'Hello Worl∑∑ d',
articleData: []
},
o✔nLoad: function () {
let that = this;
§↓★ openSocket.connect(function (data) { // WebSo✘¶ε÷cket初始化(huà)連接
let result = data.d✘εε₩ata
if (result) {
that£.setData({articleData: [result].concat(th↑δat.data.articleData)}) // ≠£§将獲得(de)的(de)socket推送消息拼接到(dào)當前文(wén)章(zhāng <γ₽)列表的(de)最前面
}
});
if (app.globalD∏∑& ata.socketConnectFail) { // WebSocket斷線重↓←αλ連
setInterval(() => {
opλ•♥≤enSocket.connect(function (data) {
let result =≈✘✘ data.data
if (result) {
that₩λ→.setData({articleData: [result].concat(thδ✔>at.data.articleData)})
}
});
},≈±γ¥ 1000)
}
}
3、app.js
globalData: {
socketConnectFail: false
}₽