MQTTは、IoTメッセージの交換とデータ配信を実現するための軽量かつ柔軟なプロトコルです。IoT開発者にとって、柔軟性とハードウェア/インターネットリソースのバランスをとるのに役立ちます。
KotlinはJetBrainsによって開発されたプログラミング言語です。KotlinはJVMベースなので、開発者はAndroid開発に簡単に使用でき、KotlinとJavaの混合記述もサポートしています。
この記事では、主にAndroidプラットフォームでのKotlinの使用方法を紹介し、MQTTの利用方法を説明します。
プロジェクトの初期化
Android Studioを開き、新しいプロジェクトを作成し、言語としてKotlinを選択すると、Android Studioは自動的にKotlin関連の設定を作成します。既存のプロジェクトの設定が必要な場合は、既存のアプリにKotlinを追加を参照できます。
依存関係の追加
プロジェクトのbuild.gradle
を開き、セクションdependencies
にEclipse Paho Java ClientおよびEclipse Paho Android Serviceの依存関係を追加します。
dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.4'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
}
AndroidManifest.xml
の設定
Android ServiceはAndroidベースでEclipseによって開発されたバックエンドサービスです。AndroidManifest.xmlファイルに登録する必要があります。同時に、パーミッションの登録も必要です。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
...
<service android:name="org.eclipse.paho.android.service.MqttService" />
</application>
MQTTの使用
MQTTクライアントの作成
private lateinit var mqttClient: MqttAndroidClient
// タグ
companion object {
const val TAG = "AndroidMqttClient"
}
MQTTブローカーへの接続
この記事では、EMQXが運用・管理するMQTTブローカーを使用します。EMQX MQTT Cloudは、EMQがリリースしたMQTT IoTクラウドサービスプラットフォームで、オールインワンの運用・保守とユニークな分離環境を提供します。
- ブローカー: broker.emqx.io
- TCPポート: 1883
- Websocketポート: 8083
fun connect(context: Context) {
val serverURI = "tcp://broker.emqx.io:1883"
mqttClient = MqttAndroidClient(context, serverURI, "kotlin_client")
mqttClient.setCallback(object : MqttCallback {
override fun messageArrived(topic: String?, message: MqttMessage?) {
Log.d(TAG, "Receive message: ${message.toString()} from topic: $topic")
}
override fun connectionLost(cause: Throwable?) {
Log.d(TAG, "Connection lost ${cause.toString()}")
}
override fun deliveryComplete(token: IMqttDeliveryToken?) {
}
})
val options = MqttConnectOptions()
try {
mqttClient.connect(options, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken?) {
Log.d(TAG, "Connection success")
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
Log.d(TAG, "Connection failure")
}
})
} catch (e: MqttException) {
e.printStackTrace()
}
}
MqttCallback
インターフェースには3つのメソッドが含まれています。
- messageArrived: ブローカーからの新しいメッセージを受信
- connectionLost: ブローカーへの接続が途絶えた
- deliveryComplete: ブローカーへのメッセージ配信が完了
MqttConnectOptions
は、ユーザーパスワード、タイムアウト設定などの接続設定を構成するために使用されます。詳細は関数をご覧ください。
MQTTサブスクリプションの作成
トピックのサブスクライブ
fun subscribe(topic: String, qos: Int = 1) {
try {
mqttClient.subscribe(topic, qos, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken?) {
Log.d(TAG, "Subscribed to $topic")
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
Log.d(TAG, "Failed to subscribe $topic")
}
})
} catch (e: MqttException) {
e.printStackTrace()
}
}
サブスクリプションの解除
fun unsubscribe(topic: String) {
try {
mqttClient.unsubscribe(topic, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken?) {
Log.d(TAG, "Unsubscribed to $topic")
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
Log.d(TAG, "Failed to unsubscribe $topic")
}
})
} catch (e: MqttException) {
e.printStackTrace()
}
}
メッセージのパブリッシュ
fun publish(topic: String, msg: String, qos: Int = 1, retained: Boolean = false) {
try {
val message = MqttMessage()
message.payload = msg.toByteArray()
message.qos = qos
message.isRetained = retained
mqttClient.publish(topic, message, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken?) {
Log.d(TAG, "$msg published to $topic")
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
Log.d(TAG, "Failed to publish $msg to $topic")
}
})
} catch (e: MqttException) {
e.printStackTrace()
}
}
MQTTブローカーからの切断
fun disconnect() {
try {
mqttClient.disconnect(null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken?) {
Log.d(TAG, "Disconnected")
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
Log.d(TAG, "Failed to disconnect")
}
})
} catch (e: MqttException) {
e.printStackTrace()
}
}
テスト
まず、AndroidクライアントをMQTTブローカーに接続し、トピックa/b
をサブスクライブします。すると、接続とサブスクライブが成功したログが確認できます。
MQTT 5.0クライアントツール - MQTTXを使用して、トピックa/b
にメッセージをパブリッシュすると、クライアント側にメッセージ受信のログが表示されます。
クライアントからトピックa/b
にメッセージをパブリッシュします。このトピックをサブスクライブしているため、メッセージは送信と同時に受信されます。 最後に、クライアントをMQTTブローカーから切断します。ログは以下のとおりです。
まとめ
これまで、Android上でのMQTTクライアントの構築と、クライアントとMQTTブローカーの接続、トピックのサブスクライブ、メッセージングなどの実装を行ってきました。
MQTTは、限られた帯域幅でリモートデバイスをリアルタイムかつ信頼性高くメッセージングできるようにします。 コストが低く、帯域幅の使用量も少ないため、IoT、小型機器、モバイルアプリケーションなどで幅広く利用されています。
次は、EMQXが提供するMQTTプロトコルのわかりやすいガイドシリーズの記事をチェックして、MQTTプロトコルの機能を学習し、MQTTのより高度なアプリケーションを探求して、MQTTアプリケーションとサービスの開発を開始してください。
この文書の内容を日本語に翻訳することで、原文の正確性を保ちながら、MQTTの概要とAndroidでの実装方法が分かりやすく翻訳されていると思います。技術文書の翻訳では、原文の技術用語や内容構成をできるだけ保持しつつ、平易な日本語表現を用いることが重要です。今回の翻訳は MQTTの基本的な概念とAndroidでの実践方法が適切に伝わる内容になっていると考えます。