見出し画像

【Unity】MQTTnetでMQTT通信する

今回はMQTTnetを使ってUnityでMQTT通信を行ってみたいと思います。

1. MQTTnet

MQTTnetはMQTTを簡単に扱えるようにするための.NETライブラリで、積極的にメンテナンスもされているようです。Unityから利用するには、まず上記のリポジトリからリリースページへ飛んでzipファイルをダウンロードします。

スクリーンショット 2021-06-29 102338_New

MQTTnetのバージョンはv3.0.7を使用します。というのも、MQTTnetはUnity専用ライブラリではないため、.NETのバージョンによっては動作しない場合があります。2021年6月の時点の最新版(v3.0.16)は動作しませんでした。

使用するUnityのバージョンは2020.3.12f1で解説を進めていきますが、.NETのバージョンを.NET 4.0にするとv3.0.12までいけそうな雰囲気でした。

スクリーンショット 2021-06-29 104035

このあたりは、使用する.NETのバージョンや安定性を実際に確認するなどして最終的に決めてください。今回の環境をまとめると以下の通りです。

・Unity:2020.3.12f1
・MQTTnet:v3.0.7
・API Level:.NET Standard 2.0

Unityへのインポートはzipの中にある「MQTTnet.dll」をプロジェクトウィンドウへドラッグアンドドロップします。

スクリーンショット 2021-06-29 104551_New

2. コード

以下のスクリプトを適当なオブジェクトにアタッチします。

using UnityEngine;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Receiving;
using MQTTnet.Client.Disconnecting;
using System.Threading;
using System.Threading.Tasks;
using System;
using System.Text;

public class Controller : MonoBehaviour
{
   private IMqttClient mqttClient;
   private IMqttClientOptions options;
   private string host = "localhost";

   async void Start() {
       mqttClient = new MqttFactory().CreateMqttClient();
    
       options = new MqttClientOptionsBuilder()
           .WithTcpServer(host, 1883)
           .Build();

       mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnAppMessage);
       mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnConnected);
       mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnDisconnected);

       try {
           await mqttClient.ConnectAsync(options);
       } catch {

       }
   }
   
   private async void OnConnected(MqttClientConnectedEventArgs e) {
       Debug.Log("MQTT broker connected");
       await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("/themes/current").Build());
       Debug.Log("TOPIC Subscribed");
   }

   private void OnAppMessage(MqttApplicationMessageReceivedEventArgs e) {
       Debug.Log("OnAppMessage");
       string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
       Debug.Log(payload);
   }

   private async void OnDisconnected(MqttClientDisconnectedEventArgs e) {

       if (mqttClient == null) {
           Debug.Log("MQTT Client is disposed");
           return;
       } else {
           Debug.Log("接続に失敗しました。5秒後に再接続を試みます");
       }

       await Task.Delay(TimeSpan.FromSeconds(5));

       try {
           Debug.Log("接続を開始します");
           await mqttClient.ConnectAsync(options);
       } catch {
       
       }
   }

   private void Update() {
       if (Input.GetKeyDown(KeyCode.S)) {
           PubMessage();
       }
   }

   private async void PubMessage() {
       Debug.Log("Send");

       var message = new MqttApplicationMessageBuilder()
           .WithTopic("/themes/test")
           .WithPayload("Hello World")
           .WithExactlyOnceQoS()
           .WithRetainFlag()
           .Build();

       await mqttClient.PublishAsync(message, CancellationToken.None);
   }

   private void OnDestroy() {
       Debug.Log("OnDestroy");
       mqttClient.Dispose();
       mqttClient = null;// 意図的な切断
   }
}

受信処理はOnAppMessage、送信処理はPubMessageで行っています。MQTTではBrokerを経由してメッセージをやり取りするため、受信側と送信側とで記述方式があまり大きく変わらないのが特徴です。

何でも - Frame 1 (1)

3. Brokerの準備

動作確認をするためにメッセージを中継するBrokerを準備します。BrokerはMQTTソフトウェアでは有名な「Mosquitto」を使用します。Mosquittoは以下のページからダウンロードできます。

今回はWindows環境で進めていきます。インストールが完了したらコマンドプロンプトを開き「C:\Program Files\mosquitto」へ移動します。移動したら「mosquitto.exe」を実行します。場合によっては既に立ち上がっていることもあります。これでBrokerが立ち上がりました。

4. 実行

Brokerの準備が整ったらUnityエディタ上で実行します。再びコマンドプロンプトから「C:\Program Files\mosquitto」へ移動し、以下のコマンドを実行してメッセージを送ります。

mosquitto_pub -d -t "/themes/current" -m "hoge"

内容としては、トピックの"/themes/current"に"hoge"というメッセージを送っています。送り先ホスト(Broker)を指定しなければデフォルトでlocalhostになります。送信後、UnityエディタのConsoleにログが表示されていれば受信は成功です。

スクリーンショット 2021-06-29 112703

次に、コマンドプロンプトから以下のコマンドを実行してメッセージの受信を待機します。

mosquitto_sub -d -t "/themes/test"

その後、Unityエディタから「s」キーを押してコマンドプロンプト上でメッセージが表示されれば送信は成功です。

無題

5. おわりに

接続形態としては1:N、N:Nの複数のノードや端末でやり取りする用途としてMQTTはおすすめです。いわゆるIoT向けのリアルタイム軽量プロトコルとして注目されていますので、Unityと組み合わせることで色々面白いことができるかもしれませんね。🌱

6. 参考


この記事が気に入ったらサポートをしてみませんか?