最近在用mosca这个组件做聊天,遇到几个问题,望大神们指点: 1,moscaSettings中backend使用redis,离线数据各方面没有问题,但是发生了数据顺序错乱的情况 2,使用rabbitmq或者zeromq时,数据顺序正常,但是发生了在线收到的消息,再次登陆时,又发送了一遍,redis只会发一遍 qos在关注和发送时都设置为1 不知道是服务器设置的问题,还是本身的策略就是如此, 另外我们客户端的messageId在发送时都是int型的自增长,但是查看数据库中存储的离线消息messageId变成了随机字符串
-
数据错乱 如果你用的是
mosca
的redis
持久化,它取离线消息是lrange
拉取再forward
的,但是 redis 的离线只支持0 ~ 10000
之内的离线消息,且离线消息的TTL
是由用户自定义的,数据顺序乱世肯定会有的,你可以给每一条消息加一个创建时间来标记。 -
消息多发 并不是说
redis
会PUBLISH
多次,原因是因为你所使用的客户端库针对于在收到服务端推送的PUBISH
QoS1 消息报文时是否返回PUBACK
报文,如果服务器收到PUBACK
则认为这条消息已经成功送达客户端(该消息不是离线消息,下次客户端登录不在发送这个消息);否则,服务器则认为这条 QoS1 的消息未送达客户端(是离线消息,下次客户端重连后需要重发)。对于你提到的zeroMQ
和rabbitmq
,他们本身不是实现的 MQTT 协议,是不能与 以 MQTT 协议为基础的服务端 Mosca 对接上的,建议 web 端使用MQTT.js
,安卓端使用paho
来作为MQTT
客户端。 -
MessageId 离线消息都是 随机 ID 的,这是消息的唯一标识,他是通过 shortid 生产的唯一标识串,消息通过
PUBLISH
到一个客户端后,会调用这个forward
方法(其实就是往TCP 里面写入报文),在写入之前,会根据拿到一个的messageId
,该 ID 是自增长的Number
类型,且该 ID 不超过 65535,为什么是 0~65535 之间?这取决于可变报头最多容纳的字节数。 。最后,客户端收到服务器发送过来的报文,解析后,客户端必须向服务器返回PUBACK
报文,该报文必须携带该报文的标识符(即:该消息的 messageId),服务端最后根据 messageId 和 client identifiy 将该消息从离线消息队列中移除,如果未收到PUBACK
或PUBACK
报文携带的 messageId 有问题,则导致不能正确更改某一消息的 发送状态 ,这就是 QoS1 为什么会至少发送一次的原因。
你若想详细了解 Mosca 的工作原理,你必须全部明白 MQTT 协议,希望我的答案能给你尽绵薄之力。