设置客户端自动重连
无论是通过公网还是通过内网接入 MQTT 集群, 传输层连接断开都是常态: 移动设备在基站间切换、 网络抖动、服务端版本发布等。因此 MQTT 客户端均需要设置连接断开后自动重连, 并配置合理的退避策略。
需要在 Connect Options 设置连接超时时间、自动重连、最小自动重连间隔、最大自动重连间隔等选项。
public class MqttConnectionOptions {...// Automatic Reconnectprivate boolean automaticReconnect = false;// Time to wait before first automatic reconnection attempt in seconds.private int automaticReconnectMinDelay = 1;// Max time to wait for automatic reconnection attempts in seconds.private int automaticReconnectMaxDelay = 120;// Connection timeout in secondsprivate int connectionTimeout = 30;private int maxReconnectDelay = 128000;...}
struct MQTTAsync_connectOptions {.../*** The time interval in seconds to allow a connect to complete.*/int connectTimeout;/*** Reconnect automatically in the case of a connection being lost. 0=false, 1=true*/int automaticReconnect;/*** The minimum automatic reconnect retry interval in seconds. Doubled on each failed retry.*/int minRetryInterval;/*** The maximum automatic reconnect retry interval in seconds. The doubling stops here on failed retries.*/int maxRetryInterval;};
Paho SDK CleanSession=True 或 CleanStart = True 订阅
Paho SDK Subscriber Client, 如果 Session 配置 CleanSession = True 或者 CleanStart = True , 当发生自动重连后,SDK 不会自动重新订阅,需要在回调中重新订阅。参考 Issue 221。
以 Java 回调为例:
try (MqttClient client = new MqttClient(serverUri, clientId, new MemoryPersistence())) {MqttConnectOptions options = new MqttConnectOptions();options.setCleanSession(true);...client.setCallback(new MqttCallbackExtended() {@Overridepublic void connectComplete(boolean reconnect, String serverURI) {...try {// 必须重新订阅client.subscribe(topicFilter, qos);} catch (MqttException e) {e.printStackTrace();}}...});client.connect(options);}
QoS 降级
MQTT 服务端向订阅者投递消息的时候, 并不总是按照订阅表达式指定的 QoS 投递, 而是取 { 发布消息 QoS, 服务端支持的最大 QoS,订阅 QoS } 三者最小值。
假设发布消息 Mi 使用的 QoS 为1、服务端最大支持的 QoS 为 2、 订阅使用的 QoS 为 2,投递该消息使用的 QoS 为 1。