🫠

あまりわからないのC#でMQTTに通信できるまでの記録

2023/07/10に公開

はじめに

元バージョンのプログラムはPollingでリクエストを取っています。
DBの負荷が重すぎるのでデットロックとかパフォーマンス低下とか嫌な状況が続出しています。

ここでまずの変更点

まずはPollingをなくなってほしいです。
そこでPollingのかわりに、MQTTでリクエストを通知したいと思います。

MQTT

C#にはまだ慣れていませんのでGoogleさんに質問をすると MQTTNet という Packageが検索結果のトップでしたから、この MQTTNet を使って行きます。
まずは MQTT 関する Class を作って行きたいと思います。

using MQTTnet;
using MQTTnet.Client;
using System.Threading;
using System.Threading.Tasks;

namespace MQTTModule.Common
{
    class MqttHelper
    {
        public IMqttClient mqttClient;
        public MqttHelper() 
        {
            _ = InitializeMqtt();
        }
        private async Task InitializeMqtt()
        {
            try
            {
                string mqttUrl = "mqtt";
                var factory = new MqttFactory();
                var client = factory.CreateMqttClient();
                var options = new MqttClientOptionsBuilder()
                    .WithTcpServer(mqttUrl, 1883)
                    .Build();
                await client.ConnectAsync(options);
                this.mqttClient = client;
            } catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

こんな感じで MQTT に接続することができました。
ですが MQTT URL が間違っていた時や MQTT Serverに通信できなかった時は try...catch...の例外が取れませんでした。
なぜがよくわからないですから、ちょっとGoogleで調べて見ると
初期化しているときの _ = InitializeMqtt() は sync の形で呼ばれたですが
InitializeMqtt この Function は async の形で執行していました。
なので async function は別のスレッドで執行しているため
初期化の _ = InitializeMqtt() は InitializeMqtt() のスレッドが開けた後終わったと判断しました。

そうすれば、async functionで throw でも無駄なことになりますね😀😀
初期化の function を直します。

public MqttHelper() 
  {
    var task = Task.Run(() => InitializeMqtt());
    try
      {
        task.Wait();
      } catch (Exception ex)
      {
        throw ex;
      }
  }

これで throw したエラーがキャッチできるになりました😭

GitHubで編集を提案

Discussion