From 39343e32c59d4fe21f79248458afa05f8af3a76a Mon Sep 17 00:00:00 2001 From: dev02 Date: Thu, 27 Feb 2025 13:07:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E8=BD=89=E5=A2=9Emqtt=20publish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mqtt/Controllers/AlarmController.cs | 34 +++++++++- Mqtt/Models/HTTP.cs | 99 +++++++++++++++++++++++++++++ Mqtt/Services/MqttClientService.cs | 9 +-- 3 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 Mqtt/Models/HTTP.cs diff --git a/Mqtt/Controllers/AlarmController.cs b/Mqtt/Controllers/AlarmController.cs index 0cb0ce4..33190b4 100644 --- a/Mqtt/Controllers/AlarmController.cs +++ b/Mqtt/Controllers/AlarmController.cs @@ -9,6 +9,7 @@ using MQTTnet.Client; using Repository.BackendRepository.Interface; using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace Mqtt.Controllers @@ -41,7 +42,7 @@ namespace Mqtt.Controllers } [HttpPost] - public async Task AlarmResult() + public async Task AlarmRefresh() { try { @@ -58,5 +59,36 @@ namespace Mqtt.Controllers return new OkObjectResult(dic); } + + [HttpPost] + public async Task Publish([FromBody] HTTPBody body) + { + try + { + if (!body.data.ContainsKey("topic")) + { + dic.Add("ok", false); + dic.Add("msg", "請輸入標題"); + } + + if (!body.data.ContainsKey("message")) + { + dic.Add("ok", false); + dic.Add("msg", "請輸入内容"); + } + + await new MqttClientService(_logger, _configuration, _backgroundServicePostgresqlRepository, _backendRepository).PublishAsync(body.data["topic"].ToString(), body.data["message"].ToString()); + dic.Add("ok", true); + dic.Add("msg", $"{body.data["topic"].ToString()}發佈成功"); + } + catch (Exception e) + { + dic.Add("ok", false); + dic.Add("msg", "發佈失敗"); + _logger.LogError($"發佈失敗, Message: {e.Message}"); + } + + return new OkObjectResult(dic); + } } } \ No newline at end of file diff --git a/Mqtt/Models/HTTP.cs b/Mqtt/Models/HTTP.cs new file mode 100644 index 0000000..4386f06 --- /dev/null +++ b/Mqtt/Models/HTTP.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Mqtt.Models +{ + public class HTTPBody + { + [JsonConverter(typeof(DictionaryStringObjectJsonConverter))] + public Dictionary data { get; set; } + } + + public class DictionaryStringObjectJsonConverter : JsonConverter> + { + public override Dictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException($"JsonTokenType was of type {reader.TokenType}, only objects are supported"); + } + + Dictionary dictionary = new Dictionary(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return dictionary; + } + + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException("JsonTokenType was not PropertyName"); + } + + string @string = reader.GetString(); + if (string.IsNullOrWhiteSpace(@string)) + { + throw new JsonException("Failed to get property name"); + } + + reader.Read(); + dictionary.Add(@string, ExtractValue(ref reader, options)); + } + + return dictionary; + } + + public override void Write(Utf8JsonWriter writer, Dictionary value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value, options); + } + + private object ExtractValue(ref Utf8JsonReader reader, JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.String: + { + if (reader.TryGetDateTime(out var value2)) + { + return value2; + } + + return reader.GetString(); + } + case JsonTokenType.False: + return false; + case JsonTokenType.True: + return true; + case JsonTokenType.Null: + return null; + case JsonTokenType.Number: + { + if (reader.TryGetInt64(out var value)) + { + return value; + } + + return reader.GetDecimal(); + } + case JsonTokenType.StartObject: + return Read(ref reader, null, options); + case JsonTokenType.StartArray: + { + List list = new List(); + while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) + { + list.Add(ExtractValue(ref reader, options)); + } + + return list; + } + default: + throw new JsonException($"'{reader.TokenType}' is not supported"); + } + } + } +} diff --git a/Mqtt/Services/MqttClientService.cs b/Mqtt/Services/MqttClientService.cs index 8c93f31..3fbd08b 100644 --- a/Mqtt/Services/MqttClientService.cs +++ b/Mqtt/Services/MqttClientService.cs @@ -377,17 +377,18 @@ namespace Mqtt.Services public async Task PublishAsync(string topic, string payload) { - if (_mqttClient.IsConnected) + if (_mqttClients.Count > 0 && _mqttClients.ContainsKey(topic)) { var message = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(payload) + .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce) //.WithExactlyOnceQoS() - .WithRetainFlag() + .WithRetainFlag(false) .Build(); - await _mqttClient.PublishAsync(message); - Console.WriteLine($"Published message to topic {topic}: {payload}"); + await _mqttClients[topic].PublishAsync(message); + _logger.LogInformation($"{topic} published message: {payload}"); } } }