-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* generic client * add generic command client * status in user properties * all green 1 by 1 --------- Co-authored-by: ridomin <[email protected]>
- Loading branch information
Showing
7 changed files
with
152 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 79 additions & 5 deletions
84
src/MQTTnet.Extensions.MultiCloud.BrokerIoTClient/Untyped/GenericCommandClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,89 @@ | ||
using MQTTnet.Client; | ||
using MQTTnet.Extensions.MultiCloud.Binders; | ||
|
||
using MQTTnet.Extensions.MultiCloud.Serializers; | ||
using MQTTnet.Server; | ||
using System.Xml.Linq; | ||
|
||
namespace MQTTnet.Extensions.MultiCloud.BrokerIoTClient.Untyped; | ||
|
||
public class GenericCommandClient : RequestResponseBinder<GenericCommandRequest, GenericCommandResponse> | ||
public class GenericCommandClient //: RequestResponseBinder<GenericCommandRequest, GenericCommandResponse> | ||
{ | ||
public GenericCommandClient(IMqttClient client) : base(client, string.Empty, false) | ||
|
||
readonly IMqttClient _mqttClient; | ||
readonly IMessageSerializer _serializer; | ||
TaskCompletionSource<GenericCommandResponse>? _tcs; | ||
string? _commandName; | ||
string _remoteClientId; | ||
Guid corr = Guid.NewGuid(); | ||
|
||
|
||
string requestTopicPattern = "device/{clientId}/commands/{commandName}"; | ||
string responseTopicSub = "device/{clientId}/commands/{commandName}/+"; | ||
string responseTopicSuccess = "device/{clientId}/commands/{commandName}/resp"; | ||
//protected string responseTopicFailure = "device/{clientId}/commands/{commandName}/err"; | ||
|
||
|
||
public GenericCommandClient(IMqttClient client) //: base(client, string.Empty, false) | ||
{ | ||
_mqttClient = client; | ||
_remoteClientId = string.Empty; | ||
_serializer = new UTF8JsonSerializer(); | ||
|
||
_mqttClient.ApplicationMessageReceivedAsync += async m => | ||
{ | ||
var topic = m.ApplicationMessage.Topic; | ||
|
||
var expectedTopic = responseTopicSuccess.Replace("{clientId}", _remoteClientId).Replace("{commandName}", _commandName); | ||
if (topic.StartsWith(expectedTopic)) | ||
{ | ||
if (m.ApplicationMessage.CorrelationData != null && corr != new Guid(m.ApplicationMessage.CorrelationData)) | ||
{ | ||
_tcs!.SetException(new ApplicationException("Invalid correlation data")); | ||
} | ||
|
||
//int status = m.ApplicationMessage.UserProperties.Contains(new Packets.MqttUserProperty("status", "200")) ? 200 : 500; | ||
var up = m.ApplicationMessage.UserProperties.FirstOrDefault(p => p.Name.Equals("status")); | ||
int status = up != null ? int.Parse(up.Value) : 500; | ||
|
||
if (_serializer.TryReadFromBytes(m.ApplicationMessage.Payload, string.Empty, out string respPayload)) | ||
{ | ||
GenericCommandResponse resp = new() | ||
{ | ||
Status = status, | ||
ReponsePayload = respPayload | ||
}; | ||
_tcs!.SetResult(resp); | ||
} | ||
else | ||
{ | ||
_tcs!.SetException(new ApplicationException("Cannot deserialize bytes")); | ||
} | ||
|
||
} | ||
await Task.Yield(); | ||
}; | ||
} | ||
|
||
public async Task<GenericCommandResponse> InvokeAsync(string clientId, GenericCommandRequest request, CancellationToken ct = default) | ||
{ | ||
|
||
_tcs = new TaskCompletionSource<GenericCommandResponse>(); | ||
_remoteClientId = clientId; | ||
_commandName = request.CommandName; | ||
string commandTopic = requestTopicPattern.Replace("{clientId}", _remoteClientId).Replace("{commandName}", _commandName); | ||
var responseTopic = responseTopicSub.Replace("{clientId}", _remoteClientId).Replace("{commandName}", _commandName); | ||
await _mqttClient.SubscribeAsync(responseTopic, Protocol.MqttQualityOfServiceLevel.AtMostOnce, ct); | ||
|
||
var pubAck = await _mqttClient.PublishAsync( | ||
new MqttApplicationMessageBuilder() | ||
.WithTopic(commandTopic) | ||
.WithPayload(_serializer.ToBytes(request.CommandPayload)) | ||
.WithResponseTopic(responseTopicSuccess.Replace("{clientId}", _remoteClientId).Replace("{commandName}", _commandName)) | ||
.WithCorrelationData(corr.ToByteArray()) | ||
.Build()); | ||
if (!pubAck.IsSuccess) | ||
{ | ||
throw new ApplicationException("Error publishing Request Message"); | ||
} | ||
return await _tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(5)); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters