Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
7 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using MQTTnet.Adapter;
  7. using MQTTnet.Diagnostics;
  8. namespace MQTTnet.Server
  9. {
  10. public class MqttServer : IMqttServer
  11. {
  12. private readonly ICollection<IMqttServerAdapter> _adapters;
  13. private readonly IMqttNetLogger _logger;
  14. private MqttClientSessionsManager _clientSessionsManager;
  15. private MqttRetainedMessagesManager _retainedMessagesManager;
  16. private CancellationTokenSource _cancellationTokenSource;
  17. public MqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
  18. {
  19. if (adapters == null) throw new ArgumentNullException(nameof(adapters));
  20. _logger = logger ?? throw new ArgumentNullException(nameof(logger));
  21. _adapters = adapters.ToList();
  22. }
  23. public event EventHandler<MqttServerStartedEventArgs> Started;
  24. public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
  25. public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
  26. public event EventHandler<MqttClientSubscribedTopicEventArgs> ClientSubscribedTopic;
  27. public event EventHandler<MqttClientUnsubscribedTopicEventArgs> ClientUnsubscribedTopic;
  28. public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
  29. public IMqttServerOptions Options { get; private set; }
  30. public Task<IList<ConnectedMqttClient>> GetConnectedClientsAsync()
  31. {
  32. return _clientSessionsManager.GetConnectedClientsAsync();
  33. }
  34. public Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters)
  35. {
  36. if (clientId == null) throw new ArgumentNullException(nameof(clientId));
  37. if (topicFilters == null) throw new ArgumentNullException(nameof(topicFilters));
  38. return _clientSessionsManager.SubscribeAsync(clientId, topicFilters);
  39. }
  40. public Task UnsubscribeAsync(string clientId, IList<string> topicFilters)
  41. {
  42. if (clientId == null) throw new ArgumentNullException(nameof(clientId));
  43. if (topicFilters == null) throw new ArgumentNullException(nameof(topicFilters));
  44. return _clientSessionsManager.UnsubscribeAsync(clientId, topicFilters);
  45. }
  46. public async Task PublishAsync(IEnumerable<MqttApplicationMessage> applicationMessages)
  47. {
  48. if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
  49. if (_cancellationTokenSource == null) throw new InvalidOperationException("The server is not started.");
  50. foreach (var applicationMessage in applicationMessages)
  51. {
  52. await _clientSessionsManager.DispatchApplicationMessageAsync(null, applicationMessage);
  53. }
  54. }
  55. public async Task StartAsync(IMqttServerOptions options)
  56. {
  57. Options = options ?? throw new ArgumentNullException(nameof(options));
  58. if (_cancellationTokenSource != null) throw new InvalidOperationException("The server is already started.");
  59. _cancellationTokenSource = new CancellationTokenSource();
  60. _retainedMessagesManager = new MqttRetainedMessagesManager(Options, _logger);
  61. await _retainedMessagesManager.LoadMessagesAsync();
  62. _clientSessionsManager = new MqttClientSessionsManager(Options, _retainedMessagesManager, _logger)
  63. {
  64. ClientConnectedCallback = OnClientConnected,
  65. ClientDisconnectedCallback = OnClientDisconnected,
  66. ClientSubscribedTopicCallback = OnClientSubscribedTopic,
  67. ClientUnsubscribedTopicCallback = OnClientUnsubscribedTopic,
  68. ApplicationMessageReceivedCallback = OnApplicationMessageReceived
  69. };
  70. foreach (var adapter in _adapters)
  71. {
  72. adapter.ClientAccepted += OnClientAccepted;
  73. await adapter.StartAsync(Options);
  74. }
  75. _logger.Info<MqttServer>("Started.");
  76. Started?.Invoke(this, new MqttServerStartedEventArgs());
  77. }
  78. public async Task StopAsync()
  79. {
  80. try
  81. {
  82. if (_cancellationTokenSource == null)
  83. {
  84. return;
  85. }
  86. _cancellationTokenSource.Cancel(false);
  87. _cancellationTokenSource.Dispose();
  88. foreach (var adapter in _adapters)
  89. {
  90. adapter.ClientAccepted -= OnClientAccepted;
  91. await adapter.StopAsync();
  92. }
  93. await _clientSessionsManager.StopAsync();
  94. _logger.Info<MqttServer>("Stopped.");
  95. }
  96. finally
  97. {
  98. _clientSessionsManager?.Dispose();
  99. _retainedMessagesManager?.Dispose();
  100. _cancellationTokenSource = null;
  101. _retainedMessagesManager = null;
  102. _clientSessionsManager = null;
  103. }
  104. }
  105. private void OnClientConnected(ConnectedMqttClient client)
  106. {
  107. _logger.Info<MqttServer>("Client '{0}': Connected.", client.ClientId);
  108. ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(client));
  109. }
  110. private void OnClientDisconnected(ConnectedMqttClient client, bool wasCleanDisconnect)
  111. {
  112. _logger.Info<MqttServer>("Client '{0}': Disconnected (clean={1}).", client.ClientId, wasCleanDisconnect);
  113. ClientDisconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(client, wasCleanDisconnect));
  114. }
  115. private void OnClientSubscribedTopic(string clientId, TopicFilter topicFilter)
  116. {
  117. ClientSubscribedTopic?.Invoke(this, new MqttClientSubscribedTopicEventArgs(clientId, topicFilter));
  118. }
  119. private void OnClientUnsubscribedTopic(string clientId, string topicFilter)
  120. {
  121. ClientUnsubscribedTopic?.Invoke(this, new MqttClientUnsubscribedTopicEventArgs(clientId, topicFilter));
  122. }
  123. private void OnApplicationMessageReceived(string clientId, MqttApplicationMessage applicationMessage)
  124. {
  125. ApplicationMessageReceived?.Invoke(this, new MqttApplicationMessageReceivedEventArgs(clientId, applicationMessage));
  126. }
  127. private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs)
  128. {
  129. eventArgs.SessionTask = Task.Run(
  130. () => _clientSessionsManager.RunSessionAsync(eventArgs.Client, _cancellationTokenSource.Token),
  131. _cancellationTokenSource.Token);
  132. }
  133. }
  134. }