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.
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 is the return value of this method.
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.5.0")
implementation("de.kempmobil.ktor.mqtt:mqtt-client:0.5.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.5.0")
implementation("de.kempmobil.ktor.mqtt:mqtt-client:0.5.0")
}
}
}
}
Ktor and this library are based on kotlinx-io
, which is
available for Android 5.0+ (API level 21+).
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.5.0")
implementation("io.ktor:ktor-client-cio:3.0.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
HttpClient
automatically depending on the artifacts added in your build script. If you need more control over theHttpClient
used, 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.
What's currently missing:
- Handling of MQTT sessions: the clean start flag is currently always set to
true
- Handling of
Authentication Method
andAuthentication Data
fields in theCONNACK
message - Handling of the
Receive Maximum
,Retain Available
,Maximum Packet Size
,Wildcard Subscription Available
Shared Subscription Available
flags in theCONNACK
message