分类 MQTT 下的文章

“MQTT消息队列遥测传输(英语:Message Queuing Telemetry Transport)是ISO 标准(ISO/IEC PRF 20922)下基于发布 (Publish)/订阅 (Subscribe)范式的消息协议,可视为“资料传递的桥梁”它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议。”

在运行过程中,接收到
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表示异常断开。

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

执行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)

mosquitto 版本为mosquitto version 1.6.9,错误代码如下

/* Error values */
enum mosq_err_t {
    MOSQ_ERR_AUTH_CONTINUE = -4,
    MOSQ_ERR_NO_SUBSCRIBERS = -3,
    MOSQ_ERR_SUB_EXISTS = -2,
    MOSQ_ERR_CONN_PENDING = -1,
    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,
    MOSQ_ERR_PAYLOAD_SIZE = 9,
    MOSQ_ERR_NOT_SUPPORTED = 10,
    MOSQ_ERR_AUTH = 11,
    MOSQ_ERR_ACL_DENIED = 12,
    MOSQ_ERR_UNKNOWN = 13,
    MOSQ_ERR_ERRNO = 14,
    MOSQ_ERR_EAI = 15,
    MOSQ_ERR_PROXY = 16,
    MOSQ_ERR_PLUGIN_DEFER = 17,
    MOSQ_ERR_MALFORMED_UTF8 = 18,
    MOSQ_ERR_KEEPALIVE = 19,
    MOSQ_ERR_LOOKUP = 20,
    MOSQ_ERR_MALFORMED_PACKET = 21,
    MOSQ_ERR_DUPLICATE_PROPERTY = 22,
    MOSQ_ERR_TLS_HANDSHAKE = 23,
    MOSQ_ERR_QOS_NOT_SUPPORTED = 24,
    MOSQ_ERR_OVERSIZE_PACKET = 25,
    MOSQ_ERR_OCSP = 26,
    MOSQ_ERR_TIMEOUT = 27,
    MOSQ_ERR_RETAIN_NOT_SUPPORTED = 28,
    MOSQ_ERR_TOPIC_ALIAS_INVALID = 29,
    MOSQ_ERR_ADMINISTRATIVE_ACTION = 30,
    MOSQ_ERR_ALREADY_EXISTS = 31,
};

在运行程序时候,得到mosquitto_connect ret = 14 
经过诊断,应该是网络不通。。。