uniapp,微信小程序中使用 MQTT
最近在uniapp打包成微信小程序的项目中第一次用到了MQTT。使用比较简单,但是还是遇到了一些问题。在此记录一下。
官方文档:MQTT Github
MQTT的js文件:mqtt.min.js
先上一点注意事项:
(1) MQTT.js 一个 MQTT 协议的客户端库,用 JavaScript 编写,可用于 Node.js 和浏览器。在 Node.js 端可以通过全局安装使用命令行连接,同时还支持 MQTT ,MQTT TLS 证书连接;值得一提的是 MQTT.js 还对微信小程序有较好的支持。
(2) MQTT可以通过三种方式连接,TCP直连, TLS和WebSocket,但是JavaScript使用 TCP 只能通过 ws 即 Websocket 链接。所以如果服务器是TCP直连,客户端是肯定连不上的,会报 Error in connection establishment 的错误。所以客户端协议只能是ws,wss,wxs(微信)
(3) WebSocket 是一种在单个 TCP 连接上进行全双工通讯的协议。作为一种通信协议,其使用 ws(非加密)、wss(SSL 加密) 作为协议标识。MQTT.js 客户端支持多种协议,连接地址需指明协议类型;
(4) ws: 未加密的 WebSocket 连接,一般使用8083端口。wss: 加密的 WebSocket 连接,一般使用8084端口。mqtt: 未加密的 TCP 连接,一般使用1883端口。mqtts: 加密 TCP 连接。
贴一下代码:
import $mqtt from './mqtt.min.js';
const mqttOptions = {
keepalive: 30,
clean: false,
connectTimeout: 5000, // Timeout
clientId: uni.getStorageSync('clientId'),
// username: 'test',
// password: 'test',
}
const connectUrl = `${mqttHost}:${mqttPort}/mqtt`;
// #ifdef H5
var client = $mqtt.connect('wss://' + connectUrl, mqttOptions);
// #endif
// #ifdef MP-WEIXIN||APP-PLUS
var client = $mqtt.connect('wxs://' + connectUrl, mqttOptions);
// #endif
client.on('connect', () => {
console.log('connect')
// 这是为了给自己发条消息,其它无作用
client.subscribe('test', (err) => {
if (!err) {
client.publish('test', '{}')
}
})
});
// 自动重连
client.on('reconnect', (msg) => {
console.log('reconnect', msg)
});
// 错误
client.on('error', () => {
console.log('error')
});
// 断开
client.on('end', () => {
console.log('end')
});
// 掉线
client.on('offline', (msg) => {
console.log('offline',msg)
});
// 收到消息
client.on('message', (topic, message) => {
// 把arrayBuffer转成字符串
let encodedString = String.fromCharCode.apply(null, new Uint8Array(message));// 全局发送消息
uni.$emit('sendTopicMsg',encodedString);
console.log(encodedString)
})
// 全局监听是否有关闭mqtt的消息的事件
uni.$on('closeMqtt',() => {
client.end(true); // 主动断开连接
})
说明:
(1) 配置项里的 keepAlive 指的是心跳时间。以秒为单位。定义服务端从客户端接收到消息的最大间隔时间。可以设置为0,表示客户端一直不断开,除非主动断开。
(2) clean 设置为false,是为了让客户端掉线的时候,服务器必须在客户端断开之后继续存储/保持客户端的订阅状态。即当为true的时候,如果掉线了,服务端会清理链接状态的数据和内容。当为false的时候,服务端会保存消息发送期间,链接断开导致发送失败的消息。这样连上的时候就会自动推送到订阅的客户端。
(3) 如果连接需要验证用户名和密码,则需要加上username和password字段。
(4) 微信小程序使用的协议,如果不是加密的,则是 wss,如果是加密的,就是 wxs。web端,一般不加密就是 wx,加密就是wss。
(5) 前端收到的消息是 arrayBuffer 格式的,需要转成字符串格式,如果带有中文,可能转成字符串会乱码。可以使用 let decodeString = decodeURIComponent(escape((encodedString))) 来避免中文乱码。或者是网上通过移位转成中文的方法来解决。
(6) clientId 是使用 Math.random().toString(36).substr(3,自定义长度) 来生成自定义长度的的唯一id。
应该是免费的测试MQTT消息的链接: o(∩_∩)o
| 协议 | 地址 | 端口 | 路径 | 证书 |
| mqtt | broker.hivemq.com | 8000 | 无 | 无 |
| mqtt | broker.emqx.io | 1883 | 无 | 无 |
| ws | test.mosquitto.org | 8080 | /mqtt | 无 |
| wss | test.mosquitto.org | 8081 | /mqtt | CA signed server |
(1) CA signed server 这个直接在MQTTX测试工具里面 选择 SSL/TLS 勾选为true时即可选择。
(2) 测试的时候,先填好内容,然后链接上的时候,再添加一个订阅,Topic就填一会你需要发送消息的Topic,这样当你模拟服务器发送消息的时候,MQTTX里面也会收到你刚才发送的内容,这样就是连通了。
开发过程中遇到的问题:
(1) 如果出现 failed: Connection closed before receiving a handshake response 这个错误。说明 服务端的 mqtt 协议和客户端的协议不一样,就比如 python用的是基于 tcp 的 mqtt ,js是基于websocket 的 mqtt ,都不能达成握手的操作。出现这个的问题应该是:服务端使用了 1883 这个端口,而客户端也是用这个端口,就导致这个问题。正确的应该是:客户端(js)应该使用 8083 端口(未加密)。
(2) 最初我设置心跳时间是3秒,在微信开发者工具,或者H5端的时候,是没有问题的。但是在小程序真机调试里,当小程序切换到后台,差不多5s就会自动断开,然后一直重连,直到切换回小程序,重连成功。而且有时候还会连续断开和重连。自动断网这个原因,小程序官网做了说明的:超过5s断网说明 在第二条 网络请求 - 使用限制里面就说明了,小程序的机制,限制了切换到后台之后网络的处理。所以把心跳时间改为30s,让 mqtt 30秒之后再自动重连。但是这样只是为了让体验稍微好一点,不会出现切换出去5s就断开链接,再切回来一直提示重连的问题。不过可以把心跳时间改为0,表示一直连接不断开。
总结:
(1)以上对mqtt的了解也只是一知半解,还没弄明白这里的心跳时间,和 TCP/IP 的心跳机制是不是一样的。超过心跳时间,能不能让客户端不掉线,或者有没有更好的解决离线的办法。
(2)而且还有很多特性都没用到,比如will遗愿标志,专门用来处理客户端断开连接的配置项。
(3)由于这个项目都是用的Qos0的消息,都不知道与Qos1,Qos2的区别是什么。
先暂时记录到这里,后面弄懂了再补充。
uniapp,微信小程序中使用 MQTT的更多相关文章
- 【重点突破】—— UniApp微信小程序开发教程学习Three
一.实战 HBuilderX:在微信小程序中运行页面,需要设置->安全 开启微信小程序服务端口,HBuilder工具->设置->配置程序路径 网络请求.模板语法.打开页面.页面传参 ...
- 网页或微信小程序中使元素占满整个屏幕高度
在项目中经常要用到一个容器元素占满屏幕高度和宽度,然后再在这个容器元素里放置其他元素. 宽度很简单就是width:100% 但是高度呢,我们知道的是height:100%必须是在父元素的高度给定了的情 ...
- 在微信小程序中使用富文本转化插件wxParse
在微信小程序中我们往往需要展示一些丰富的页面内容,包括图片.文本等,基本上要求能够解析常规的HTML最好,由于微信的视图标签和HTML标签不一样,但是也有相对应的关系,因此有人把HTML转换做成了一个 ...
- 微信小程序中发送模版消息注意事项
在微信小程序中发送模版消息 参考微信公众平台Api文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#模版消息管理 此参考地址 ...
- 微信小程序中placeholder的样式
通常,现代浏览器大多支持::placeholder选择器,用于设置placeholder的样式,但是在微信小程序中并不支持这种方式,而是提供了一个专门的属性(placeholder-class)来处理 ...
- 微信小程序中转义字符的处理
在微信小程序开发过程中,有时候会用到常用的一些特殊字符如:‘<’.‘>’.‘&’.‘空格’等,微信小程序同样支持对转义字符的处理,下面提供两种方法用来处理微信小程序中转义字符的处理 ...
- 微信小程序中用户登录和登录态维护
提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件. 让用户 ...
- 微信小程序中的组件使用1
不管是vue还是react中,都在强调组件思想,同样,在微信小程序中也是使用组件思想来实现页面复用的,下面就简单介绍一下微信小程序中的组件思想. 组件定义与使用 要使用组件,首先需要有组件页面和使用组 ...
- 微信小程序中如何使用WebSocket实现长连接(含完整源码)
本文由腾讯云技术团队原创,感谢作者的分享. 1.前言 微信小程序提供了一套在微信上运行小程序的解决方案,有比较完整的框架.组件以及 API,在这个平台上面的想象空间很大.腾讯云研究了一番之后,发现 ...
随机推荐
- centos 7 c++连接mysql的常用函数说明及使用样例
以下函数使用之前需安装mysql,并包含mysql.h头文件,设置好mysqlclient动态库 一.mysql_init() MYSQL * mysql_init(MYSQL *mysql); // ...
- .Net Core微服务入门全纪录(一)——项目搭建
前言 写这篇博客主要目的是记录一下自己的学习过程,只能是简单入门级别的,因为水平有限就写到哪算哪吧,写的不对之处欢迎指正. 什么是微服务? 关于微服务的概念解释网上有很多... 个人理解,微服务是一种 ...
- router路由配置
vue项目中router路由配置 介绍 路由:控制组件之间的跳转,不会实现请求.不用页面刷新,直接跳转-切换组件>>> 安装 本地环境安装路由插件vue-router: c ...
- Nginx深入浅出
一级标题为思维导图的链接 :) 1. Nginx简介 1.1 nginx概述 说明(C10K) 程序架构(master/worker) nginx的特性 文件并发处理(异步.事件驱动)epoll / ...
- Excel常用公式大全
公式是单个或多个函数的结合运用. AND “与”运算,返回逻辑值,仅当有参数的结果均为逻辑“真(TRUE)”时返回逻辑“真(TRUE)”,反之返回逻辑“假(FALSE)”. 条件判断 AVERAGE ...
- C++_继承
C++支持单继承和多继承,并提供3类继承:public.private及protected.在public继承中,每个派生类对象都是基类对象,反之基类对象却不是派生类对象.派生类成员无法直接访问基本的 ...
- vmware 虚拟机安装失败如何解决
1.最好安装在默认路径2,安装之前先卸载之前安装的软件,卸载使用最经典的Windows软件卸载工具Windows install clean up其他方式的卸载我使用了很多次都不行,网上很多方法都看了 ...
- 题解 - 【NOI2015】维修数列
题面大意: 使用平衡树维护一个数列,支持插入,修改,删除,翻转,求和,求最大和这 \(6\) 个操作. 题意分析: Splay 裸题,几乎各种操作都有了,这个代码就发给大家当个模板吧. 最后求最大和的 ...
- Ajax 下载文件 文件被损坏
问题表现 Ajax 下载文件成功后,打开提示格式损坏,源代码如下: axios({ method: 'get', url: "/public/工作簿1.xlsx", // 静态资源 ...
- list 迭代器的用法
string strTemp; list<string> strList; char *ch = new char[]; strcpy( ch , ""); strTe ...