微信小程序使用原生WebSokcet实现断线重连及数据拼接
以前做小程序为了应急找了个插件去链接WebSokcet,文章传送门。
回过头在新项目中再次使用时出现了些许问题,不一一赘述。遂决定好好用一下原生的WebSokcet。
一、说明
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://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: Buffer2Base64(), // 用于订阅的参数,视具体情况而定
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 Base64String = String.fromCharCode.apply(null, new Uint8Array(data));
var Base64JsonStr = decodeURIComponent(base64_decode(Base64String));
return JSON.parse(Base64JsonStr);
} catch (err) {
console.log(err);
return false;
}
} function Buffer2Base64 () { // 用于订阅的参数,视具体情况而定
var packet = {};
packet["cmd"] = "subscribe";
packet["reqNo"] = "" + new Date().getTime();
packet["params"] = {token: token, channelId: 'xcx', columnIds: "1"};
return stringToBuffer(JSON.stringify(packet))
} function stringToBuffer (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).buffer;
} 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
}
function base64_decode (input) { // base64解码
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = base64EncodeChars.indexOf(input.charAt(i++));
enc2 = base64EncodeChars.indexOf(input.charAt(i++));
enc3 = base64EncodeChars.indexOf(input.charAt(i++));
enc4 = base64EncodeChars.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
return utf8_decode(output);
}
function utf8_decode (utftext) { // utf-8解码
var string = '';
let i = 0;
let c = 0;
let c1 = 0;
let c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c1 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
i += 2;
} else {
c1 = utftext.charCodeAt(i + 1);
c2 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
i += 3;
}
}
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
}
微信小程序使用原生WebSokcet实现断线重连及数据拼接的更多相关文章
- 微信小程序结合原生JS实现电商模板(二)
接 <微信小程序结合原生JS实现电商模板(一)>,在首页列表加入购物车到购物和模块增删数量,动态计算商品价格实现后,本次提交主要实现了商品详情(还不完善)简单页面,从商品详情页跳转到购物车 ...
- 微信小程序:原生热布局终将改变世界
关于本文的所有观点都是网上收集,与作者本人没有任何关系! 最近朋友圈已经被微信小程序刷屏了,这也难怪,腾讯的产品拥有广泛的影响力,谁便推出个东西,都会有很多人认为会改变世界,这不,张小龙刚一发布微信小 ...
- 【微信小程序】模仿58同城页面制作以及动态数据加载
完成动态数据的加载,如下 使用上班的空余时间慢慢的学习,相信总有一天我会很熟悉的掌握这门技术. 本次学习小总结: 微信小程序使用的代码基本与HTML.CSS.JS等前段有关知识一样. 微信小程序js使 ...
- 微信小程序之蓝牙开发(详细读数据、写数据、附源码)
本文将详细介绍微信小程序的蓝牙开发流程(附源码)准备:微信只支持低功耗蓝牙也就是蓝牙4.0,普通的蓝牙模块是用不了的,一定要注意. 蓝牙可以连TTL接到电脑上,再用XCOM调试 一开始定义的变量 va ...
- 微信小程序从子页面退回父页面时的数据传递 wx.navigateBack()
我们知道,在微信小程序中,从一个页面转到另一个页面,一般情况下可以通过navigate或redirect时候的url来携带参数,然后在目标页面的onLoad函数参数中获取这些url参数.例如: // ...
- 微信小程序使用页面栈改变上一页面的数据
微信小程序中如果从一个页面中进入下一个页面,如果下个页面的数据有删除或者增加再返回上一个页面的时候,就会导致页面不刷新(数据加载函数在onload中),从而造成数据不一致的情况.其实在微信小程序中是可 ...
- 微信小程序结合原生JS实现电商模板(一)
前几天遇到一个朋友求助,实现购物车的相关功能,一时心血来潮,想着抽空搭建一个小程序电商平台(虽然网上有很多,但还是自己撸一遍才是王道),所以在工作之余整了一个仓库,今天提交了第一次代码,已经满足了朋友 ...
- 微信小程序(五) 利用模板动态加载数据
利用模板动态加载数据,其实是对上一节静态数据替换成动态数据:
- 微信小程序如何修改本地缓存key中的单个数据
假如用户注册后,获得用户手机号和userid,realName默认为0,然后进入B页面进行实名认证,认证成功后realName变为1,再更新缓存里的用户信息. A页面用户注册后,存储用户信息: var ...
随机推荐
- python-映射·字典
1.创建字典:字典由键值对组成,每个键值对就是字典的一个元素,键值对之间用分号(:)隔开,元素之间用逗号(,)隔开.字典中的键必须是唯一 且不可变得(不可以是列表或者字典).字典中的元素是无序的. d ...
- Jetson tx1 安装cuda错误
前两天安装Jetpack3.0的时候,看着网上的教程以为cuda会自动安装上,但是历经好几次安装,都安装不上cuda,也刷了好几次jetpack包.搜遍了网上的教程,也没有安装上.错误如下图所示: 这 ...
- SHIFT(文字列の指定位置数の移動)
文字ごとの項目内容の移動 以下のような SHIFT 命令のバリアントを使用すると.項目内容を移動することができます.SHIFT を使用すると.文字ごとに項目内容が移動します. 文字列の指定位置数の移動 ...
- Sql Server 表间对应关系
<1>.关联映射:一对多/多对一 存在最普遍的映射关系,简单来讲就如球员与球队的关系:一对多:从球队角度来说一个球队拥有多个球员 即为一对多多对一:从球员角度来说多个球员属于一个球队 即为 ...
- PRO*C 函数事例 1 -- 数据库连接、事务处理
1.程序结构 每一个Pro*C程序都包括两部分:(1)应用程序首部:(2)应用程序体 应用程序首部定义了ORACLE数据库的有关变量, 为在C语言中操纵ORACLE数据库做 ...
- 在Go语言里检测内存泄漏
我们先来设定一下数据库,建立一个MySQL数据库表,名为users,里面有login_name.nickname.uid.password.forbidden几个字段,其中uid与forbidden为 ...
- Extjs报错:isField为空或不是对象
在做Extjs开发的时候,有时候会碰到一个奇怪的问题,就是报错说"isField为空或不是对象",经过调试发现是一个数组,显示的长度是21,但是数组里面的个数只有 ...
- Get Error when restoring database in Sql Server 2008 R2
When I restored a database I got an error: "The backup set holds a backup of a database ot ...
- Qt Qml 汽车仪表
上一个原文连接http://blog.csdn.net/z609932088/article/details/53946245 参考资料连接:链接: https://pan.baidu.com/s/1 ...
- linux常用命令补充详细
1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...