davidepianca98 / kmqtt Goto Github PK
View Code? Open in Web Editor NEWKotlin Multiplatform MQTT client & embeddable and standalone broker
License: MIT License
Kotlin Multiplatform MQTT client & embeddable and standalone broker
License: MIT License
I am currently implementing a Kotlin multiplatform Project and when I run the Windows 11 native I get a a Socket.IOException: Socket connect failed, error 10047, that I believe to be the win11 socket error 'Address family not supported by protocol family'.
the error comes up when i try to execute
client.publish(
retain = true,
Qos.EXACTLY_ONCE,
topic,
message.toUByteArray(),
MQTT5Properties(
serverKeepAlive = 5000u,
retainAvailable = 1u,))
where client is:
client = MQTTClient(
MQTTVersion.MQTT5,
host,
port,
tls = null,
userName = username,
password = password?.encodeToByteArray()?.toUByteArray(),
keepAlive = 5000,
cleanStart = false,
)
I run the test locally using mosquitto and the same tests are working fine on JVM and Linux Native
Just curious about it.
Hello. I wrote my home broker with access to the external Internet and cannot connect to it, since the path to it looks like this: tcp://ХХ.ХХ.Х.ХХХ:TCP_PORT:MQTT_PORT. That is, I have a separate port for TCP and for MQTT. How can I connect to my broker using your library?
My MQTT broker URL is ws://broker.emqx.io:8083/mqtt.
How can I specify the "/mqtt" path in the MQTTClient?
Hi,
Thanks for creating this library. I was trying to test it locally and I am finding an issue when downloading the dependency. If you could please point me in the right direction it would be great. From what I understood Gradle is not finding the "jvm" variant of the lib.
Here is the error from Gradle:
Execution failed for task ':compileKotlin'.
> Could not resolve all files for configuration ':compileClasspath'.
> Could not resolve com.github.davidepianca98.KMQTT:KMQTT-linuxarm32hfp:0.2.3.
Required by:
project : > com.github.davidepianca98:KMQTT:0.2.3
> No matching variant of com.github.davidepianca98.KMQTT:KMQTT-linuxarm32hfp:0.2.3 was found. The consumer was configured to find an API of a library compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but:
- Variant 'linuxArm32Hfp-api' capability com.github.davidepianca98.KMQTT:KMQTT-linuxarm32hfp:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
- Variant 'metadata-api' capability com.github.davidepianca98.KMQTT:KMQTT-linuxarm32hfp:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
- Variant 'metadata-commonMainMetadataElements' capability com.github.davidepianca98.KMQTT:KMQTT-linuxarm32hfp:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
> Could not resolve com.github.davidepianca98.KMQTT:KMQTT-linuxx64:0.2.3.
Required by:
project : > com.github.davidepianca98:KMQTT:0.2.3
> No matching variant of com.github.davidepianca98.KMQTT:KMQTT-linuxx64:0.2.3 was found. The consumer was configured to find an API of a library compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but:
- Variant 'linuxX64-api' capability com.github.davidepianca98.KMQTT:KMQTT-linuxx64:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
- Variant 'metadata-api' capability com.github.davidepianca98.KMQTT:KMQTT-linuxx64:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
- Variant 'metadata-commonMainMetadataElements' capability com.github.davidepianca98.KMQTT:KMQTT-linuxx64:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
> Could not resolve com.github.davidepianca98.KMQTT:KMQTT-metadata:0.2.3.
Required by:
project : > com.github.davidepianca98:KMQTT:0.2.3
> No matching variant of com.github.davidepianca98.KMQTT:KMQTT-metadata:0.2.3 was found. The consumer was configured to find an API of a library compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but:
- Variant 'metadata-api' capability com.github.davidepianca98.KMQTT:KMQTT-metadata:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
- Variant 'metadata-commonMainMetadataElements' capability com.github.davidepianca98.KMQTT:KMQTT-metadata:0.2.3:
- Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'
- Other compatible attributes:
- Doesn't say anything about its component category (required a library)
- Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
- Doesn't say anything about its target Java version (required compatibility with Java 8)
- Doesn't say anything about its elements (required them preferably in the form of class files)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
And here is the build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.4.31"
}
group = "com.myorg"
version = "1.0"
repositories {
mavenCentral()
jcenter()
maven(url = "https://jitpack.io")
}
dependencies {
implementation("com.github.davidepianca98:KMQTT:0.2.3")
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "1.8"
}
File: ConnectFlags.kt
Line 32:
val willQos = ((byte shr 4) and 1) or ((byte shl 3) and 1)
((byte shl 3) and 1)
is always zero!
so you get wrong qos value.
It should be rather:
val willQos = byte.shr(4) and 3
Example client runs on JVM, after around 1 minute the app crashes.
I'm using mosquitto broker. It emits 30 to 60 events per second.
Exception in thread "main" socket.SocketClosedException
at socket.tcp.Socket.readToBuffer(Socket.kt:47)
at socket.tcp.Socket.read--5HJl4c(Socket.kt:57)
at ClientSocket.read--5HJl4c(ClientSocket.kt:32)
at MQTTClient.check(MQTTClient.kt:312)
at MQTTClient.step(MQTTClient.kt:376)
at MQTTClient.run(MQTTClient.kt:385)
at MainKt.main(Main.kt:16)
at MainKt.main(Main.kt)
I just want to report that the source code and JavaDoc are not available for the JVM artifacts when fetched from mavenCentral.
I'm using them on a single platform project:
dependencies {
implementation("io.github.davidepianca98:kmqtt-common-jvm:0.4.3")
implementation("io.github.davidepianca98:kmqtt-broker-jvm:0.4.3")
}
I'm on IntelliJ IDEA 2023.3.2 (Ultimate Edition).
Please let me know if you are able to reproduce the issue or if I should provide a reproduction project.
Hi All,
When I publish a message with 0.4.6 version.
It takes like 20 seconds or more.
while (isActive) {
client?.run()
delay(200)
}
I've done that but even it takes too much time.
Any fix?
This only happens on my CI instance, which is a bit less powerful than my desktop. I wonder if there's a race?
01-11 17:17:51.247 2605 2633 E TestRunner: java.nio.BufferOverflowException
01-11 17:17:51.247 2605 2633 E TestRunner: at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:164)
01-11 17:17:51.247 2605 2633 E TestRunner: at java.nio.ByteBuffer.put(ByteBuffer.java:732)
01-11 17:17:51.247 2605 2633 E TestRunner: at socket.tcp.Socket.send-GBYM_sE(Socket.kt:19)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.ClientConnection.writePacket$kmqtt_broker(ClientConnection.kt:103)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.Session.publish$kmqtt_broker(Session.kt:120)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.Session.publish-dKY7gkk(Session.kt:168)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.Broker.publishNormal-Doz7y5Q(Broker.kt:111)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.Broker.publish-WrwqGuM$kmqtt_broker(Broker.kt:180)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.Broker.publish-WrwqGuM$kmqtt_broker$default(Broker.kt:121)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.Broker.publish-dKY7gkk(Broker.kt:224)
01-11 17:17:51.247 2605 2633 E TestRunner: at mqtt.broker.Broker.publish-XKAnP-8(Broker.kt:244)
01-11 17:17:51.247 2605 2633 E TestRunner: at org.owntracks.android.testutils.TestWithAnMQTTBrokerImpl.sendFromBroker(TestWithAnMQTTBrokerImpl.kt:46)
I'm calling publish on multiple messages, a bit like this:
@RunWith(AndroidJUnit4::class)
class MyTest {
@Test
fun myTest() {
listOf(
MessageLocation(),
MessageCard()
}.sendFromBroker(broker)
}
fun <E : MessageBase> Collection<E>.sendFromBroker(
broker: Broker,
topicName: String = "owntracks/someuser/somedevice",
retain: Boolean = false
) = forEach { it.sendFromBroker(broker, topicName, retain) }
fun MessageBase.sendFromBroker(
broker: Broker,
topicName: String = "testTopic",
retain: Boolean
) {
this.toJsonBytes()
.run {
broker.publish(
true,
actualTopic,
Qos.AT_LEAST_ONCE,
MQTT5Properties(),
toUByteArray()
)
}
}
}
This same code works fine with either:
Hi,
I have successfully integrated you MQTT library on my KMM project.
On Android it works and I can subscribe & publish to topics.
On iOS it fails building my iOS application and it does not event start in my simulator.
The build error is:
> Task :shared:compileKotlinIosSimulatorArm64 FAILED error: Could not find "openssl-ios-simulator-arm64" in [/Users/MyUser/path/to/project, /Users/MyUser/.konan/klib, /Users/MyUser/.konan/kotlin-native-prebuilt-macos-aarch64-1.9.10/klib/common, /Users/MyUser/.konan/kotlin-native-prebuilt-macos-aarch64-1.9.10/klib/platform/ios_simulator_arm64] error: Compilation finished with errors
Do you have any idea what's causing this?
PS: Excluding your mqtt lib and all relevant code from my app fixes building iOS app.
Thanks
Jan
Thanks for your tools, it's very helpfull and straight to the point!
But could you add the connection timeout as a constructor parameter for the MQTTClient?
Thanks for sharing your work :)
Hi,
Trying to connect to an activemq instance on aws,
Here is my source code:
val client = MQTTClient(
5,
"id.mq.eu-central-1.amazonaws.com",
8883,
TLSClientSettings()
) {
Logger.debug(TAG, "test ${it.payload?.toByteArray()?.decodeToString()}")
}
client.publish(
false,
Qos.AT_MOST_ONCE,
"/toto",
"hello".encodeToByteArray().toUByteArray()
)
client.step()
client.run()
Exception trapped
socket.SocketClosedException
at socket.tls.TLSSocket.read0(TLSSocket.kt:152)
at socket.tls.TLSSocket.read--5HJl4c(TLSSocket.kt:172)
at TLSClientSocket.read--5HJl4c(TLSClientSocket.kt:117)
at MQTTClient.check(MQTTClient.kt:283)
at MQTTClient.step(MQTTClient.kt:346)
at MQTTClient.run(MQTTClient.kt:355)
Using jitpack version 0.4.1
Please could you test on your side using amazon mq instance on mqtt protocol ?
Thanks
onDisconnected is not called when client disconnects or when the server goes offline.
Version: MQTT5
Platform: Android
Hi,
Is it possible to get the authentication information in the packet interceptor? My use case would be to validate that certain user can send information for a topic or validate the payload.
Thanks!
Make internal fun getSession(clientId: String?): ISession?
public,
and it would be nice to have a onDisconnect
event that would trigger whenever a client has disconnected or timed out.
Some MQTT clients, such as HiveMQ uses all lowercase in the HTTP headers during a websocket handshake.
KMQTT does a case sensitive regex match against, for example, Sec-WebSocket-Protocol
. Due to this it's not possible to use WebSockets to connect to KMQTT from a client using on HiveMQ.
It would be great if case insensitive matching could be used when matching against http headers.
For reference, here's an example of what the request and response looks like during the handshake:
GET / HTTP/1.1
host: 192.168.22.52:1884
upgrade: websocket
connection: upgrade
sec-websocket-key: GDDymPLXlAntP0fSTArBCg==
origin: http://192.168.22.52:1884
sec-websocket-protocol: mqtt
sec-websocket-version: 13
HTTP/1.1 400 Bad Request
Hello,
The SDK is missing state of connection callback (onConnected / onDisconnected)
Also, I did not find where to manage the LWT message topic from client side.
https://www.hivemq.com/blog/mqtt-essentials-part-9-last-will-and-testament/
Could you do these enhancements ?
And possible to keep your up to date version available on Jitpack please ?
Thanks
I noticed in #17 there was a discussion about how the openssl klib doesn't get included in the dependency package. I had a discussion with @kpgalligan in the Kotlin Lang Slack about the issue and he mentioned since you're building them from source you could use touchlab/cklib to package them in. Happy to help contribute a PR if you're open to it.
While testing the MQTT publish and subscribe functions in KMM I'm seeing a delay of more than 1-3 minutes. Please guide me on how this can be fixed.
Hi,
The MQTT client works well, but I need to implement auto-reconnect for internet reconnections, server disconnections, and similar issues.
Initialize broker with TLS enabled
val broker = Broker(
port =1883,
tlsSettings = TLSSettings(
keyStoreFilePath = getTlsFilepath(serverCertUri),
keyStorePassword = "Incorrectpasskey", // change to correct on next run
requireClientCertificate = false
),
miscCallbacks = object : MiscCallbacks {
override fun brokerStarted() {
Log.d("Broker", "Started")
}
override fun brokerStopped() {
Log.d("Broker", "Stopped")
}
}
)
broker.step()
If the keyStore password is incorrect, the broker throws following exception:
`
"java.io.IOException: PKCS12 key store mac invalid - wrong password or corrupted file."
`
Now, if a new broker instance with correct keyStore Password is supplied , it will throw:
java.net.BindException: Address already in use
Hello,
First of all, thank you for providing this library to the KMM community.
I'm working on a KMM project and I wanted to test the tool on it but I wasn't able to do so. The project has targets for Android and iOS (iosX64, iosArm64, iosSimulatorArm64). I took a look in JitPack and apparently, I can't find a kmqtt-common for the mentioned iOS targets.
Am I missing something or is it something from the library side?
Kotlin version - 1.8.10
* What went wrong:
Could not determine the dependencies of task ':shared:transformIosMainCInteropDependenciesMetadataForIde'.
> Could not resolve all task dependencies for configuration ':shared:allSourceSetsRuntimeDependenciesMetadata'.
> Could not resolve com.github.davidepianca98.KMQTT:kmqtt-common:0.4.1.
Required by:
project :shared
> Could not resolve com.github.davidepianca98.KMQTT:kmqtt-common:0.4.1.
> Could not get resource 'https://my_artifactory_link/github/davidepianca98/KMQTT/kmqtt-common/0.4.1/kmqtt-common-0.4.1.pom'.
> Could not GET 'https://my_artifactory_link//github/davidepianca98/KMQTT/kmqtt-common/0.4.1/kmqtt-common-0.4.1.pom'. Received status code 403 from server: Forbidden
> Could not resolve com.github.davidepianca98.KMQTT:kmqtt-client:0.4.1.
Required by:
project :shared
> Could not resolve com.github.davidepianca98.KMQTT:kmqtt-clien:0.4.1.
> Could not get resource 'https://my_artifactory_link/github/davidepianca98/KMQTT/kmqtt-client/0.4.1/kmqtt-client-0.4.1.pom'.
> Could not GET 'https://my_artifactory_link/com/github/davidepianca98/KMQTT/kmqtt-client/0.4.1/kmqtt-client-0.4.1.pom'. Received status code 403 from server: Forbidden
sourceSets {
val commonMain by getting {
dependencies {
implementation(com.github.davidepianca98.KMQTT:kmqtt-common:0.4.1)
implementation(com.github.davidepianca98.KMQTT:kmqtt-client:0.4.1)
}
}
}
Ciao @davidepianca98 👋 ,
While testing a feature using KMM I noticed I get the following error:
--- Error: socket.IOException: Error in recv: 9
at 0 Sdk 0x121e217af kfun:socket.tcp.Socket#read(){}kotlin.UByteArray? + 943
at 1 Sdk 0x121e28baf kfun:ClientSocket#read(){}kotlin.UByteArray? + 511
at 2 Sdk 0x121f33a37 kfun:socket.SocketInterface#read(){}kotlin.UByteArray?-trampoline + 207
at 3 Sdk 0x121e238bb kfun:MQTTClient.check#internal + 235
at 4 Sdk 0x121e2c1a7 kfun:kmp.backend.calls.MyMqttClientImpl.$subscribe$lambda$2$FUNCTION_REFERENCE$2.invoke#internal + 939
at 5 Sdk 0x121f034b7 kfun:kotlin.Function2#invoke(1:0;1:1){}1:2-trampoline + 207
at 6 Sdk 0x121a8b417 kfun:kotlin.coroutines.intrinsics.object-3.invokeSuspend#internal + 451
at 7 Sdk 0x121a8a33b kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 171
at 8 Sdk 0x121b6710b kfun:kotlinx.coroutines.DispatchedTask#run(){} + 471
at 9 Sdk 0x121b789d7 kfun:kotlinx.coroutines.DarwinGlobalQueueDispatcher.$dispatch$lambda$0$FUNCTION_REFERENCE$0.$<bridge-UNN>invoke(){}#internal + 83
at 10 Sdk 0x121f01443 kfun:kotlin.Function0#invoke(){}1:0-trampoline + 207
at 11 Sdk 0x1221d3797 ___6f72672e6a6574627261696e732e6b6f746c696e783a6b6f746c696e782d636f726f7574696e65732d636f72652f6f70742f6275696c644167656e742f776f726b2f343465633665383530643563363366302f6b6f746c696e782d636f726f7574696e65732d636f72652f6e617469766544617277696e2f7372632f44697370617463686572732e6b74_knbridge2_block_invoke + 231
at 12 libdispatch.dylib 0x110c1453b _dispatch_call_block_and_release + 31
at 13 libdispatch.dylib 0x110c15fef _dispatch_client_callout + 19
at 14 libdispatch.dylib 0x110c18b27 _dispatch_queue_override_invoke + 1051
at 15 libdispatch.dylib 0x110c2a467 _dispatch_root_queue_drain + 407
at 16 libdispatch.dylib 0x110c2ae63 _dispatch_worker_thread2 + 195
at 17 libsystem_pthread.dylib 0x1f733cdbb _pthread_wqthread + 227
at 18 libsystem_pthread.dylib 0x1f733cb97 start_wqthread + 7
It happens only when this line is present:
client.disconnect(ReasonCode.SUCCESS)
Also it only happens on iOS :/ It doesn't happen on Android.
Do you have any idea about how to fix this? Are we doing anything wrong? Can it be tied to the prebuilt .klibs we're bundling in the project for iOS to work?
Thanks in advance for your work
Do you think there will be a possibility to make all file path based settings for TLSClientSettings to have also a String based settings ?
I know it's possible on JVM based platform but i don't know if other platform can take a String argument ?
public data class TLSClientSettings(
val version: String = "TLS",
val serverCertificatePath: String? = null,
val clientCertificatePath: String? = null,
val clientCertificateKeyPath: String? = null,
val clientCertificatePassword: String? = null
)
I cloned the repo and published common
and client
to maven local.
My project script is just one file
kotlin("multiplatform") version "1.9.0"
}
group = "me.alex"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
mavenLocal()
}
kotlin {
macosArm64("macos") {
binaries {
executable {
entryPoint = "main"
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("com.github.davidepianca98:kmqtt-client:0.4.1")
implementation("com.github.davidepianca98:kmqtt-common:0.4.1")
}
}
val macosMain by getting {
dependencies {
implementation("com.github.davidepianca98:kmqtt-common-macosarm64:0.4.1")
implementation("com.github.davidepianca98:kmqtt-client-macosarm64:0.4.1")
}
}
}
}
I have my main
function in src/commonMain/kotlin/Main
Intellij indexer shows that I can import the MQTT library. Project compilation fails with
e: Could not find "openssl-macos-arm64" in [projectDir, /Users/alex/.konan/klib, /Users/alex/.konan/kotlin-native-prebuilt-macos-aarch64-1.9.0/klib/common, /Users/alex/.konan/kotlin-native-prebuilt-macos-aarch64-1.9.0/klib/platform/macos_arm64]
Hi, thanks for your library.
I don't know if it's intended behavior, but I'm having issues subscribing to some MQTT topics after I already invoked client.run()
.
Usually, when I call later client.subscribe(...)
I end up with a socket.IOException: Connection reset by peer
.
All seems to work fine if I call in this specific order client.subscribe(...)
and then client.run()
.
Let me know if you need a repro, if so I'll try to extract the logic from my project.
Edit: I'm running on JVM (Android).
Thanks.
Hi! First, thanks a lot for this project. It rocks!
Are you considering the publication of the libraries on Maven Central?
Would you accept a PR setting up the required Gradle boilerplate?
it's my misunderstanding.
I have been getting error like this whenever I have tried to connect to the MQTT Broker from some client with TLS enabled. Can anyone point me in the right direction please.
javax.net.ssl.SSLException: Unable to parse TLS packet header
at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:807)
at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
at com.android.org.conscrypt.Java8EngineWrapper.unwrap(Java8EngineWrapper.java:237)
at socket.tls.TLSSocket.read0(TLSSocket.kt:136)
at socket.tls.TLSSocket.runHandshake(TLSSocket.kt:122)
at socket.tls.TLSSocket.<init>(TLSSocket.kt:28)
at socket.tls.TLSServerSocket.createSocket(TLSServerSocket.kt:78)
at socket.ServerSocket.accept(ServerSocket.kt:107)
at socket.ServerSocket.select(ServerSocket.kt:138)
at socket.ServerSocketLoop.run(ServerSocketLoop.kt:22)
at mqtt.broker.Broker.listen(Broker.kt:68)
at com.example.headphonetest.broker.MqttBrokerManager$startBroker$1.invokeSuspend(MqttBrokerManager.kt:106)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:585)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:802)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:706)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:693)
socket.SocketClosedException
at socket.tls.TLSSocket.send0-GBYM_sE(TLSSocket.kt:81)
at socket.tls.TLSSocket.read0(TLSSocket.kt:162)
at socket.tls.TLSSocket.runHandshake(TLSSocket.kt:122)
at socket.tls.TLSSocket.<init>(TLSSocket.kt:28)
at socket.tls.TLSServerSocket.createSocket(TLSServerSocket.kt:78)
at socket.ServerSocket.accept(ServerSocket.kt:107)
at socket.ServerSocket.select(ServerSocket.kt:138)
at socket.ServerSocketLoop.run(ServerSocketLoop.kt:22)
at mqtt.broker.Broker.listen(Broker.kt:68)
at com.example.headphonetest.broker.MqttBrokerManager$startBroker$1.invokeSuspend(MqttBrokerManager.kt:106)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:585)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:802)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:706)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:693)
I have a PKCS12 file (containing both the self - signed certificate and private key) stored in the android project's raw folder. The CA that signed the certificate is installed on both the MQTT client and broker device. Except for the warning of key length being 1024 -bits, ssl- checker shows the certificate as valid.
I am trying to create project using this library with kotlin native on linux 64bit, but i am getting strange error about missing openssl. I have installed openssl and libssl-dev but the error still persists.
e: Could not find "openssl" in [/home/fjerabek/mqttTest, /home/fjerabek/.konan/klib, /home/fjerabek/.konan/kotlin-native-prebuilt-linux-x86_64-1.7.0/klib/common, /home/fjerabek/.konan/kotlin-native-prebuilt-linux-x86_64-1.7.0/klib/platform/linux_x64]
Execution failed for task ':compileKotlinNative'.
> Compilation finished with errors
Am i missing some other library on my system ?
It would be useful to have access to the list of connected clients of the broker. This would be very simple to implement: just create a function that returns the sessions.keys
of the Broker
class:
public fun getConnectedClients(): ListString = sessions.keys
MQTTConnect
offers a lot of data about the client that connected to the MQTT broker, but MQTTDisconnect
does not provide any information at all beside that some unidentified session was closed.
It would be useful if MQTTDisconnect
would provide at least the Client ID of the client that disconnected from the broker.
Function putOrEnlarge() in src/jvmMain/kotlin/socket/tls/TLSSocket.kt:123 does not handle the case when 0 bytes have been received from super.readToBuffer() into the receiveBuffer.
Although nothing has been received, we still try to put into the cacheReceiveBuffer - for some reason, this causes a BufferOverflowException :-(
Following that, we will enlarge the buffer and try to unwrap the data which leads to an "Unable to parse TLS packet header" error eventually.
src/jvmMain/kotlin/socket/tls/TLSSocket.kt
src/jvmMain/kotlin/socket/tcp/Socket.kt
I'm running KMQTT broker using TLS on an android device together with a raspberry pi running mosquitto as client. TLS certificates need to be in place.
Every time I try to publish or subscribe to the broker, i get this "Unable to parse TLS packet header". During debugging, I found out, that i don't get this "0-byte-channel-read" when i set a breakpoint on tcpEventHandler.read() in the do-while-loop in handleEvent() in ServersocketLoop.kt:33. I guess that this "0-byte-channel-read" only happens if the broker sends a message to the client but the client is not fast enough to deliver a complete answer.
Hello, thank you very much for open-sourcing this project. It has been incredibly helpful to me. I have a few questions. I noticed that there are some TODOs in the source code. Will those be completed in the future? Additionally, I couldn't find any callbacks or notifications regarding the connection status in the Client. Do you have any suggestions for how to know the connection status?
Ran the KMQTT Broker on Android10 with TLS enabled.
Ran into the following exception:
java.io.IOException: exception decrypting data - java.security.NoSuchAlgorithmException: 1.2.840.113549.1.5.12 SecretKeyFactory not available
at com.android.org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.cryptData(PKCS12KeyStoreSpi.java:730)
at com.android.org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(PKCS12KeyStoreSpi.java:978)
at java.security.KeyStore.load(KeyStore.java:1484)
at socket.tls.TLSServerSocket.(TLSServerSocket.kt:32)
at socket.ServerSocketLoop.(ServerSocketLoop.kt:15)
at mqtt.broker.Broker.(Broker.kt:50)
at mqtt.broker.Broker.(Unknown Source:0)
at mqtt.broker.Broker.(Broker.kt:20)
Hi, this is an AWESOME project. I'm trying to import the kmqtt-client library in my own kmm library which is oriented to the Android/iOS platform. As I added the following lines in commonMain dependencies:
implementation("com.github.davidepianca98:kmqtt-common:0.4.2")
implementation("com.github.davidepianca98:kmqtt-client:0.4.2")
I still cannot use the MQTTClient class in my code, it was appeared as unresolved reference.
One more question, is kmqtt-client planning to support Android platform?
Hello,
Trying to connect on IOS simulator (also a real phone) to mqtt broker with SSL.
My MQTT broker trusts the certificate on device directly, so no need to set any path on Android..
if (tlsSettings.serverCertificatePath != null) {
if (SSL_CTX_load_verify_locations(sslContext, tlsSettings.serverCertificatePath, null) != 1) {
throw Exception("Server certificate path not found")
}
} else {
if (SSL_CTX_load_verify_locations(sslContext, null, getenv(X509_get_default_cert_dir_env()?.toKString())?.toKString()) != 1) {
throw Exception("Server certificate path not found") //Fail HERE
}
}
But in IOS it throws on the "else" branch, any idea ?
Thanks for help.. it's really blocking.
Would it be possible to add a Broker Started/Stopped listener?
Trying to connect to a bambu labs printer, without obvious access to certs.
Standard practice seems to be to disable TLS validation.
https://github.com/markhaehnel/bambulab/blob/main/src/client.rs#L87
async fn connect(&self) -> Result<(), Box<dyn std::error::Error>> {
let ssl_opts = paho_mqtt::SslOptionsBuilder::new()
.disable_default_trust_store(true)
.enable_server_cert_auth(false)
.verify(false)
.finalize();
Is this supported?
Hi, thanks for the great work, making the mqtt client, supporting multiplatform.
I was able to run the sample codes, that is subscribe before calling client.run.
Just like to share that I also tried to use client.subscribe after the client.run was called. However, it seems like the subscription was not registered.
Appreciate if you can advise on why this is happening. The objective is to allow the client to subscribe to a topic after client is connected to the broker.
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.