Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

119 rader
4.1 KiB

  1. using Microsoft.AspNetCore.Connections;
  2. using MQTTnet.Adapter;
  3. using MQTTnet.AspNetCore.Client.Tcp;
  4. using MQTTnet.Exceptions;
  5. using MQTTnet.Packets;
  6. using MQTTnet.Serializer;
  7. using System;
  8. using System.IO.Pipelines;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. namespace MQTTnet.AspNetCore
  12. {
  13. public class MqttConnectionContext : IMqttChannelAdapter
  14. {
  15. public MqttConnectionContext(
  16. IMqttPacketSerializer packetSerializer,
  17. ConnectionContext connection)
  18. {
  19. PacketSerializer = packetSerializer;
  20. Connection = connection;
  21. }
  22. public string Endpoint => Connection.ConnectionId;
  23. public ConnectionContext Connection { get; }
  24. public IMqttPacketSerializer PacketSerializer { get; }
  25. public event EventHandler ReadingPacketStarted;
  26. public event EventHandler ReadingPacketCompleted;
  27. public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
  28. {
  29. if (Connection is TcpConnection tcp && !tcp.IsConnected)
  30. {
  31. return tcp.StartAsync();
  32. }
  33. return Task.CompletedTask;
  34. }
  35. public Task DisconnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
  36. {
  37. Connection.Transport.Input.Complete();
  38. Connection.Transport.Output.Complete();
  39. return Task.CompletedTask;
  40. }
  41. public async Task<MqttBasePacket> ReceivePacketAsync(TimeSpan timeout, CancellationToken cancellationToken)
  42. {
  43. var input = Connection.Transport.Input;
  44. try
  45. {
  46. while (!cancellationToken.IsCancellationRequested)
  47. {
  48. ReadResult readResult;
  49. var readTask = input.ReadAsync(cancellationToken);
  50. if (readTask.IsCompleted)
  51. {
  52. readResult = readTask.Result;
  53. }
  54. else
  55. {
  56. readResult = await readTask;
  57. }
  58. var buffer = readResult.Buffer;
  59. var consumed = buffer.Start;
  60. var observed = buffer.Start;
  61. try
  62. {
  63. if (!buffer.IsEmpty)
  64. {
  65. if (PacketSerializer.TryDeserialize(buffer, out var packet, out consumed, out observed))
  66. {
  67. return packet;
  68. }
  69. else
  70. {
  71. // we did receive something but the message is not yet complete
  72. ReadingPacketStarted?.Invoke(this, EventArgs.Empty);
  73. }
  74. }
  75. else if (readResult.IsCompleted)
  76. {
  77. throw new MqttCommunicationException("Connection Aborted");
  78. }
  79. }
  80. finally
  81. {
  82. // The buffer was sliced up to where it was consumed, so we can just advance to the start.
  83. // We mark examined as buffer.End so that if we didn't receive a full frame, we'll wait for more data
  84. // before yielding the read again.
  85. input.AdvanceTo(consumed, observed);
  86. }
  87. }
  88. }
  89. finally
  90. {
  91. ReadingPacketCompleted?.Invoke(this, EventArgs.Empty);
  92. }
  93. cancellationToken.ThrowIfCancellationRequested();
  94. return null;
  95. }
  96. public Task SendPacketAsync(MqttBasePacket packet, CancellationToken cancellationToken)
  97. {
  98. var buffer = PacketSerializer.Serialize(packet);
  99. return Connection.Transport.Output.WriteAsync(buffer.AsMemory(), cancellationToken).AsTask();
  100. }
  101. public void Dispose()
  102. {
  103. }
  104. }
  105. }