質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

コールバック

コールバックは他のコードに引数として渡されるコードのことを指します。

MQTT

MQTT(Message Queue Telemetry Transport)とは、TCP/IPネットワークで利用可能な通信プロトコルの一つで、IoT/M2M向けに開発された軽量なプロトコルです。ヘッダ部分は最小2バイトと小さく、通信量・CPU負荷・電力消費量などを抑えることができます。

Q&A

解決済

1回答

3931閲覧

MQTT:mosquittoのQoS1でコールバックが受信できない

HYDESA

総合スコア8

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

コールバック

コールバックは他のコードに引数として渡されるコードのことを指します。

MQTT

MQTT(Message Queue Telemetry Transport)とは、TCP/IPネットワークで利用可能な通信プロトコルの一つで、IoT/M2M向けに開発された軽量なプロトコルです。ヘッダ部分は最小2バイトと小さく、通信量・CPU負荷・電力消費量などを抑えることができます。

1グッド

0クリップ

投稿2021/06/10 06:50

編集2021/06/11 00:31

前提・実現したいこと

現在、MQTTのC言語、mosquittoを勉強中です。
ノートPC2台を置いて、1台はWindows10でBrokerとClient。
もう1台もWindows10ですが、開発・送信は
WLS2のubuntu20.24で行っています。

ところが、Qos=0だと下記のソースでうまく動くのですが、
QoS=1だとコールバックが受信されないため、
Whileのところで止まってしまいます。

発生している問題・エラーメッセージ

QoS=1だとコールバックを受け取れません。
ちなみにブローカはPowerShellにて

.\mosquitto -c test.conf -v // test.conf listener 1883 allow_anonymous true

イメージ説明

クライアント側もPowerShellにて

.\mosquitto_sub -h 192.168.0.116 -t TEST -d -q 1

イメージ説明
で実行していて、
受信するとPUBACKを返しています(Brokerも同様です)。

該当のソースコード

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <mosquitto.h> #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif char *topic = "TEST"; char *message = "Hello World"; char *id = "mqtt/pub"; char *host = "192.168.0.116"; int port = 1883; int keepalive = 0; int connect_desire = TRUE; /* debug mode flag */ int is_debug = TRUE; /* Brokerとの接続成功時に実行されるcallback関数 */ void on_connect(struct mosquitto *mosq, void *obj, int result) { if(is_debug) { printf("%s(%d)\n", __FUNCTION__, __LINE__); } mosquitto_connect(mosq, host, port, keepalive); } /* Brokerとの接続を切断した時に実行されるcallback関数 */ void on_disconnect(struct mosquitto *mosq, void *obj, int rc) { if(is_debug) { printf("%s(%d)\n", __FUNCTION__, __LINE__); } } /* BrokerにMQTTメッセージ送信後に実行されるcallback関数 */ static void on_publish(struct mosquitto *mosq, void *userdata, int mid) { printf("mid %d has completed publishing\n", mid); connect_desire = FALSE; mosquitto_disconnect(mosq); } /* mqtt_pubメイン関数 */ int main(int argc, char *argv[]) { int cnt = 2; int msgLen = 11; int charLength = cnt + msgLen + 2; char *cafile = NULL; char *certfile = NULL; char *keyfile = NULL; bool clean_session = true; struct mosquitto *mosq = NULL; char msg[charLength]; int status; if(is_debug) { printf(" %s\n", host); printf(" %d\n", port); printf(" %s\n", cafile); printf(" %s\n", certfile); printf(" %s\n", keyfile); printf(" %s\n", topic); printf(" %s\n", message); } mosquitto_lib_init(); mosq = mosquitto_new(id, clean_session, NULL); if(!mosq){ fprintf(stderr, "Cannot create mosquitto object\n"); mosquitto_lib_cleanup(); return(EXIT_FAILURE); } /* ブローカに接続コールバックを設定 */ printf("Connect_Clbk\n"); mosquitto_connect_callback_set(mosq, on_connect); /* ブローカに切断コールバックを設定 */ printf("Disconnect_Clbk\n"); mosquitto_disconnect_callback_set(mosq, on_disconnect); /* ブローカにパブリッシュコールバックを設定 */ printf("Publish_Clbk\n"); mosquitto_publish_callback_set(mosq, on_publish); for(int i=0;i<20;i++){ /* ブローカに接続 */ status = mosquitto_connect_bind(mosq, host, port, keepalive, NULL); if(status){ printf("Error (%d) connecting to broker.\n", status); return 3; } /* 送信内容セット */ snprintf(msg, charLength, "%s %02d", message,i); connect_desire = TRUE; /* 内容送信 */ printf("publishing...\n"); mosquitto_publish(mosq, NULL, topic, charLength, msg, 1, false); /* CallBack待ち */ while(connect_desire != FALSE){ continue; } usleep(30000); /* 1s = 1000000μs */ /* ブローカに応答依頼 */ printf("loop_start\n"); mosquitto_loop_forever(mosq, -1, 1); } /* Destroy */ printf("Destroy\n"); mosquitto_destroy(mosq); /* Cleanup */ printf("Cleanup\n"); mosquitto_lib_cleanup(); return(EXIT_SUCCESS); }

上記ソースから何か不足しているところがあれば
ご教示いただけると嬉しいです。

以上、よろしくお願い致します。

※追記:FireWall、セキュリティソフトともにブロック解除済みです

yuki23👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

mosquitto_loop を呼ばないとコールバックが呼ばれないのが原因だと思います。
ワーカースレッドを立てて mosquitto_loop_forever を実行するのが良いのではないかと思います。

投稿2021/06/11 06:00

yuki23

総合スコア1448

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HYDESA

2021/06/11 06:41

ご教示ありがとうございました。 無事にそれぞれのコールバックが受信できるようになりました。 大変助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問