A multiplatform Kotlin MQTT 5 client library, which is built on Ktor, kotlinx-io and Coroutines. It
provides a fast and easy setup of asynchronous MQTT 5 clients without the need to use callbacks. It
allows connections to MQTT servers via plain sockets or via websockets.
This library does not support MQTT 3.
| Connection Type | JVM | Android | iOS | Wasm* |
|---|---|---|---|---|
| Plain Socket | ✔️ | ✔️ | ✔️ | |
| Secure Socket | ✔️ | ✔️ | ** | |
| Websocket | ✔️ | ✔️ | ✔️ | |
| Secure Websocket | ✔️ | ✔️ | ✔️ | ✔️ |
* Wasm support is currently experimental, see a simple demo page here.
** Will be available when this Ktor bug is resolved.
Creating a client with username password authentication, subscribing to a topic and receiving PUBLISH packets is as simple as:
runBlocking {
val client = MqttClient("test.mosquitto.org", 1884) {
username = "ro"
password = "readonly"
}
// Print the first 100 published packets
val receiver = launch {
client.publishedPackets.take(100).collect { publish ->
println("New publish packet received: $publish")
}
}
client.connect().onSuccess { connack ->
if (connack.isSuccess) {
client.subscribe(buildFilterList { +"#" })
}
}.onFailure {
throw it
}
receiver.join()
client.disconnect()
}To publish data, create a PublishRequest and specify the topic (or topic alias):
client.publish(PublishRequest("topics/test") {
desiredQoS = QoS.AT_LEAST_ONCE
messageExpiryInterval = 12.hours
payload("This text message expires in 12h")
userProperties {
"key-1" to "value-1"
}
})When the publish() method returns successfully, all acknowledgement messages required for the QoS level
used, will be transmitted between the server and the client. Note that the desiredQoS might be
automatically downgraded, in case the server sent a lower max. QoS in its CONNACK message. The QoS that
was actually used, can be gathered from the returned PublishResponse.
PublishRequest is a data class, hence you can reuse it, if you just want to change some properties:
val next = publishRequest.copy(payload = "Another payload".encodeToByteString())To use TLS, enable it in the connection DSL:
val client = MqttClient("test.mosquitto.org", 8886) {
connection {
tls { }
}
}The tls part allows you to configure further TLS settings via Ktor
TLSConfigBuilder,
for example for the Java platform, you can use your
own X509TrustManager.
A will message, its topic, payload and properties are defined in the constructor DSL, for example:
val client = MqttClient("test.mosquitto.org", 1883) {
willMessage("topics/last/will") {
payload("Have been here")
properties {
willDelayInterval = 1.minutes
}
}
}By default, the library does not create any log messages. However logging is based on Kermit and can be enabled in the logging part of the constructor DSL; for example:
val client = MqttClient("test.mosquitto.org", 1883) {
logging {
minSeverity = Severity.Debug
}
}Make sure that you have mavenCentral() in the list of repositories:
repositories {
mavenCentral()
}Add the library to dependencies:
dependencies {
implementation("de.kempmobil.ktor.mqtt:mqtt-core:0.8.0")
implementation("de.kempmobil.ktor.mqtt:mqtt-client:0.8.0")
}In multiplatform projects, add a dependency to the commonMain source set dependencies:
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("de.kempmobil.ktor.mqtt:mqtt-core:0.8.0")
implementation("de.kempmobil.ktor.mqtt:mqtt-client:0.8.0")
}
}
}
}Ktor and this library are based on kotlinx-io, which is
available for Android 5.0+ (API level 21+),
see Android
in kotlinx-io.
If you want to connect to the MQTT server via web sockets, also add the mqtt-client-ws library
and at least one Ktor Http client library, for example CIO:
dependencies {
implementation("de.kempmobil.ktor.mqtt:mqtt-client-ws:0.8.0")
implementation("io.ktor:ktor-client-cio:3.3.1")
}Then pass a URL instead of a server name and a port number to the MqttClient factory method:
val client = MqttClient("http://test.mosquitto.org:8080") { }- As protocol, you can use either
http:orws:for plain connections orhttps:orwss:for secure connections. - Ktor will choose the
HttpClientautomatically depending on the artifacts added in your build script. If you need more control over theHttpClientused, for example, to specify a http proxy and a custom trust manager overwrite the http client builder:
val client = MqttClient("https://test.mosquitto.org:8081") {
connection {
http = {
HttpClient(CIO) {
install(WebSockets) // Remember to install the WebSockets plugin!
install(Logging) // Helpful for debugging http connection problems
engine {
proxy = ProxyBuilder.http("http://my.proxy.com:3128")
https {
trustManager = ...
}
}
}
}
}
}See the Ktor documentation on how to configure a http client.
Wasm Support is currently experimental. Already now it shows the power of Wasm as you get a full features MQTT 5 client with merely 650kB of compiled Wasm code.
You can launch a test page with:
./gradlew wasmJsBrowserProductionRunSources are available at main.kt.
Do not expect Wasm to support plain socket connections in the future. Due to its nature, it will always require a (secure) websocket connection to your MQTT broker.
What's currently missing:
- Handling of
Authentication MethodandAuthentication Datafields in theCONNACKmessage - Handling of the
Receive Maximum,Retain Available,Maximum Packet Size,Wildcard Subscription AvailableShared Subscription Availableflags in theCONNACKmessage