mqtt是什么?
MQTT是一个轻量级传输协议
,它被设计用于轻量级的发布/订阅式消息传输
,MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化。是一种简单、稳定、开放、轻量级易于实现的消息协议,在物联网
的应用下的信息采集
,工业控制
,智能家居
等方面具有广泛的适用性。
谁发布
,谁订阅
?
MQTT服务器类似一个公告栏,里面张贴了各种广告。张三跑过来说,凡是涉及足球的(/public/TEST/Soccer)的都发给自己(订阅)第二天,李四过来贴广告了,主题是(/public/TEST/Soccer),发布的内容是“30号有比赛”此时,公告栏会自动发短信给张三,发送的信息为 “30号有比赛”张三:APP端;李四:设备端;公告栏:云端的MQTT服务器
mqtt优点?
1、MQTT更加简单:
MQTT是一种消息队列协议,使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合,相对于其他协议,开发更简单;
2、MQTT网络更加稳定
工作在TCP/IP协议上;由TCP/IP协议提供稳定的网络连接;
3、轻量级
小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;适合低带宽,数据量较小的应用;
MQTT和Websocket的区别是什么?
-
MQTT
是为了物联网场景设计的基于TCP的Pub/Sub协议,有许多为物联网
优化的特性,比如适应不同网络的QoS、层级主题、遗言等等。 -
WebSocket
是为了HTML5
应用方便与服务器双向通讯而设计的协议,HTTP握手然后转TCP协议,用于取代之前的Server Push、Comet、长轮询
等老旧实现。两者之所有有交集,是因为一个应用场景:如何通过HTML5应用来作为MQTT的客户端,以便接受设备消息或者向设备发送信息,那么MQTT over WebSocket自然成了最合理的途径了。
如何适用mqtt去实现聊天功能?
- 首先我们从前端布局样式开始

为了时时滚动到最新消息我们使用 scroll-view 标签包裹 使用它的
scroll-into-view
属性我们绑定一个自定义id
如图:
我们在创建的元素上绑定一个 id
属性,scroll-view
即可自动滚动到其对应位置。
以上就是几种不同消息类型的展示,我们先不考虑类型的样式,我们先来实现聊天左右分布的布局
推荐大家使用
flex
布局去实现
左侧医生:display: flex;justify-content: flex-start;
(默认属性)
右侧患者:display: flex;justify-content: flex-end;
(尾部对齐)
样式方面主要也就是这两个属性,其他消息类型的,也是在这基础上做修改即可。
2.连接 mqtt
首先我们要引入依赖
var Paho = require('./utils/paho-mqtt-wx.js')
var Paho = require('./utils/paho-mqtt-wx.js')/*** 连接 mqtt*/
connectMqtt() {// let t = '异常断线';var t = {}t.i = this.globalData.connectParams.msgTopicNamet.c = 0t.t = 3// console.log(t, 98)const message = new Paho.Message(JSON.stringify(t))this.connectOptions = {}//连接mqtt用户名this.connectOptions.userName = api.mqttuser //连接mqtt密码this.connectOptions.password = api.mqttpass //遗嘱消息 当客户端断开连接时,发送给相关的订阅者的遗嘱消息this.connectOptions.willMessage = message //心跳保持时间 是一种用于MQTT 的 长连接机制。this.connectOptions.keepAliveInterval = 10 //断开连接时是否要清除sessionthis.connectOptions.cleanSession = this.globalData.connectParams.cleanSession//设置如果连接丢失,客户端是否自动尝试重新连接到服务器this.connectOptions.reconnect = false //连接成功回调this.connectOptions.onSuccess = this.onConnect //连接失败回调this.connectOptions.onFailure = this.failConnect this.client = new Paho.Client('wss://' + this.globalData.connectParams.dnHost + '/mqtt', this.globalData.connectParams.clientId)//当客户端失去连接时调用this.client.onConnectionLost = this.onConnectionLost this.client.onMessageArrived = this.onMessageArrived//与服务器建立连接this.client.connect(this.connectOptions)
},
onConnect(){console.log('连接成功 - onSuccess')//订阅this.client.subscribe(this.globalData.connectParams.msgTopicName) //订阅// var t = '上线';var t = {}t.i = this.globalData.connectParams.msgTopicNamet.c = 0t.t = 0const message = new Paho.Message(JSON.stringify(t))message.destinationName = this.globalData.connectParams.statusTopicName //发送上线消息this.client.send(message)
}
failConnect(){// 从新连接console.log('连接失败 - onFailure')
}
onMessageArrived(message){console.log('mqtt消息到达 - onMessageArrived:', message)
}
onConnectionLost(response){// 从新连接console.log('mqtt失去连接 - responseObject:', response)
}
以上我们完成mqtt连接操作,以及一些事件监听。
发送消息以及聊天记录缓存处理?
到这里就已经是聊天功能的核心了
首先是消息分组,消息按发送时间段去缓存分组,实现起来的思路大概就是,当我们
发送
或者收到
消息的时候
我们只需要拿当前你要发送或者你接受的消息发送时间(endTime)去与我们本地缓存记录的最新一条消息去做对比
//举个栗子
//最新消息的发送时间
let newEndtime = 1624418176356,//本地缓存最新消息发送时间
oldEndtime = 1624418212889 //120000(毫秒)2分钟newEndtime - oldEndtime <= 120000 ? 创建新分组 : 当前分组添加消息
时间分组的实现思路就是这样,我们只需要根据消息发送时间去计算,判断是不是两分钟内的消息,如果是我们直接在当前消息分组(
messageArr[messageArr.length-1].messages.Push
)一条新消息,如果大于两分钟了,我们就直接从新创建一个分组,也就是messageArr.Push
,Push过在把最新消息更新到本地历史消息即可。
历史消息上拉加载?
本地存储
数据与服务端数据混合加载
,因小程序本地存储限制我们前端只存100条聊天数据,本地的数据加载完以后,在上拉我们就要调用分页去获取历史消息了,
注意了:历史消息的分页,会有一个分页参数就是我们messageArr消息记录最后一条消息的endTime(发送时间),然后把服务端返回历史消息合并到我们messageArr里,消息加载总体就这些逻辑,
以上步骤我们就可以实现一个基本的聊天功能了 思路大体就是这样 有疑问的同学可以私信我
