标签 mqtt 下的文章

“”

在运行过程中,接收到
on_disconnect callback rc = 19
on_connect callback rc = 0

mqtt disconnect rc = 19

网上没有查到相关的错误说明。

官方api
rc integer value indicating the reason for the disconnect. A value of 0 means the client has called mosquitto_disconnect. Any other value indicates that the disconnect is unexpected.

只说非0表示异常断开。

怀疑是网络异常断开导致,自动能重连恢复。

连接mqtt broker过程中出现rc为14
on_disconnect callback rc = 14

需要注意的是,mqtt重连会导致订阅失效。

This is because you get a fresh session by default when you reconnect
(because you have clean_session=True), so you have no active
subscriptions.

Move the call to client.subscribe('topic') to inside the on_connect
callback then it will resubscribe when it reconnects.

上面虽然说的是paho,但mosquitto其实也是一样的。在mosquitto_new(const char id,bool clean_session,void obj)中,

clean_session    
set to true to instruct the broker to clean all messages and subscriptions on disconnect, false to instruct it to keep them.  See the man page mqtt(7) for more details.  Note that a client will never discard its own outgoing messages on disconnect.  Calling mosquitto_connect or mosquitto_reconnect will cause the messages to be resent.  Use mosquitto_reinitialise to reset a client to its original state.  Must be set to true if the id parameter is NULL.

如果id为空,则clean_session为true。

所以每次连接成功后,需要重新订阅,即在on_connect()中mosquitto_subscribe

on_connect
a callback function in the following form: void callback(struct mosquitto mosq, void obj, int rc)
Callback Parameters
mosq the mosquitto instance making the callback.
obj the user data provided in mosquitto_new
rc the return code of the connection response. The values are defined by the MQTT protocol version in use. For MQTT v5.0, look at section 3.2.2.2 Connect Reason code: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html For MQTT v3.1.1, look at section 3.2.2.3 Connect Return code: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
mosquitto_subscribe
Subscribe to a topic.

It is valid to use this function for clients using all MQTT protocol versions. If you need to set MQTT v5 SUBSCRIBE properties, use mosquitto_subscribe_v5 instead.

Parameters
mosq a valid mosquitto instance.
mid a pointer to an int. If not NULL, the function will set this to the message id of this particular message. This can be then used with the subscribe callback to determine when the message has been sent.
sub the subscription pattern.
qos the requested Quality of Service for this subscription.

执行mosquitto_loop_forever时,返回错误值8。
查看相应的头文件

MOSQ_ERR_SUCCESS = 0,
MOSQ_ERR_NOMEM = 1,
MOSQ_ERR_PROTOCOL = 2,
MOSQ_ERR_INVAL = 3,
MOSQ_ERR_NO_CONN = 4,
MOSQ_ERR_CONN_REFUSED = 5,
MOSQ_ERR_NOT_FOUND = 6,
MOSQ_ERR_CONN_LOST = 7,
MOSQ_ERR_TLS = 8,

错误号8为TLS相关的错误。

使用mosquitto_pub测试,提示如下错误:

Client const.net.cn sending CONNECT
OpenSSL Error[0]: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
Error: A TLS error occurred.

证书应该是合法的,问题可能出在时间上。

date

Fri Dec 6 08:59:02 CST 2019

ntpdate time.apple.com

29 Jul 12:02:53 ntpdate[26987]: step time server 17.253.84.123 offset +51937409.969086 sec

date

Thu Jul 29 12:03:06 CST 2021

再执行mosquitto_pub就正常了。

Client const.net.cn sending CONNECT
Client const.net.cn received CONNACK (0)
Client const.net.cn sending PUBLISH (d0, q2, r0, m1, 'command///req/reqid-7', ... (29 bytes))
Client const.net.cn received PUBREC (Mid: 1)
Client const.net.cn sending PUBREL (m1)
Client const.net.cn received PUBCOMP (Mid: 1, RC:0)
Client const.net.cn sending DISCONNECT

查看函数:
int mosquitto_publish(struct mosquitto *mosq,int *mid,const char *topic,int payloadlen,const void * payload,int qos,bool retain)

关于mid的说明

mid    pointer to an int.  If not NULL, the function will set this to the message id of this particular message.  This can be then used with the publish callback to determine when the message has been sent.  Note that although the MQTT protocol doesn’t use message ids for messages with QoS=0, libmosquitto assigns them message ids so they can be tracked with this parameter.

大致意思就是可以在回调函数中跟踪到本条信息具体发送时间。即使用QoS为0的情况下,也能正常跟踪。

同样,在mosquitto_sub中也有这个功能。

mid    a pointer to an int.  If not NULL, the function will set this to the message id of this particular message.  This can be then used with the subscribe callback to determine when the message has been sent.

都是在回调函数中使用。

on_subscribe(struct mosquitto *mq, void *obj, int mid, int qos_count, const int * granted_qos)