このトピックでは、ApsaraMQ for MQTT ブローカーをクライアントに接続することに関するよくある質問への回答を提供します。
Android デモを使用すると、接続失敗エラーが返されるのはなぜですか?
問題の説明
- リソースは正しく構成されており、ネットワークにアクセスできます。
- AccessKey ID と AccessKey シークレットは承認されており、正しく入力されています。
考えられる原因
エンドポイントの形式が正しくありません。エンドポイントは、tcp://エンドポイント:1883 または tls://エンドポイント:8883 のいずれかの形式で指定してください。
コンシューマーがサブスクライブした後、クライアントがすぐに切断されるのはなぜですか?
親トピック
- MQTT は、パブリッシュ - サブスクライブモデルに基づくメッセージングプロトコルです。MQTT では、各メッセージはトピックに属します。MQTT プロトコルは複数レベルのトピックをサポートしています。レベル 1 のトピックは親トピックです。ApsaraMQ for MQTT を使用する前に、ApsaraMQ for MQTT コンソールまたは ApsaraMQ for RocketMQ コンソールで親トピックを作成する必要があります。
サブトピック
- レベル 2 トピックまたはレベル 3 トピックは、Message Queue for MQTT の親トピックのサブトピックです。Message Queue for MQTT コンソールでサブトピックを作成する必要なく、アプリケーションコードでサブトピックを指定できます。サブトピックは、<親トピックの名前>/<レベル 2 トピックの名前>/<レベル 3 トピックの名前> の形式で指定できます。親トピックとサブトピックはスラッシュ (/) で区切られます。例:SendMessage/demo/producer。ApsaraMQ for MQTT では、親トピックとサブトピックの名前の合計の長さは 64 文字を超えることはできません。上記の条件が満たされない場合、クライアント例外が発生します。
コンソールに表示されるサブスクリプションの数が、実際のシナリオで使用されるサブスクリプションの数よりも多いのはなぜですか?
cleanSession パラメーターが false に設定されている場合、クライアントが切断された後もサブスクリプションはクリアされません。
クライアントが切断された後にサブスクリプションを保持したくない場合は、サブスクリプションクリーンアップ機能を使用してサブスクリプションをクリアできます。詳細については、「トピックのサブスクリプションをクリアする」をご参照ください。
クライアントが繰り返し再接続し、「invalid param」エラーが返されるのはなぜですか?
考えられる原因:メッセージ本文のサイズが制限を超えたため、ブローカーが接続要求を拒否しました。ApsaraMQ for MQTT では、メッセージ本文のサイズは 64 KB を超えることはできません。
ビジネス側で変更が行われていないときに、クライアントがブローカーから予期せず切断されたのはなぜですか?
考えられる原因:
- デバイスがシャットダウンされているか、ネットワークにアクセスできません。
- トークンベースの認証を使用している場合、トークンの有効期限が切れるとクライアントはブローカーから切断され、新しいトークンを取得しないと接続の再試行も失敗します。
クライアントのハートビートタイムアウト期間を指定するにはどうすればよいですか?
MqttConnectOptions クラスを呼び出します。
String clientId = mqttTools.getClientId();
mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setUserName("Signature|" + accessKey + "|" + instanceId);
mqttConnectOptions.setPassword(mqttTools.macSignature(clientId).toCharArray());
mqttConnectOptions.setCleanSession(true);
// クライアントのハートビートタイムアウト期間。デフォルト値:90 秒。
mqttConnectOptions.setKeepAliveInterval(90);
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setMqttVersion(MQTT_VERSION_3_1_1);
mqttConnectOptions.setConnectionTimeout(5000);
mqttLogger.info("MQTT is connect setting={},clientId={}", JSON.toJSONString(mqttConnectOptions), clientId);
mqttClient = new MqttClient("tcp://" + endPoint + ":1883", clientId, memoryPersistence);
mqttClient.setTimeToWait(5000);
mqttClient.setCallback(this.getMqttCallbackExtended());
mqttClient.connect(mqttConnectOptions);クライアントがブローカーに接続されているときに、「valid owner failed」エラーが発生したのはなぜですか?
- インスタンス名が正しく指定されていますか?
- コンソールでコンシューマーグループとトピックを作成し、それらの名前を正しく指定しましたか?
- 指定されたインスタンスのグループまたはトピックに関する情報を正しく指定しましたか?
「connection reset by peer」エラーが発生したのはなぜですか?
クライアント ID が存在する場合、アカウントの競合が発生します。この場合、ブローカーはクライアントから切断され、クライアントは確立された TCP 接続を介してデータの送信を続けます。これにより、ブローカーソケットがリセット (RST) パケットを送信します。
指定するクライアント ID がグローバルに一意であることを確認してください。詳細については、「クライアント」をご参照ください。
Message Queue for MQTT の Java クライアント用 SDK の自動接続機能を構成するにはどうすればよいですか?
Java クライアント用 SDK のクライアント自動再接続機能を有効にする
mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setAutomaticReconnect(true);autoReconnect パラメーターを true に設定すると、ApsaraMQ for MQTT の Java クライアント用 SDK が自動的に再接続されます。
mqttClient.setCallback(new MqttCallbackExtended() {
@Override
public void connectComplete(boolean reconnect, String serverURI) {
/**
* クライアント接続が確立された後にサブスクライブする必要があるトピック。
*/
System.out.println("connect success");
}
@Override
public void connectionLost(Throwable throwable) {
throwable.printStackTrace();
}
@Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
/**
* 送信されたメッセージを消費するために呼び出されるコールバック。コールバックが例外をスローしないことを確認してください。コールバックに対してレスポンスが返された場合、メッセージは消費されます。
* メッセージは指定された期間内に消費される必要があります。Message Queue for MQTT ブローカーに指定したタイムアウト期間内にメッセージが消費されない場合、Message Queue for MQTT ブローカーは信頼性の高い伝送モードでメッセージの再送信を試みる可能性があります。ビジネスデータが冪等であることを確認してください。
* タイムアウト期間については、「制限」を参照してください。
*/
System.out.println(
"receive msg from topic " + s + " , body is " + new String(mqttMessage.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("send msg succeed topic is : " + iMqttDeliveryToken.getTopics()[0]);
}
});クライアントのコールバックの connectComplete メソッドが呼び出されると、接続または再接続が成功し、ユーザーは接続ステータスに注意を払う必要はありません。この場合、再確立された接続は以前の接続ではなくなります。その結果、メッセージの送信やサブスクライブなど、以前の接続で行われたアクションは、新しい接続では有効になりません。
新しいトピックにサブスクライブする必要があります。これにより、ユーザーはメッセージの送受信を続けることができます。
@Override
public void connectComplete(boolean reconnect, String serverURI) {
/**
* クライアント接続が確立された後にサブスクライブする必要があるトピック。
*/
System.out.println("connect success");
executorService.submit(new Runnable() {
@Override
public void run() {
try {
final String topicFilter[] = {mq4IotTopic};
final int[] qos = {qosLevel};
mqttClient.subscribe(topicFilter, qos);
} catch (MqttException e) {
e.printStackTrace();
}
}
});
}ユーザーによるクライアント接続の手動メンテナンス
mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setAutomaticReconnect(false);autoReconnect パラメーターが false に設定されている場合、ApsaraMQ for MQTT クライアントは切断後に自動的に再接続しません。
Message Queue for MQTT クライアントが切断されると、例外はユーザーによってキャプチャされます。この場合、ユーザーは元の接続を手動で終了し、新しい接続を確立する必要があります。