You need to enable JavaScript to run this app. 连接Bridge后与MQTT交互抛出UnknownHostException如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

连接Bridge后与MQTT交互抛出UnknownHostException如何解决?

问题背景
  • 开发了一款支持MQTT操作、可与本地Bridge设备交互的应用,连接Bridge的方式和普通WiFi接入逻辑一致,即让移动设备通过WiFi直接接入Bridge的热点完成交互流程。
  • 仅执行MQTT流程时,连接、订阅、发布数据、接收MQTT下行数据等所有MQTT相关操作均可正常运行。
  • 完成Bridge交互流程后,再次尝试发起MQTT操作时抛出连接异常。
错误日志
MqttException (0) - java.net.UnknownHostException: Unable to resolve host "iot.rkl.com": No address associated with hostname
1608604152.272 9629-9629/com.asiczen.azlock W/System.err:     at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
1608604152.272 9629-9629/com.asiczen.azlock W/System.err:     at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:690)
1608604152.275 9629-9629/com.asiczen.azlock W/System.err:     at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:75)
1608604152.275 9629-9629/com.asiczen.azlock W/System.err:     at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:92)
1608604152.275 9629-9629/com.asiczen.azlock W/System.err:     at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:676)
故障根因与修复方向

故障核心本质: 接入Bridge的专用WiFi热点后,该热点本身无公网出口、也不配置可解析公网域名的DNS服务,同时Android系统默认将该热点设为全局网络路由出口,导致解析公网MQTT broker域名时直接失败,抛出UnknownHostException。

  • 修复方案1:与Bridge完成交互后,主动将设备默认网络切回可访问公网的原有WiFi/移动数据网络,再发起MQTT连接流程。
  • 修复方案2:保持Bridge热点连接的同时,通过Android网络路由API强制将MQTT相关请求走具备公网出口的链路,不使用Bridge热点的默认DNS和路由规则。
  • 修复方案3:提前将MQTT broker域名解析为固定IP并本地缓存,跳过Bridge热点下的DNS解析环节,直接通过IP发起连接。
核心业务代码片段

MQTT服务类实现

public class MqttMessageService extends Service {
    private static final String TAG = MqttMessageService.class.getSimpleName();
    public static final String EXTRA_DATA = "android.nfc.extra.DATA";
    public static final String MQTT_CONNECTED = "android.nfc.extra.MQTT_CONNECTED";
    public static final String MQTT_DISCONNECTED = "android.nfc.extra.MQTT_DISCONNECTED";
    public static final String MQTT_DATA_AVAILABLE = "android.nfc.extra.MQTT_DATA_AVAILABLE";
    public static final String MQTT_DELEVIERY_COMPLETED = "android.nfc.extra.MQTT_DELEVIERY_COMPLETED";
    public static final String MQTT_UNABLE_TO_PUBLISH = "android.nfc.extra.MQTT_UNABLE_TO_PUBLISH";
    public static final String MQTT_UNABLE_TO_SUBSCRIBE = "android.nfc.extra.MQTT_UNABLE_TO_SUBSCRIBE";
    public static final String MQTT_USUBSCRIBE = "android.nfc.extra.MQTT_USUBSCRIBE";
    public static final String MQTT_UN_SCBSCRIBE = "android.nfc.extra.MQTT_UN_SCBSCRIBE";

    private MqttAndroidClient mqttAndroidClient;

    public void connectMQTT(){
        Log.d(TAG, "MQTT CONNECTION STAR: ");
        PahoMqttClient pahoMqttClient = new PahoMqttClient();
        mqttAndroidClient = pahoMqttClient.getMqttClient(getApplicationContext(), Packet.PublishTopic.MQTT_BROKER_URL, AppContext.getClientId(this));

        mqttAndroidClient.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean b, String s) {
                Log.d(TAG, "connectComplete: ");
                Log.d(TAG, "MQTT CONNECTED: ");
                broadcastUpdate(MqttMessageService.MQTT_CONNECTED);
            }

            @Override
            public void connectionLost(Throwable throwable) {
                Log.d(TAG, "connectionLost: ");
                Log.d(TAG, " MQTT CONNECTION LOST: ");
                broadcastUpdate(MqttMessageService.MQTT_DISCONNECTED);
            }

