溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

原生WebSokcet如何實(shí)現(xiàn)斷線重連及數(shù)據(jù)拼接

發(fā)布時(shí)間:2021-01-26 10:43:34 來源:億速云 閱讀:227 作者:小新 欄目:移動(dòng)開發(fā)

這篇文章給大家分享的是有關(guān)原生WebSokcet如何實(shí)現(xiàn)斷線重連及數(shù)據(jù)拼接的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

WebSocket protocol 是HTML5一種新的協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信(full-duplex)。

一、說明

1.小程序原生的WebSokcet沒有斷線重連機(jī)制,這個(gè)是他的不足之處。

2.小程序新的版本庫(kù)已經(jīng)支持存在多個(gè) WebSokcet 連接。

官方說明:基礎(chǔ)庫(kù) 1.7.0 之前,一個(gè)微信小程序同時(shí)只能有一個(gè) WebSocket 連接,如果當(dāng)前已存在一個(gè) WebSocket 連接,會(huì)自動(dòng)關(guān)閉該連接,并重新創(chuàng)建一個(gè) WebSocket 連接?;A(chǔ)庫(kù)版本 1.7.0 及以后,支持存在多個(gè) WebSokcet 連接,每次成功調(diào)用 wx.connectSocket 會(huì)返回一個(gè)新的 SocketTask。

官方文檔地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-socket.html#wxclosesocket

二、實(shí)際例子:

首先你需要socket地址url: let url = 'wss://http://xxx.xxx.com/?xxx=xxx'

注意:1.小程序管理后臺(tái)添加socket域名的時(shí)候不能出現(xiàn)端口;2.如果使用了appID,協(xié)議必須是 wss;3.socket服務(wù)端映射的端口僅支持 80 和 443,和公眾號(hào)一個(gè)尿性。

接下來放例子:

1、socket.js

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

  wx.onSocketOpen(function (res) { // 監(jiān)聽WebSocket連接打開事件。
      console.log('WebSocket打開成功');
      wx.sendSocketMessage({ // 通過 WebSocket 連接發(fā)送數(shù)據(jù),需要先 wx.connectSocket,并在 wx.onSocketOpen 回調(diào)之后才能發(fā)送。
          data: String2Base64(), // 用于訂閱的參數(shù),視具體情況而定
          success (data) {
              console.log('WebSocket發(fā)送消息:', data.errMsg)
},
          fail (err) {
              console.log('Err', err)
}
})

})

  wx.onSocketMessage(function (res) { // 監(jiān)聽WebSocket接受到服務(wù)器的消息事件。
      console.log('WebSocket接收到消息:', ArryBuffer2Json(res.data));
      cb(ArryBuffer2Json(res.data)); // 將接收到的消息進(jìn)行回調(diào),如果是ArryBuffer,需要進(jìn)行轉(zhuǎn)換
})

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

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

function ArryBuffer2Json (data) { // ArryBuffer轉(zhuǎn)換成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 () { // 用于訂閱的參數(shù),視具體情況而定
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轉(zhuǎn)碼
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)}) // 將獲得的socket推送消息拼接到當(dāng)前文章列表的最前面
}
});
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}

感謝各位的閱讀!關(guān)于“原生WebSokcet如何實(shí)現(xiàn)斷線重連及數(shù)據(jù)拼接”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI