2017年8月、MQTT 5.0のドラフトがOASIS MQTT技術委員会によって公開レビューのために公式にリリースされました。2018年に、MQTT 5.0の公式バージョンがリリースされました。しかし、Appleのエコシステムにおいて、MQTT 5.0 を完全にサポートするクライアントSDKはまだありません。
CocoaMQTTは、現在iOS開発者に広く使用されているEMQがiOS開発者のために提供するMQTTクライアントSDKです。AppleのエコシステムにおけるMQTT 5.0サポートのギャップを埋めるために、EMQチームは最近新しいCocoaMQTT v2.0を公式にリリースしました。 CocoaMQTT v2.0はMQTT 5.0をサポートしており、バージョン3.1.1と互換性があり、iOS、tvOS、OSXオペレーティングシステムをサポートしています。ユーザーは今、CocoaMQTTを通じてiOSシステムデバイスをMQTT 5.0クラウドサービスに接続し、MQTT5.0が提供する強力な機能を楽しむことができます。
CocoaMQTTは、Objective-CではなくSwift言語で開発されています。これは、Swiftが型安全な言語で、プロトコルのサポートが豊富だからです。拡張機能、汎用機能、アソシエーション型と組み合わせたプロトコル指向プログラミングにより、コードの柔軟性が大幅に向上します。
さらに、WWDC 2021カンファレンスで、AppleはSwift言語の並列モデルの大幅な更新を発表しました: コンパイラによって実装されたアクター並列モデルと、新しいアクター参照型は、開発者がデータ競合の問題を回避するのに役立ちます。 したがって、私たちはまた、MQTT関連のI/O集中型並列アプリケーションにおいて、SwiftのパフォーマンスがObjective-Cよりも期待できると信じています。
MQTT 5.0 vs MQTT 3.1.1
MQTT 3.1.1にはまだ多くの不備があります。 たとえば、接続が異常に切断された場合、相手側は理由を通知できません。 MQTT 5.0では、MQTT 3.1.1をベースに多くの変更が加えられていますが、下位互換性はありません。 MQTT 5.0は、セッション/メッセージ遅延、理由コード、トピックエイリアス、飛行中ストリーム制御、ユーザープロパティ、共有サブスクリプションなどの新機能を追加するとともに、認証セキュリティを強化するためのAUTHパケットを追加しています。 理由コードとユーザープロパティフィールドにより、MQTT 5.0は、バージョン3.1.1では不完全なプロトコルのために対処が難しい問題に、より多くのコンテキスト情報を運ぶことができます。
MQTT 5.0の主な機能上の利点は以下のとおりです。
- より大規模な拡張可能なシステムのさらなるサポート
- より詳細なエラー報告と処理メカニズム
- 容量探索および要求-応答などの一般モードの標準化された操作
- 拡張可能なユーザープロパティ
- パフォーマンスの改善と小さいクライアントのサポート
- セッションの保持とメッセージのタイムアウト設定
- 要求/応答メッセージモードの新しいサポート
iOSクライアントでのMQTTの使い方 - CocoaMQTT
この記事では、EMQが提供するFree Public MQTT Brokerを使用して、CocoaMQTTの機能を紹介します。このサービスは、MQTTクラウドサービス - EMQX Cloudに基づいて作成されています。
ブローカーへのアクセス情報は以下のとおりです。
- ブローカー: broker.emqx.io
- TCPポート: 1883
- Websocketポート: 8083
- TCP/TLSポート: 8883
- Websocket/TLSポート:8084
MQTTサービスへの接続
MQTT 5.0では多くのプロパティが追加されたことがわかります。その中で、Property
フィールドを使用することで、ユーザーは自身の状況に応じてより詳細な要件を満たすことができます。
///MQTT 5.0
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
let mqtt5 = CocoaMQTT5(clientID: clientID, host: "broker.emqx.io", port: 1883)
let connectProperties = MqttConnectProperties()
connectProperties.topicAliasMaximum = 0
connectProperties.sessionExpiryInterval = 0
connectProperties.receiveMaximum = 100
connectProperties.maximumPacketSize = 500
mqtt5.connectProperties = connectProperties
mqtt5.username = "test"
mqtt5.password = "public"
mqtt5.willMessage = CocoaMQTTWill(topic: "/will", message: "dieout")
mqtt5.keepAlive = 60
mqtt5.delegate = self
mqtt5.connect()
///MQTT 3.1.1
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
let mqtt = CocoaMQTT(clientID: clientID, host: "broker.emqx.io", port: 1883)
mqtt.username = "test"
mqtt.password = "public"
mqtt.willMessage = CocoaMQTTWill(topic: "/will", message: "dieout")
mqtt.keepAlive = 60
mqtt.delegate = self
mqtt.connect()
サブスクライブ
MQTT 5.0には、MQTT 3.1.1よりもサブスクリプションオプションなどの操作が多くあります。
///MQTT 5.0
mqtt5.subscribe("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1)
//または
//let subscriptions : [MqttSubscription] = [MqttSubscription(topic: "chat/room/animals/client/+"),MqttSubscription(topic: "chat/room/foods/client/+"),MqttSubscription(topic: "chat/room/trees/client/+")]
//mqtt.subscribe(subscriptions)
///MQTT 3.1.1
mqtt.subscribe("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1)
//または
//let subscriptions : [(String, CocoaMQTTQoS)] = [("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1),("chat/room/foods/client/+", qos: CocoaMQTTQoS.qos1),("chat/room/trees/client/+", qos: CocoaMQTTQoS.qos1)]
//mqtt.subscribe(subscriptions)
パブリッシュ
///MQTT 5.0
mqtt5!.publish("chat/room/animals/client/" + animal!, withString: message!, qos: .qos1, DUP: false, retained: false, properties: publishProperties)
///MQTT 3.1.1
mqtt!.publish("chat/room/animals/client/" + animal!, withString: message!, qos: .qos1)
自動再接続
MQTTはTCP長接続に基づくプロトコルです。実際のシナリオでは、ネットワーク障害や信号の問題による接続の中断は一般的な問題です。多くの開発者は、SDKが自動的に再接続する便利な方法を提供してほしいと考えています。
///MQTT 5.0
mqtt5!.autoReconnect = true
///MQTT 3.1.1
mqtt!.autoReconnect = true
単方向および双方向SSL
///MQTT 5.0
mqtt5!.enableSSL = true
///MQTT 3.1.1
mqtt!.enableSSL = true
let clientCertArray = getClientCertFromP12File(certName: "client-keycert", certPassword: "MySecretPassword")
var sslSettings: [String: NSObject] = [:]
sslSettings[kCFStreamSSLCertificates as String] = clientCertArray
///MQTT 5.0
mqtt5!.sslSettings = sslSettings
///MQTT 3.1.1
mqtt!.sslSettings = sslSettings
.p12
ファイルが必要な場合は、ターミナルで次のステートメントを使用して生成できます。
openssl pkcs12 -export -clcerts -in client-cert.pem -inkey client-key.pem -out client.p12
Retained MessageとWill Messageの設定
MQTT 3.1.1と比較して、MQTT 5.0にはユーザーが使用できるプロパティ設定がより多くあります。
///MQTT 5.0
let lastWillMessage = CocoaMQTTMessage(topic: "/chat/room/animals/client/Sheep", string: "dieout")
lastWillMessage.retained = true
lastWillMessage.qos = .qos1
mqtt5!.willMessage = lastWillMessage
///MQTT 3.1.1
mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string: "dieout")
AUTHパケット
MQTTは、CONNECT
だけで認証を実行するのに十分な情報をサーバーに提供していない場合があります。このため、MQTT 5.0では、クライアントとサーバー間の認証を強化するためにこの機能が追加されています。
let authProperties = MqttAuthProperties()
mqtt5!.auth(reasonCode: CocoaMQTTAUTHReasonCode.continueAuthentication, authProperties: authProperties)
バックグラウンドで実行されるiOSアプリケーション
「Background fetch」モードまたはiOS 13で新しく追加された「Background processing」モードを使用することをお勧めします。
beginBackgroundTaskWithName
と endBackgroundTask
に関連するAPIを使用する場合、アプリを30秒間バックグラウンドで実行し続けることができます。
まとめ
これまで、CocoaMQTTクライアントをパブリックMQTTブローカーに接続し、クライアントとMQTTブローカー間の接続、メッセージ送信、サブスクリプションを実現してきました。
コードは https://github.com/emqx/CocoaMQTT/tree/master/Example から入手できます。
EMQは、ユーザーがIoTビジネスを行うためにMQTTを簡単かつ便利に使用できるよう支えています。一連のクライアントSDKは継続的に開発されており、引き続きご期待ください。