微信小程序使用原生WebSokcet实现断线重连及数据拼接

| 2018-01-26 11:08:22

一、说明


1.小程序原生的WebSokcet没有断线重连机制,这个是他的不足之处。


2.小程序新的版本库已经支持存在多个 WebSokcet 连接。


官方说明:基础库 1.7.0 之前,一个微信小程序同时只能有一个 WebSocket 连接,如果当前已存在一个 WebSocket 连接,会自动关闭该连接,并重新创建一个 WebSocket 连接。基础库版本 1.7.0 及以后,支持存在多个 WebSokcet 连接,每次成功调用 wx.connectSocket 会返回一个新的 SocketTask。


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




二、实际例子:


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


注意:1.小程序管理后台添加socket域名的时候不能出现端口;2.如果使用了appID,协议必须是 wss;3.socket服务端映射的端口仅支持 80 和 443,和公众号一个尿性。


接下来放例子:


1、socket.js


const app = getApp();

let url = 'wss://xxx.xxx.com/?xxx=xxx'

export const connect = function (cb) { // 定义一个方法

   wx.connectSocket({ // 创建一个 WebSocket 连接

       url: url,

       fail (err) {

if (err) {

               console.log('%cWebSocket连接失败', 'color:red', err)

               app.globalData.socketConnectFail = true // 定义一个全局变量,当链接失败时改变变量的值

}

}

})


   wx.onSocketOpen(function (res) { // 监听WebSocket连接打开事件。

       console.log('WebSocket打开成功');

       wx.sendSocketMessage({ // 通过 WebSocket 连接发送数据,需要先 wx.connectSocket,并在 wx.onSocketOpen 回调之后才能发送。

           data: String2Base64(), // 用于订阅的参数,视具体情况而定

           success (data) {

               console.log('WebSocket发送消息:', data.errMsg)

},

           fail (err) {

               console.log('Err', err)

}

})


})


   wx.onSocketMessage(function (res) { // 监听WebSocket接受到服务器的消息事件。

       console.log('WebSocket接收到消息:', ArryBuffer2Json(res.data));

       cb(ArryBuffer2Json(res.data)); // 将接收到的消息进行回调,如果是ArryBuffer,需要进行转换

})


   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 () { // 用于订阅的参数,视具体情况而定

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)}) // 将获得的socket推送消息拼接到当前文章列表的最前面

}

});

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

}


文 / 网盛    阅:662

免费获取网站建设与品牌策划方案报价

在线预约享受建站8

  • 公司名称
  • 手机号码
  • 网站类型
  • 所在城市
  • 联系人
  • 需求

在线
客服

在线客服服务时间:9:00-17:00

客服
热线

024-83959235
建站服务热线

关注
微信

关注官方微信
顶部
在线客服