Visual Studio for Mac(C#) でアプリを書いて、RaspberryPiからAWS IoTへ接続してみた(.NET Core編)

AWS IoT では、インターネットに接続された各種デバイスからMQTTを使用してデータを送受信できます。また、受信したデータは、ルールを設定することで、LambdaやDynamoDBなど各種AWSサービスへ連携することができます。 今回は.NET Core (C#) でAWSIoTへのパブリッシュとサブスクライブを行うサンプルを作成し、RaspberryPIで実行してみました。
2018.07.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

昨日、下記の記事を投稿しました。そして、Raspberry.Pi上のMonoで利用しようとしたのですが、M2Mqttをうまく動かせませんでした。

pi@raspberrypi:~ $ mono MonoAWSIotSample.exe

Unhandled Exception:
uPLibrary.Networking.M2Mqtt.Exceptions.MqttConnectionException: Exception connecting to the broker ---> System.IO.IOException: The authentication or decryption has failed. ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (System.IAsyncResult asyncResult) [0x00040] in <1d0bb82c94e7435eb09324cf5ef20e36>:0

・・・略

なんとか、このままRaspberryPiで動かしたいということで・・・.NET Coreでコンパイルすると、うまく行ったので、ちょっと紹介させて下さい。

ソースコードは、まったく変更してません。

2 プロジェクト作成

プロジェクトは、.NET Core > アプリ > コンソールアプリケーションから作成します。

プロジェクト名は、DotNetCoreAWSIotSampleとしました。

3 パッケージ追加

NuGetから追加するパッケージは、M2Mqtt及び、 Pit.M2Mqtt の2つです。

4 実装

ソースコードは、前回と全く同じです。

using System;
using System.Text;
using System.Security.Cryptography.X509Certificates;

using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

namespace MonoAWSIotSample
{
    class MainClass
    {

        const string endpoint = "xxxxxxxx.iot.us-east-1.amazonaws.com";

        const string clientCertFile = "MonoAWSIotSample.pfx";
        const string clientCertPassword = "xxxxxx";
        const string rootCaFile = "root-CA.crt";

        const string topic = "sample_topic";

        public static void Main(string[] args)
        {
            var clientCert = new X509Certificate2(clientCertFile, clientCertPassword);
            var rootCa = X509Certificate.CreateFromCertFile(rootCaFile);

            AWSIot iot = new AWSIot(endpoint, clientCert, rootCa);

            // Subscribe
            iot.Recv += Recv;
            iot.Subscribe(topic);

            // Publish
            iot.Publish(topic, "DotNetAWSIotSampleからのメッセージ!");

            Console.ReadLine();
        }

        static void Recv(string message)
        {
            Console.WriteLine(message);
        }
    }

    delegate void RevcHandler(string message);

    class AWSIot
    {
        public event RevcHandler Recv = null;

        // AWS IoTでは、TLS1.2ポートが使用されている
        private const int BrokerPort = 8883;
        MqttClient client;

        public AWSIot(string endpoint, X509Certificate2 clientCert, X509Certificate rootCa)
        {

            client = new MqttClient(endpoint, BrokerPort, true, rootCa, clientCert, MqttSslProtocols.TLSv1_2);
            client.Connect("clientid1");
            if (client.IsConnected)
            {
                Console.WriteLine("AWSIot Connected.");
            }
            client.MqttMsgPublishReceived += MessageReceived;
        }

        public void Subscribe(string Topic)
        {
            client.Subscribe(new[] { Topic }, new[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
        }

        public void Publish(string Topic, string message)
        {
            client.Publish(Topic, Encoding.UTF8.GetBytes(message));
        }

        void MessageReceived(object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishEventArgs e)
        {
            Recv(new String(Encoding.UTF8.GetChars(e.Message)));
        }
    }
}

5 動作確認

RaspberryPiには、予め .NET Core (2.1)のランタイムをインストールしています。

pi@raspberrypi:~/dotnet_mqtt $ dotnet --info

Host (useful for support):
  Version: 2.1.2
  Commit:  811c3ce6c0

.NET Core SDKs installed:
  No SDKs were found.

.NET Core runtimes installed:
  Microsoft.NETCore.App 2.1.2 [/opt/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

必要なファイルを転送します。

pi@raspberrypi:~/dotnet_mqtt $ ls -la
drwxr-xr-x  2 pi pi  4096  7月 28 21:56 .
drwxr-xr-x 27 pi pi  4096  7月 28 21:20 ..
-rw-r--r--  1 pi pi  7168  7月 28 21:52 DotNetCoreAWSIotSample.dll
-rw-r--r--  1 pi pi   146  7月 28 21:23 DotNetCoreAWSIotSample.runtimeconfig.json
-rwxr--r--  1 pi pi 50688  7月 28 21:53 M2Mqtt.Net.dll
-rw-r--r--  1 pi pi  3749  7月 28 21:23 MonoAWSIotSample.pfx
-rw-r--r--  1 pi pi  1758  7月 28 21:23 root-CA.crt

実行している様子です。 AWS Iot Coreのテスト画面で、メッセージのやり取りを確認できます。

pi@raspberrypi:~/dotnet_mqtt $ dotnet DotNetCoreAWSIotSample.dll

6 最後に

.NET Coreだと、あったり動きました。C#でRaspberryPiからAWS IoTできるのは、個人的に超快適です。私だけでしょうか・・・・

7 参考リンク


MQTT Client Library Encyclopedia – M2Mqtt
Visual Studio for Mac
Visual Studio for Mac(C#)でAWS IoTへ接続してみた。