Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

76 wiersze
2.5 KiB

  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Threading.Tasks;
  4. using MQTTnet.Packets;
  5. namespace MQTTnet.Client
  6. {
  7. public class MqttPacketDispatcher
  8. {
  9. private readonly ConcurrentDictionary<Tuple<ushort, Type>, TaskCompletionSource<MqttBasePacket>> _awaiters = new ConcurrentDictionary<Tuple<ushort, Type>, TaskCompletionSource<MqttBasePacket>>();
  10. public void Dispatch(Exception exception)
  11. {
  12. foreach (var awaiter in _awaiters)
  13. {
  14. awaiter.Value.SetException(exception);
  15. }
  16. }
  17. public void Dispatch(MqttBasePacket packet)
  18. {
  19. if (packet == null) throw new ArgumentNullException(nameof(packet));
  20. ushort identifier = 0;
  21. if (packet is IMqttPacketWithIdentifier packetWithIdentifier && packetWithIdentifier.PacketIdentifier.HasValue)
  22. {
  23. identifier = packetWithIdentifier.PacketIdentifier.Value;
  24. }
  25. var type = packet.GetType();
  26. var key = new Tuple<ushort, Type>(identifier, type);
  27. if (_awaiters.TryRemove(key, out var tcs))
  28. {
  29. tcs.TrySetResult(packet);
  30. return;
  31. }
  32. throw new InvalidOperationException($"Packet of type '{type.Name}' not handled or dispatched.");
  33. }
  34. public void Reset()
  35. {
  36. _awaiters.Clear();
  37. }
  38. public TaskCompletionSource<MqttBasePacket> AddPacketAwaiter<TResponsePacket>(ushort? identifier) where TResponsePacket : MqttBasePacket
  39. {
  40. var tcs = new TaskCompletionSource<MqttBasePacket>();
  41. if (!identifier.HasValue)
  42. {
  43. identifier = 0;
  44. }
  45. var key = new Tuple<ushort, Type>(identifier ?? 0, typeof(TResponsePacket));
  46. if (!_awaiters.TryAdd(key, tcs))
  47. {
  48. throw new InvalidOperationException($"The packet dispatcher already has an awaiter for packet of type '{key.Item2.Name}' with identifier {key.Item1}.");
  49. }
  50. return tcs;
  51. }
  52. public void RemovePacketAwaiter<TResponsePacket>(ushort? identifier) where TResponsePacket : MqttBasePacket
  53. {
  54. if (!identifier.HasValue)
  55. {
  56. identifier = 0;
  57. }
  58. var key = new Tuple<ushort, Type>(identifier ?? 0, typeof(TResponsePacket));
  59. _awaiters.TryRemove(key, out var _);
  60. }
  61. }
  62. }