feat(Core): update DTOs and shared models

This commit is contained in:
2026-08-09 21:01:38 +02:00
parent 6337e63a77
commit 5475c3ac51
58 changed files with 3418 additions and 30 deletions
+34 -8
View File
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Text;
using System.Text.Json;
@@ -150,15 +150,34 @@ public abstract class ManagedMqttClient : IDisposable
/// <summary>
/// Serializes a generic object into a structured JSON string and publishes it to the specified topic.
/// Utilizes .NET 8 JSON Source Generators for zero-reflection overhead, with reflection fallback for unregistered types.
/// </summary>
public Task PublishAsync<T>(string topic, T data, bool retain = false)
{
var jsonOptions = new JsonSerializerOptions
byte[] jsonBytes;
var typeInfo = FinlyticJsonSerializerContext.Default.GetTypeInfo(typeof(T))
?? (data != null ? FinlyticJsonSerializerContext.Default.GetTypeInfo(data.GetType()) : null);
if (typeInfo != null)
{
ReferenceHandler = ReferenceHandler.IgnoreCycles
};
var json = JsonSerializer.Serialize(data, jsonOptions);
return PublishAsync(topic, json, retain);
jsonBytes = JsonSerializer.SerializeToUtf8Bytes(data, typeInfo);
}
else
{
jsonBytes = JsonSerializer.SerializeToUtf8Bytes(data);
}
if (!IsConnected)
throw new InvalidOperationException("Cannot publish message: MQTT client is offline.");
var message = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(jsonBytes)
.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)
.WithRetainFlag(retain)
.Build();
return _mqttClient.PublishAsync(message, CancellationToken.None);
}
/// <summary>
@@ -190,12 +209,12 @@ public abstract class ManagedMqttClient : IDisposable
// 2. Serialize and dispatch via the existing JSON helper
await PublishAsync(requestTopic, requestData);
_logger.LogDebug("RPC request published to '{Topic}' [CorrelationId: {Id}]", requestTopic, correlationId);
_logger.LogInformation("RPC request published to '{Topic}' [CorrelationId: {Id}]", requestTopic, correlationId);
try
{
// 3. Block asynchronously until the response loop resolves the token
var effectiveTimeout = timeout ?? TimeSpan.FromSeconds(10);
var effectiveTimeout = timeout ?? TimeSpan.FromSeconds(25);
var rawJsonResult = await tcs.Task.WaitAsync(effectiveTimeout);
if (typeof(TResponse) == typeof(string))
@@ -203,6 +222,12 @@ public abstract class ManagedMqttClient : IDisposable
return rawJsonResult as TResponse;
}
var respTypeInfo = FinlyticJsonSerializerContext.Default.GetTypeInfo(typeof(TResponse));
if (respTypeInfo != null)
{
return JsonSerializer.Deserialize(rawJsonResult, respTypeInfo) as TResponse;
}
return JsonSerializer.Deserialize<TResponse>(rawJsonResult);
}
catch (TimeoutException)
@@ -223,6 +248,7 @@ public abstract class ManagedMqttClient : IDisposable
{
var topic = e.ApplicationMessage.Topic;
var payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
_logger.LogInformation("MQTT message received on topic '{Topic}', length={Length}", topic, payload?.Length ?? 0);
// Intercept message if it belongs to the RPC response convention
if (topic.StartsWith("services/response/"))