MQTTプロトコルを理解し適用することは、IoTの分野で重要なスキルです。デバイスとサーバー間の安定した接続を確保するためには、MQTTクライアントの自動再接続機能を深く理解し、効果的に適用する必要があります。以下では、神秘的な冒険島を探索するかのように、MQTTプロトコルと再接続メカニズムを掘り下げてみましょう。
MQTTは、TCPプロトコルに基づくパブリッシュ/サブスクライブモデルプロトコルです。モノのインターネット、センサーネットワーク、その他の低帯域幅で不安定なネットワーク環境をナビゲートする船のようなものです。しかし、海の波と同様に、ネットワーク環境には課題があります。ネットワーク障害、信号の低下、データのパケット損失など、MQTTクライアントとサーバー間の接続が中断される可能性があります。モノのインターネットの海では、ネットワーク環境の悪さやネットワークの切断、サーバーのアップグレード、デバイスやクライアントの再起動、その他のネットワーク要因などが頻繁に発生します。
このような状況では、“ボート”(MQTTクライアント)が常に“ポート”(サーバー)と安定した接続を維持できるようにするにはどうすればよいでしょうか。その答えは、自動ナビゲーションシステム、MQTTクライアントの自動再接続ロジックを船に装備する必要があるということです。
優れたMQTTクライアントの再接続ロジックを設計することは、堅牢な船を構築するようなものです。設計が不合理であれば、私たちの“船”はナビゲーションを失い、沈黙はもはや“港”からのメッセージを受信しなくなり、頻繁に再接続しようとして無意識のうちに私たちの“港”を攻撃するかもしれません。これは海で頭のない急いでいるようなもので、自分のエネルギーを消費するだけでなく、“港”に不必要な圧力をもたらします。しかし、私たちの再接続ロジックが適切に設計されていれば、私たちの“船”は着実に自律的に航行し、港を見つけ、接続を維持することができます。
MQTTクライアントの再接続ロジックを設計する際には、いくつかの重要な要素を考慮する必要があります。
- 航海時間の確保MQTTでは、これをKeep Aliveと呼びます。これは、私たちの“船”が“港”に接続しているかどうかを定期的にチェックするタイマーです。実際のネットワーク環境とアプリケーションのニーズに応じて、適切なKeep Aliveをセットアップする必要があります。
- 再接続戦略と撤退船が港との接続を失った場合、すぐに再接続しようとするのではなく、資源を過剰に消費しないように合理的な待機時間を設定する必要があります。船が海で迷ったときに、一時停止して風を観察し、電流を測定し、新しいルートを計画するようなものです。これは、指数バックオフアルゴリズムやステップ遅延戦略を使用して実現できます。
- 接続状態の管理私たちの“船”には、“港”との接続状況、接続が切断された理由、購読された情報などの重要な情報を記録する航海日誌が必要です。接続が切断された場合、私たちの“船”はログを見て、接続が切断された理由を分析し、“港”を再接続しようとします。
- 例外処理航海中、当社の“船”は、“港”が利用できない、認証の失敗、ネットワークの異常など、さまざまな問題に遭遇する可能性があります。私たちの船には、これらの問題に対処するためのコンティンジェンシープランが必要です。例えば、“港”が利用できない場合、当社の“船”は別の“港”を探す必要があります。認証が失敗した場合、当社の“船”は自身の認証情報が正しいかどうかを確認する必要があります。ネットワークが異常な場合、当社の“船”はネットワークが正常に戻るまで航行を一時停止する必要があります。
- 最大試行回数の制限低消費電力デバイスによっては、デバイスの電力を過剰に消費しないように、再接続の試行回数を制限することを検討する必要があります。海での“船”のように、何度も試みても“港”が見つからないと、より良い航海条件を待つために一時停止する必要があるかもしれません。
この自動ナビゲーションシステム(MQTTクライアントの自動再接続ロジック)を設計することで、当社の船はIoTの海をナビゲートすることができ、課題にかかわらず常に港への安定した接続を維持し、アプリケーションをスムーズに実行することができます。
実際のケースを見てみましょうPaho MQTT Cライブラリを例にとってみましょう。これは、自動ナビゲーションシステムの動作を実際の状況に合わせて設定することができるコールバック関数という豊富なナビゲーションツールセットを提供します。Pahoはグローバルコールバック、APIコールバック、非同期メソッドコールバックを提供しており、さまざまな状況でポートへの接続を維持することができる。
これは、モノのインターネットの海を航海する方法の物語です。このストーリーがMQTTプロトコルと再接続メカニズムをよりよく理解するのに役立ち、あなたの“船”がモノのインターネットの海をナビゲートできることを願っています。
/** *****************************************************************************
* Copyright c 2012 2022 IBM Corp.イアン·クラグス
*
* すべての権利を保持。この手順と付随する情報
* Eclipse Public License v 2.0による
* とEclipse Distribution License v 1.0の条項で提供されます。
*
* Eclipse Public Licenseは以下のサイトで入手できます。
* https://www.eclipse.org/legal/epl-2.0/
* Eclipseディストリビューションのライセンスは以下のサイトで入手できます。
* http//www.eclipse.org/org/documents/edl-v10.php。
*
*******************************************************************************/
#include stdio.h>
#include stdlib.h>
#include string.h>
#include "MTAc.h"
#もし! defined_WIN32
#include unistd.h>
#elseさん
#include windows.h>
#endif
#if ined_WRS_KERNEL
#include OsWper.h>
#endif
//ブローカーアドレスやクライアントIDなど、使用するMQTT接続パラメータを定義します。
#define ADDRESS “tcp//broker.emqx.io 1883”
#define Clientid PahoClientSub"
#define TOPIC “nanomq/test”
#defineペイロード “Hello World! "
#QoSの定義 1
#define TIMEOUT 10000リットル
//メインスレッドで論理フラグを定義する
int disc_finished = 0;
int subscribed = 0;
int finished = 0;
//APIコールバック関数の最初の宣言
onConnect
void onConnectFailure void* context MHTTAsync_failureData * response;
void onSubscribe void* context MHTTAsync_successData * response;
void onSubscribeFailure void* context MHTTAsync_failureData * response;
以下の2つはAsyncが使用するコールバック関数です。
//非同期接続成功コールバック関数は、接続成功時にサブスクライブ操作を行います。
conn_est
{
f\n"nClose;
MTA = MTAcontext;
MTA_onseOptions opts = MTA_onseOptions_inalizer;
略称はRRC。
printf "接続は成功しました\n";
printf "サブスクライブトピック%s\nクライアント%sを使用してQoS%d\n"
“Q Enterキーを押して終了\n\n\n "TOPIC CLIENTID QOS;
opts.on Success = onSubscribe;
opts.onure = onribeure;
opts.context = client;
if rc = MTA_subscTOPIC QOS opts!= MQTTASYNC_SUCCESS)
{
printf "サブスクリプション開始に失敗しました。リターンコード%d\n" rc;
完成度= 1。
}
}
//非同期接続がDisconnectメッセージを受信したときのコールバック。ほとんどの切断ではDisconnectメッセージが受信されないため、このメソッドはめったにトリガーされません。
void disconnect_lost void* context MQTProperties
enum Reasones reasonCode
{
printf "クライアントは切断されました!\ N 'N';
}
//以下は、接続切断とメッセージ到着のためのクライアントグローバルコールバック関数です。
void conn_lost void *context char *cause
{
MTA = MTAcontext;
MTA_connectOptions conn_opts = MTA_connectOptions_inalizer;
略称はRRC。
printf "\n接続が切断されました\n";
if cause
f 理由%s\n"、use;
printf "再接続中\n";
conn_opts.keepveInt = 20;
conn_opts.cleansession = 1;
conn_opts.RetryInt = 16;
conn_opts.minRetryInt = 2;
conn_opts.automReconnect = 1;
//conn_opts.onSuccess = onConnect;
conn_opts.onure = onure;
MTA_setConnected conn_estished;
if rc = MTA_conn_opts!= ASYNC_SUC
{
printf "接続開始に失敗しました。リターンコード%d\n" rc;
完成度= 1。
}
}
//メッセージ受信時のグローバルコールバック関数、ここではメッセージを出力するだけ
int msgarrvd *context *topicName int topicLen MTA_*
{
f
f トピック%s\n"、topicName;
f 略称はC。
“息”“‥”
/* メッセージの内容 */
char* payloadptr = message-payload;
for int i = 0; i-pay; i++
{
put * payptr ++;
}
put\n;
/* メッセージメモリを解放 */
MTA_freeMessage;
MTA_free topicName;
リターン1;
}
/* 非同期接続解除のコールバック関数 */
void onDisconnect void* context MHTTAsync_successData * response
{
printf "切断に成功しました\n";
disc_finished = 1;
}
/* 非同期接続成功コールバック関数で、接続成功時にサブスクリプション操作を実行します。*/
void onConnect void* context MHTTAsync_successData * response
{
MTA = MTAcontext;
MTA_onseOptions opts = MTA_onseOptions_inalizer;
略称はRRC。
printf "接続に成功しました\n";
printf "サブスクライブトピック%s\nクライアント%sを使用してQoS%d\n"
“Q Enterキーを押して終了\n\n\n "TOPIC CLIENTID QOS;
/* サブスクリプションを開始 */
opts.on Success = onSubscribe;
opts.onure = onribeure;
opts.context = client;
if rc = MTA_subscTOPIC QOS opts!= ASYNC_SUC
{
printf "サブスクリプション開始に失敗しました。リターンコード%d\n" rc;
完成度= 1。
}
}
/* 非同期接続に失敗したコールバック関数 */
on
{
f
if response response-message
{
printf "失敗メッセージ%s\n" response-message;
}
完成度= 1。
}
/* 成功したコールバック関数を非同期サブスクライブ */
on
{
printf "サブスクライブに成功しました\n";
Subscribed = 1;
}
/* 非同期サブスクリプションに失敗したコールバック関数 */
on
{
printf "サブスクライブに失敗しました\n";
if response response-message
{
printf "失敗メッセージ%s\n" response-message;
}
完成度= 1。
}
/* 非同期登録解除コールバック関数 */
onUnsubsc
{
printf "登録解除に成功しました\n";
完成度= 1。
}
int main int c * v []
{
MQTTAsyncクライアント;
MTA_connectOptions conn_opts = MTA_connectOptions_inalizer;
略称はRRC。
MTA_msg = MTA__inalizer;
MQTTAsync_tokenトークン;
/* MQTTクライアントを作成 */
MTA_ADDRESS CLNTID CL_PEISTE_NONE NULL;
/* グローバルコールバック関数を設定する */
MTA_setCallbacks conn_lost msgarrvd NULL;
/* 接続オプションの設定 */
conn_opts.keepveInt = 20;
conn_opts.cleansession = 1;
conn_opts.automReconnect = 1;
//conn_opts.onSuccess = onConnect;
conn_opts.onure = onure;
MTA_setConnected conn_estished;
/* 接続を開始 */
if rc = MTA_conn_opts!= MQTTASYNC_SUCCESS)
{
printf "接続開始に失敗しました。リターンコード%d\n" rc;
Return to exit_failure;
}
while! finished
{
#if ined_WIN32
Sleep 1000;
#elseさん
sleep(1);
#endif
}
if subscribed
{
if rc = MTA_unsubscTOPIC NULL!= MQTTASYNC_SUCCESS)
{
printf "サブスクリプション解除に失敗しました。リターンコード%d\n" rc;
Return to exit_failure;
}
}
/* 接続を解除 */
MTA_disconnectOptions disc_opts = MTA_disconnectOptions_inalizer;
disc_opts.onSuess = onDis;
if rc = MTA_disdisc_opts!= MQTTASYNC_SUCCESS)
{
printf "切断の開始に失敗しました。リターンコード%d\n" rc;
Return to exit_failure;
}
while! disc_finished
{
#if ined_WIN32
Sleep 1000;
#elseさん
sleep(1);
#endif
}
/* クライアントを破棄する */
MTA_roy;
EXIT_SUCCESSを返す
}
发表回复