Paho Mqtt Android 客户端错误:无效的客户端句柄,非法参数异常(应用程序运行时随时随机出现)

问题描述 投票:0回答:3

Paho Mqtt Android 客户端错误:无效的客户端句柄,非法参数异常(应用程序运行时随时随机出现)

使用 PahoAndroidMqtt 客户端库 连接代码:

@Override
    public IMqttToken connect(MqttConnectOptions options, Object userContext,
            IMqttActionListener callback) throws MqttException {

        IMqttToken token = new MqttTokenAndroid(this, userContext,
                callback);

        connectOptions = options;
        connectToken = token;

        /*
         * The actual connection depends on the service, which we start and bind
         * to here, but which we can't actually use until the serviceConnection
         * onServiceConnected() method has run (asynchronously), so the
         * connection itself takes place in the onServiceConnected() method
         */
        if (mqttService == null) { // First time - must bind to the service
            Intent serviceStartIntent = new Intent();
            serviceStartIntent.setClassName(myContext, SERVICE_NAME);
            Object service = myContext.startService(serviceStartIntent);
            if (service == null) {
                IMqttActionListener listener = token.getActionCallback();
                if (listener != null) {
                    listener.onFailure(token, new RuntimeException(
                            "cannot start service " + SERVICE_NAME));
                }
            }

            // We bind with BIND_SERVICE_FLAG (0), leaving us the manage the lifecycle
            // until the last time it is stopped by a call to stopService()
            myContext.bindService(serviceStartIntent, serviceConnection,
                    Context.BIND_AUTO_CREATE);

            if (!receiverRegistered) registerReceiver(this);
        }
        else {
            pool.execute(new Runnable() {

                @Override
                public void run() {
                    doConnect();

                    //Register receiver to show shoulder tap.
                    if (!receiverRegistered) registerReceiver(MqttAndroidClient.this);
                }

            });
        }

        return token;
    }

    private void registerReceiver(BroadcastReceiver receiver) {
        IntentFilter filter = new IntentFilter();
                filter.addAction(MqttServiceConstants.CALLBACK_TO_ACTIVITY);
                LocalBroadcastManager.getInstance(myContext).registerReceiver(receiver, filter);
                receiverRegistered = true;
    }

    /**
     * Actually do the mqtt connect operation
     */
    private void doConnect() {
        if (clientHandle == null) {
            clientHandle = mqttService.getClient(serverURI, clientId,myContext.getApplicationInfo().packageName,
                    persistence);
        }
        mqttService.setTraceEnabled(traceEnabled);
        mqttService.setTraceCallbackId(clientHandle);

        String activityToken = storeToken(connectToken);
        try {
            mqttService.connect(clientHandle, connectOptions, null,
                    activityToken);
        }
        catch (MqttException e) {
            IMqttActionListener listener = connectToken.getActionCallback();
            if (listener != null) {
                listener.onFailure(connectToken, e);
            }
        }
    }

抛出错误的 Mqtt 服务类代码是:

 /**
   * Get an MqttConnection object to represent a connection to a server
   *
   * @param serverURI specifies the protocol, host name and port to be used to connect to an MQTT server
   * @param clientId specifies the name by which this connection should be identified to the server
   * @param contextId specifies the app conext info to make a difference between apps
   * @param persistence specifies the persistence layer to be used with this client
   * @return a string to be used by the Activity as a "handle" for this
   *         MqttConnection
   */
  public String getClient(String serverURI, String clientId, String contextId, MqttClientPersistence persistence) {
    String clientHandle = serverURI + ":" + clientId+":"+contextId;
    if (!connections.containsKey(clientHandle)) {
      MqttConnection client = new MqttConnection(this, serverURI,
          clientId, persistence, clientHandle);
      connections.put(clientHandle, client);
    }
    return clientHandle;
  }

 /**
   * Get the MqttConnection identified by this client handle
   *
   * @param clientHandle identifies the MqttConnection
   * @return the MqttConnection identified by this handle
   */
  private MqttConnection getConnection(String clientHandle) {
    MqttConnection client = connections.get(clientHandle);
    if (client == null) {
      throw new IllegalArgumentException("Invalid ClientHandle");
    }
    return client;
  }

StackTrace 是:

  Fatal Exception: java.lang.IllegalArgumentException: Invalid ClientHandle
       at org.eclipse.paho.android.service.MqttService.getConnection(MqttService.java:588)
       at org.eclipse.paho.android.service.MqttService.connect(MqttService.java:328)
       at org.eclipse.paho.android.service.MqttAndroidClient.doConnect(MqttAndroidClient.java:467)
       at org.eclipse.paho.android.service.MqttAndroidClient.access$200(MqttAndroidClient.java:76)
       at org.eclipse.paho.android.service.MqttAndroidClient$1.run(MqttAndroidClient.java:435)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)
android mqtt paho
3个回答
2
投票

我认为您的问题是您使用的客户端与发布 IMqttToken 的客户端不同。

尝试通过以下方式获得正确的客户参考:

科特林:

val currentClient = asyncActionToken!!.client          

爪哇:

IMqttAsyncClient currentClient = asyncActionToken.getClient()

0
投票

我也面临同样的问题,所以我定制了方法,以便每次我们都得到布尔值的响应。

public boolean isAlreadyConnected() {
        if(myMqttAndroidClient != null){
            try{
                boolean result = myMqttAndroidClient.isConnected();
                if(result){
                    return true;
                }
                else {
                    return false;
                }
            }
            catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }
        else {
            return false;
        }
    }

0
投票

我建议你使用hiveMQ库,它支持很好地处理重连和连接等。 一开始用的是paho,后来用的是这个库,就没再遇到这样的问题了

© www.soinside.com 2019 - 2024. All rights reserved.