【问题标题】:Mqtt Paho - Trying to publish while broker is unreachableMqtt Paho - 在无法访问代理时尝试发布
【发布时间】:2014-01-21 21:20:59
【问题描述】:

我开始使用 Mqtt,但我很难处理不可靠的网络。 我正在使用 Paho Java 客户端(在 groovy 中)向远处的 Mosquitto Broker 发布消息。

有没有办法,当代理无法访问时,让 Paho 客户端持久保存消息并自动重新连接到代理并发布本地存储的消息?我是否必须自己处理所有事情,例如使用本地经纪人?

这是我的客户端构建代码

    String persistenceDir = config['persistence-dir'] ?: System.getProperty('java.io.tmpdir')
    def persistence = new MqttDefaultFilePersistence(persistenceDir)
    client = new MqttAsyncClient(uri, clientId, persistence)
    client.setCallback(this)
    options = new MqttConnectOptions()
    if (config.password) {
        options.setPassword(config.password as char[])
        options.setUserName(config.user)
    }
    options.setCleanSession(false)
    client.connect(options)

还有我的发布代码

  def message = new MqttMessage(Json.encode(outgoingMessage).getBytes())
    try {
    client?.connect(options)
    def topic = client.getTopic('processMsg')
    message.setQos(1)
    def token = topic.publish(message)
    if (client) {
        client.disconnect()
    }

谢谢

【问题讨论】:

    标签: java groovy mqtt


    【解决方案1】:

    Paho 客户端仅在连接到代理时才会持久保存动态消息。

    通常,当连接问题开始出现时,您会看到消息超时弹出

    • 等待服务器响应超时 (32000)

    此时消息仍将保留。

    但是,当连接丢失时,您开始看到这个

    • 客户端未连接 (32104)

    您应该假设 Paho 没有保留该消息。

    您可以在org.eclipse.paho.client.mqttv3.internal.ClientComms 中调试它:

    /**
     * Sends a message to the broker if in connected state, but only waits for the message to be
     * stored, before returning.
     */
    public void sendNoWait(MqttWireMessage message, MqttToken token) throws MqttException {
        final String methodName = "sendNoWait";
        if (isConnected() ||
                (!isConnected() && message instanceof MqttConnect) ||
                (isDisconnecting() && message instanceof MqttDisconnect)) {
            this.internalSend(message, token);
        } else {
            //@TRACE 208=failed: not connected
            log.fine(className, methodName, "208");
            throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_NOT_CONNECTED);
        }
    }
    

    internalSend 将保留消息,但前提是它连接到代理。

    还要考虑到 Paho 可以处理的飞行消息的最大数量。如果超过了,它也将决定不持久化消息。

    【讨论】:

      【解决方案2】:

      您可以设置一个本地代理并将其与远程代理桥接。这样,您可以在本地排队所有消息,并且当远程代理重新联机时,所有消息都可以传递。

      【讨论】:

        【解决方案3】:

        是的...在收到消息无法传递的异常后,必须将其持久化或重新生成消息。

        如果您打算使用本地代理,您可以查看真正的小型消息代理 (https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=d5bedadd-e46f-4c97-af89-22d65ffee070)

        【讨论】:

          猜你喜欢
          • 2022-07-06
          • 1970-01-01
          • 1970-01-01
          • 2022-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多