Как подключиться к Mqtt3AsyncClient с помощью библиотеки HiveMq-mqtt? - PullRequest
1 голос
/ 20 июня 2019

Я пытался реализовать mqtt с помощью hivemq в моем приложении для Android.Хотя я использовал те же спецификации и конфигурацию из их документов, я все еще не могу установить успешное соединение.

Я мог использовать paho для mqtt ранее, но это не работает для Android Oreo и вышеесли приложение находится в фоновом режиме, потому что в библиотеке не было обновления startServiceForeground.Итак, перешел на HiveMq.Я просто пробую их пример приложения, используя краткие руководства по началу работы здесь.1. https://hivemq.github.io/hivemq-mqtt-client/ 2. https://www.hivemq.com/blog/mqtt-client-library-enyclopedia-hivemq-mqtt-client/ 3. https://github.com/hivemq/hivemq-mqtt-client/blob/develop/README.md Почти потерянный день, чтобы понять, как подключиться к своему mqtt, но безуспешно

lateinit var client : Mqtt3Client

    fun connect() {
        client = Mqtt3Client.builder()
             .identifier(UUID.randomUUID().toString())
            .serverHost("broker.hivemq.com")
            .serverPort(1883)
            .buildAsync()


            client.toAsync().connect()
            .whenComplete { mqtt3ConnAck, throwable ->
                if (throwable != null) {
                    // handle failure
                    android.util.Log.v("HIVE-MQTT-LCDP", " connection failed")
                } else {
                    android.util.Log.v("HIVE-MQTT-LCDP", " connected")
                    // setup subscribes or start publishing
                    subscribe()
                    publish()
                }
            }

        fab.setOnLongClickListener {
            android.util.Log.v("HIVE-MQTT-LCDP", " disconnected")
            client.toAsync().disconnect()
            true
        }

    }


    fun publish() {
        client.toAsync().publishWith()
            .topic("the/topic")
            .payload("payload".toByteArray())
            .send()
            .whenComplete { mqtt3Publish, throwable ->
                if (throwable != null) {
                    android.util.Log.v("HIVE-MQTT-LCDP", " failure to publish")
                    // handle failure to publish
                } else {
                    android.util.Log.v("HIVE-MQTT-LCDP", " successful to publish")
                    // handle successful publish, e.g. logging or incrementing a metric
                }
            }
    }

    fun subscribe() {
        client.toAsync().subscribeWith()
            .topicFilter("the/topic")
            .callback { mqtt3Publish ->
                // Process the received message
                android.util.Log.v("HIVE-MQTT-LCDP", " Message received")
            }
            .send()
            .whenComplete { mqtt3SubAck, throwable ->
                if (throwable != null) {
                    android.util.Log.v("HIVE-MQTT-LCDP", " failure to subscribe")
                    // Handle failure to subscribe
                } else {
                    android.util.Log.v("HIVE-MQTT-LCDP", " successful to subscribe")
                    // Handle successful subscription, e.g. logging or incrementing a metric
                }
            }
    }```

expecting a response in the subscribe-whenComplete.

the clues:

it throws the exception "com.hivemq.client.mqtt.exceptions.ConnectionClosedException: Server closed connection without DISCONNECT." in the addConnectionListener

Stacktrace:

   Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.logging.log4j.spi.ExtendedLoggerWrapper" on path: DexPathList[[zip file "/data/app/com.example.myapplication-jscQ0Rz9LiCQTlaR1v-Z5w==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.myapplication-jscQ0Rz9LiCQTlaR1v-Z5w==/lib/arm64, /system/lib64, /system/vendor/lib64]]
        at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:93)
        at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:379)
        at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
        at io.netty.util.internal.logging.InternalLogger io.netty.util.internal.logging.Log4J2LoggerFactory.newInstance(java.lang.String) (Log4J2LoggerFactory.java:33)
        at io.netty.util.internal.logging.InternalLoggerFactory io.netty.util.internal.logging.InternalLoggerFactory.newDefaultFactory(java.lang.String) (InternalLoggerFactory.java:51)
        at io.netty.util.internal.logging.InternalLoggerFactory io.netty.util.internal.logging.InternalLoggerFactory.getDefaultFactory() (InternalLoggerFactory.java:67)
        at io.netty.util.internal.logging.InternalLogger io.netty.util.internal.logging.InternalLoggerFactory.getInstance(java.lang.String) (InternalLoggerFactory.java:93)
        at io.netty.util.internal.logging.InternalLogger io.netty.util.internal.logging.InternalLoggerFactory.getInstance(java.lang.Class) (InternalLoggerFactory.java:86)
        at void io.netty.util.internal.SystemPropertyUtil.<clinit>() (SystemPropertyUtil.java:29)
        at boolean io.netty.util.internal.SystemPropertyUtil.getBoolean(java.lang.String, boolean) (SystemPropertyUtil.java:99)
        at void io.netty.channel.epoll.Epoll.<clinit>() (Epoll.java:31)
        at boolean io.netty.channel.epoll.Epoll.isAvailable() (Epoll.java:68)
        at com.hivemq.client.internal.mqtt.netty.NettyEventLoopProvider com.hivemq.client.internal.mqtt.netty.NettyModule.provideNettyEventLoopProvider() (NettyModule.java:40)
        at com.hivemq.client.internal.mqtt.netty.NettyEventLoopProvider com.hivemq.client.internal.mqtt.netty.NettyModule_ProvideNettyEventLoopProviderFactory.proxyProvideNettyEventLoopProvider() (NettyModule_ProvideNettyEventLoopProviderFactory.java:31)
        at com.hivemq.client.internal.mqtt.netty.NettyEventLoopProvider com.hivemq.client.internal.mqtt.netty.NettyModule_ProvideNettyEventLoopProviderFactory.provideInstance() (NettyModule_ProvideNettyEventLoopProviderFactory.java:22)
        at com.hivemq.client.internal.mqtt.netty.NettyEventLoopProvider com.hivemq.client.internal.mqtt.netty.NettyModule_ProvideNettyEventLoopProviderFactory.get() (NettyModule_ProvideNettyEventLoopProviderFactory.java:18)
        at java.lang.Object com.hivemq.client.internal.mqtt.netty.NettyModule_ProvideNettyEventLoopProviderFactory.get() (NettyModule_ProvideNettyEventLoopProviderFactory.java:7)
        at java.lang.Object dagger.internal.DoubleCheck.get() (DoubleCheck.java:47)
        at com.hivemq.client.internal.mqtt.netty.NettyEventLoopProvider com.hivemq.client.internal.mqtt.ioc.DaggerSingletonComponent.nettyEventLoopProvider() (DaggerSingletonComponent.java:377)
        at io.netty.channel.EventLoop com.hivemq.client.internal.mqtt.MqttClientConfig.acquireEventLoop() (MqttClientConfig.java:174)
        at void com.hivemq.client.internal.mqtt.handler.connect.MqttConnAckSingle.subscribeActual(io.reactivex.SingleObserver) (MqttConnAckSingle.java:69)
        at void io.reactivex.Single.subscribe(io.reactivex.SingleObserver) (Single.java:3575)
        at void io.reactivex.internal.operators.single.SingleObserveOn.subscribeActual(io.reactivex.SingleObserver) (SingleObserveOn.java:35)
        at void io.reactivex.Single.subscribe(io.reactivex.SingleObserver) (Single.java:3575)
        at void com.hivemq.client.internal.rx.RxFutureConverter$RxJavaSingleFuture.<init>(io.reactivex.Single) (RxFutureConverter.java:114)
I/zygote64:     at java.util.concurrent.CompletableFuture com.hivemq.client.internal.rx.RxFutureConverter.toFuture(io.reactivex.Single) (RxFutureConverter.java:44)
        at java.util.concurrent.CompletableFuture com.hivemq.client.internal.mqtt.MqttAsyncClient.connect(com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5Connect) (MqttAsyncClient.java:70)
        at java.util.concurrent.CompletableFuture com.hivemq.client.internal.mqtt.mqtt3.Mqtt3AsyncClientView.connect(com.hivemq.client.mqtt.mqtt3.message.connect.Mqtt3Connect) (Mqtt3AsyncClientView.java:116)
        at java.util.concurrent.CompletableFuture com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient.connect() (Mqtt3AsyncClient.java:59)
        at void com.example.myapplication.MainActivity.connect() (MainActivity.kt:70)
        at void com.example.myapplication.MainActivity.onCreate(android.os.Bundle) (MainActivity.kt:58)
        at void android.app.Activity.performCreate(android.os.Bundle) (Activity.java:7183)
        at void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle) (Instrumentation.java:1220)
        at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent) (ActivityThread.java:2910)
        at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:3032)
        at void android.app.ActivityThread.-wrap11(android.app.ActivityThread, android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:-1)
        at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1696)
        at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:105)
        at void android.os.Looper.loop() (Looper.java:164)
        at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6944)
        at java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[]) (Method.java:-2)
        at void com.android.internal.os.Zygote$MethodAndArgsCaller.run() (Zygote.java:327)
        at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:1374)
E/zygote64: No implementation found for int io.netty.channel.epoll.Native.offsetofEpollData() (tried Java_io_netty_channel_epoll_Native_offsetofEpollData and Java_io_netty_channel_epoll_Native_offsetofEpollData__)
I/PlatformDependent: Your platform does not provide complete low-level API for accessing direct buffers reliably. Unless explicitly requested, heap buffer will always be preferred to avoid potential system instability.
W/io.netty.util.NetUtil: Failed to find the loopback interface
W/MacAddressUtil: Failed to find a usable hardware address from the network interfaces; using random bytes: 20:c2:d8:6a:3f:bc:f6:90
W/DefaultPromise: An exception was thrown by com.hivemq.client.internal.mqtt.handler.connect.-$$Lambda$MqttConnAckSingle$1NP8pOpp3tvaWFx_4_jMw-CQFiU.operationComplete()
    java.lang.IllegalStateException: MqttClientReconnector must be called from the eventLoop.
        at com.hivemq.client.internal.mqtt.lifecycle.MqttClientReconnector.checkThread(MqttClientReconnector.java:158)
        at com.hivemq.client.internal.mqtt.lifecycle.MqttClientReconnector.isReconnect(MqttClientReconnector.java:93)
        at com.hivemq.client.internal.mqtt.handler.connect.MqttConnAckSingle.reconnect(MqttConnAckSingle.java:135)
        at com.hivemq.client.internal.mqtt.handler.connect.MqttConnAckSingle.reconnect(MqttConnAckSingle.java:103)
        at com.hivemq.client.internal.mqtt.handler.connect.MqttConnAckSingle.lambda$connect$0(MqttConnAckSingle.java:90)
        at com.hivemq.client.internal.mqtt.handler.connect.-$$Lambda$MqttConnAckSingle$1NP8pOpp3tvaWFx_4_jMw-CQFiU.operationComplete(Unknown Source:8)
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
        at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485)
        at io.netty.util.concurrent.DefaultPromise.access$000(DefaultPromise.java:33)
        at io.netty.util.concurrent.DefaultPromise$1.run(DefaultPromise.java:435)
        at io.netty.util.concurrent.GlobalEventExecutor$TaskRunner.run(GlobalEventExecutor.java:248)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:764)
D/OpenGLRenderer: HWUI GL Pipeline
D/ViewRootImpl@2daeee6[MainActivity]: setView = DecorView@cea6ed4[MainActivity] TM=true MM=false
V/InputMethodManager: Not IME target window, ignoring
D/ViewRootImpl@2daeee6[MainActivity]: dispatchAttachedToWindow
V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0
D/ViewRootImpl@2daeee6[MainActivity]: Relayout returned: old=[0,0][0,0] new=[0,0][1080,1920] result=0x7 surface={valid=true 481715916800} changed=true
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 2
D/libGLESv1: STS_GLApi : DTS, ODTC are not allowed for Package : com.example.myapplication
D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000,  [1080x1920]-format:1
D/OpenGLRenderer: eglCreateWindowSurface = 0x702882f2b0
E/System: Uncaught exception thrown by finalizer
E/System: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.io.FileDescriptor.isSocket$()' on a null object reference
        at sun.nio.ch.FileDispatcherImpl.preCloseImpl(FileDispatcherImpl.java:115)
        at sun.nio.ch.SocketDispatcher.preClose(SocketDispatcher.java:66)
        at sun.nio.ch.SocketChannelImpl.implCloseSelectableChannel(SocketChannelImpl.java:883)
        at java.nio.channels.spi.AbstractSelectableChannel.implCloseChannel(AbstractSelectableChannel.java:234)
        at java.nio.channels.spi.AbstractInterruptibleChannel.close(AbstractInterruptibleChannel.java:116)
        at sun.nio.ch.SocketChannelImpl.finalize(SocketChannelImpl.java:937)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:250)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:237)
        at java.lang.Daemons$Daemon.run(Daemons.java:103)
        at java.lang.Thread.run(Thread.java:764)
I/zygote64: Do partial code cache collection, code=61KB, data=53KB
I/zygote64: After code cache collection, code=61KB, data=53KB
    Increasing code cache capacity to 256KB
D/ViewRootImpl@2daeee6[MainActivity]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x3 surface={valid=true 481715916800} changed=false
I/zygote64: Compiler allocated 9MB to compile void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int)
D/ViewRootImpl@2daeee6[MainActivity]: MSG_RESIZED_REPORT: frame=Rect(0, 0 - 1080, 1920) ci=Rect(0, 72 - 0, 0) vi=Rect(0, 72 - 0, 0) or=1
D/ViewRootImpl@2daeee6[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@159ea78 nm : com.example.myapplication ic=null
I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@9899551 nm : com.example.myapplication ic=null
D/ViewRootImpl@2daeee6[MainActivity]: ViewPostIme pointer 0
D/ViewRootImpl@2daeee6[MainActivity]: ViewPostIme pointer 1
V/HIVE-MQTT-LCDP:  failure to publish
I/zygote64: Do full code cache collection, code=123KB, data=95KB
I/zygote64: After code cache collection, code=102KB, data=64KB

Ответы [ 2 ]

2 голосов
/ 21 июня 2019

Вы должны добавить следующее разрешение в ваш AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>

(см. https://github.com/hivemq/hivemq-mqtt-client/issues/213)

ClassNotFoundException - это просто сообщение журнала, а не ошибка. Netty (сетевая библиотека, используемая клиентом HiveMQ MQTT), пытается определить, загружена ли у вас среда ведения журнала, поэтому добавление структуры ведения журнала необязательно.


Обновление для Proguard:

Netty иJCTools не может быть хорошо защищен, поэтому добавьте следующие правила proguard:

-keepclassmembernames class io.netty.** {
    *;
}

-keepclassmembernames class org.jctools.** {
    *;
}
0 голосов
/ 20 июня 2019

Попробуйте добавить это в свой файл сборки

https://mvnrepository.com/artifact/log4j/log4j/1.2.17

группа компиляции: 'log4j', имя: 'log4j', версия: '1.2.17'

...