Когда я разрабатывал клиент MQTT, используя библиотеку Paho MQTT C, почему сообщение приходит с использованием обратного вызова с использованием MQTTASYNC_SETCALLBACKS дважды? Ubuntu и запуск его на платформе Arm Linux. Тем не менее, я обнаружил, что клиентская программа дважды запускает функцию обратного вызова из -за одного сообщения , поэтому я должен очистить сообщение и The TeapName во время второго триггера обратного вызова, в противном случае произойдет ошибка сегментации . /> вот моя программа C. < /h2>
Код: Выделить всё
#include "MQTTAsync.h"
#include "string.h"
#include "stdio.h"
#include
#define SERVER_ADDRESS "192.168.10.100"
#define CLIENT_ID "MQTT_ZYX"
#define USER_NAME "MQTT_test"
#define PASSWORD "123456"
//连接断开回调函数
void cntlost(void* context, char* cause)
{
printf("connect lost\r\n");
printf("cause : %s", cause);
}
//接收到消息的回调函数
int messarri(void* context, char* topicName, int topicLen, MQTTAsync_message* message)
{
if(topicName!=NULL && (message->payload)!=NULL && message->payloadlen>0) {
printf("\r\nmessage arrive\r\n");
printf("topic is : %s\r\n", topicName);
printf("payload_len = %d\r\n", message->payloadlen);
printf("receive message : %.*s\r\n", message->payloadlen, message->payload);
message->payloadlen=0;
} else {
MQTTAsync_freeMessage(&message);
MQTTAsync_free(topicName);
}
return 0;
}
//发送完成回调函数
void delcomp(void* context, MQTTAsync_token token)
{
printf("delivery complete\r\n");
}
//连接成功回调函数
void on_connect(void* context, MQTTAsync_successData* response)
{
printf("connect success\r\n");
}
//连接失败回调函数
void on_connectFail(void* context, MQTTAsync_failureData* response)
{
printf("connect fail: %d\r\n", response->code);
}
//发布成功回调函数
void on_send(void* context, MQTTAsync_successData* response)
{
printf("send %s success\r\n", (char *)context);
}
//发布失败回调函数
void on_notsend(void* context, MQTTAsync_failureData* response)
{
printf("send %s failure: %d\r\n", (char *)context, response->code);
}
//订阅成功回调函数
void on_subscribe(void* context, MQTTAsync_successData* response)
{
printf("subscribe %s success\r\n", (char *)context);
}
//订阅失败回调函数
void on_dissubscribe(void* context, MQTTAsync_failureData* response)
{
printf("subscribe %s failure: %d\r\n", (char *)context, response->code);
}
//断开连接成功回调函数
void on_discon(void* context, MQTTAsync_successData* response)
{
printf("disconnect success\r\n");
}
//断开连接失败回调函数
void on_disconfail(void* context, MQTTAsync_failureData* response)
{
printf("disconnect failure: %d\r\n", response->code);
}
int main(int argc, char * argv[])
{
int ret=0;
MQTTAsync client; //客户端句柄
MQTTAsync_connectOptions con_opts=MQTTAsync_connectOptions_initializer; //连接选项
MQTTAsync_disconnectOptions discon_opts=MQTTAsync_disconnectOptions_initializer;
MQTTAsync_willOptions will_opts=MQTTAsync_willOptions_initializer; //遗嘱选项
MQTTAsync_responseOptions pub_resp_opts=MQTTAsync_responseOptions_initializer; //发布结果
MQTTAsync_responseOptions sub_resp_opts=MQTTAsync_responseOptions_initializer; //订阅结果
MQTTAsync_message mess=MQTTAsync_message_initializer; //发布消息结构体
/* 创建MQTT对象,若创建成功client不再是一个空指针*/
ret = MQTTAsync_create(&client, SERVER_ADDRESS, CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if(ret!=MQTTASYNC_SUCCESS) {
printf("client creat error\r\n");
return -1;
}
printf("creat success\r\n");
/* 设置回调函数*/
ret = MQTTAsync_setCallbacks(client, NULL, cntlost, messarri, delcomp);
if(ret!=MQTTASYNC_SUCCESS) {
printf("set callback error\r\n");
goto CREAT_ERROR;
}
/* 设置连接函数,连接到指定的MQTT服务器*/
//1.配置遗嘱参数
will_opts.topicName="zyx_topic/will";
will_opts.qos=1;
will_opts.retained=1;
will_opts.message="dev unexpected disconnect"; //设备意外掉线
//2.配置连接参数
con_opts.keepAliveInterval=45; // 心跳时间间隔,单位s
con_opts.cleansession=0; // 不清除会话,接收离线信息
con_opts.will=&will_opts;
con_opts.username=USER_NAME;
con_opts.password=PASSWORD;
con_opts.connectTimeout=30; //连接时间,默认是30s,这里和默认一致
con_opts.onSuccess=on_connect;
con_opts.onFailure=on_connectFail;
//3.连接
ret = MQTTAsync_connect(client, &con_opts);
if(ret!=MQTTASYNC_SUCCESS) {
printf("mqtt connect error: %d\r\n", ret);
goto CREAT_ERROR;
}
sleep(10);
/* 发布:向遗嘱主题发布消息,表示设备上线*/
char message[20]={0};
memcpy(message, "dev connect", sizeof("dev connect"));
pub_resp_opts.onSuccess=on_send;
pub_resp_opts.onFailure=on_notsend;
pub_resp_opts.context="zyx_topic/will";
mess.payload=message;
mess.payloadlen=strlen(message);
mess.qos=1;
mess.retained=1;
ret = MQTTAsync_sendMessage(client, "zyx_topic/will", &mess, &pub_resp_opts);
if(ret!=MQTTASYNC_SUCCESS) {
printf("mqtt send error: %d\r\n", ret);
}
/* 订阅:订阅led主题*/
sub_resp_opts.onSuccess=on_subscribe;
sub_resp_opts.onFailure=on_dissubscribe;
sub_resp_opts.context="zyx_topic/led";
MQTTAsync_subscribe(client, "zyx_topic/led", 1, &sub_resp_opts);
for(;;) {
sleep(10);
}
/* 断开连接*/
//discon_opts.timeout=10;
discon_opts.onSuccess=on_discon;
discon_opts.onFailure=on_disconfail;
MQTTAsync_disconnect(client, &discon_opts);
CREAT_ERROR:
MQTTAsync_destroy(&client);
return -1;
EXIT:
return 0;
}
. Первое, что не пропагандируется, без очистки сообщения и topicname , не будет неисправности сегментации второй раз, введя функцию обратного вызова.
Английский не является моим нативным языком, поэтому я надеюсь, что я надеюсь, что это достаточно ясное. Спасибо за вашу помощь.
Подробнее здесь: https://stackoverflow.com/questions/797 ... ered-twice
Мобильная версия