            @Override
            public void messageArrived(String s, MqttMessage mqttMessage) {
                String msg = new String(mqttMessage.getPayload(), StandardCharsets.ISO_8859_1);
                Log.d(TAG, "MQTT MESSAGE ARRIVED: "+msg);
                byte[] b = mqttMessage.getPayload();
                broadcastUpdate(b);
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

            }
        });
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
        Log.d(TAG, "MQTT ONCREATE: ");
        connectMQTT();
    }

    private final IBinder mBinder = new LocalService();
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "MQTT ONBIND: ");
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "MQTT ONUNBIND: ");
        return super.onUnbind(intent);
    }
    public class LocalService extends Binder {
        public MqttMessageService getService(){return  MqttMessageService.this;}
    }

    public void subcribe(){
        try {
            IMqttToken token = mqttAndroidClient.subscribe(Utils.getSubscribeTopic(), 0);
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken iMqttToken) {
                    Log.d(TAG, "MQTT SUBSCRIBED 0: ");
                    Log.d(TAG, "Subscribe Successfully " + "BridgeId_SCAN_RESPONSE");
                    broadcastUpdate(MqttMessageService.MQTT_USUBSCRIBE);
                }

                @Override
                public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                    Log.e(TAG, "Subscribe Failed " + "BridgeId_SCAN_RESPONSE");
                    throwable.printStackTrace();
                    broadcastUpdate(MqttMessageService.MQTT_UNABLE_TO_SUBSCRIBE);
                }
            });
        } catch (MqttException e) {
            broadcastUpdate(MqttMessageService.MQTT_UNABLE_TO_SUBSCRIBE);
            e.printStackTrace();
        }catch (Exception e){
            broadcastUpdate(MqttMessageService.MQTT_UNABLE_TO_SUBSCRIBE);
            e.printStackTrace();
        }

    }

    public void msubscribe(String topic){
        try {
            mqttAndroidClient.subscribe(topic, 0);
            Log.d(TAG, "MQTT SUBSCRIBED 1: ");
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    public void publish(byte[] payload){
        Log.d(TAG, "publish: ");
        MqttMessage message = new MqttMessage(payload);
        message.setId(320);
        message.setRetained(false);
        message.setQos(0);
        try {
            mqttAndroidClient.publish(Utils.getPublishTopic(), message);
            Log.d(TAG, "MQTT DATA PUBLISHED: ");
        } catch (MqttException e) {
            e.printStackTrace();
            broadcastUpdate(MqttMessageService.MQTT_UNABLE_TO_PUBLISH);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void unSubscribe(){

        IMqttToken token;
        try {
            token = mqttAndroidClient.unsubscribe(Utils.getSubscribeTopic());
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken iMqttToken) {
                    Log.d(TAG, "UnSubscribe Successfully ");
                    Log.d(TAG, "MQTT UNSUBSCRIBED: ");
                    broadcastUpdate(MqttMessageService.MQTT_UN_SCBSCRIBE);
                }

                @Override
                public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                    Log.e(TAG, "UnSubscribe Failed ");
                    broadcastUpdate(MqttMessageService.MQTT_UN_SCBSCRIBE);
                }
            });
        } catch (MqttException e) {
            broadcastUpdate(MqttMessageService.MQTT_UN_SCBSCRIBE);
            e.printStackTrace();
        }
    }

    public void disconnect()  {
        try {
            IMqttToken mqttToken = mqttAndroidClient.disconnect();
            mqttToken.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken iMqttToken) {
                    Log.d(TAG, "MQTT DISCONNECTED: ");
                    Log.d(TAG, "Successfully disconnect");
                }

                @Override
                public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                    Log.d(TAG, "Failed to disconnect " + throwable.toString());
                }
            });
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    private void broadcastUpdate(final String action) {
        final Intent intent = new Intent(action);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }

    private void broadcastUpdate(byte[] data) {
        final Intent intent = new Intent(MqttMessageService.MQTT_DATA_AVAILABLE);
        intent.putExtra(EXTRA_DATA, data);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
}

Paho MQTT连接类实现

public class PahoMqttClient {
    public MqttAndroidClient getMqttClient(Context context, String brokerUrl, String clientId) {
        mqttAndroidClient = new MqttAndroidClient(context, brokerUrl, clientId);
        try {
            MqttConnectOptions MQTT_CONNECTION_OPTIONS = getMqttConnectionOption();
            if (brokerUrl.contains("ssl")) {
                InputStream i=  context.getResources().openRawResource(R.raw.client_ca);
                InputStream i1=  context.getResources().openRawResource(R.raw.client_crt);
                InputStream inputStream =  context.getResources().openRawResource(R.raw.client_key);
                MQTT_CONNECTION_OPTIONS.setSocketFactory(createSSLSocketFactory(i,i1,inputStream));
            }
            IMqttToken token = mqttAndroidClient.connect(MQTT_CONNECTION_OPTIONS);
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    mqttAndroidClient.setBufferOpts(getDisconnectedBufferOptions());
                    Log.d(TAG, "MQTT CONNECTED:0 ");
                    Log.d(TAG, "Success");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.d(TAG, "MQTT CONNETION FAILED:0 ");
                    exception.printStackTrace();
                    Log.d(TAG, "Failure " + exception.toString());
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }

        return mqttAndroidClient;
    }
}

内容的提问来源于stack exchange,提问作者Bichitra Pradhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.12 01:45:09