Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

137 linhas
5.3 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using MQTTnet.Core.Adapter;
  6. using Microsoft.Extensions.Logging;
  7. using Microsoft.Extensions.Options;
  8. using System.Linq;
  9. using Microsoft.Extensions.DependencyInjection;
  10. namespace MQTTnet.Core.Server
  11. {
  12. public class MqttServer : IMqttServer
  13. {
  14. private readonly IMqttClientRetainedMessageManager _clientRetainedMessageManager;
  15. private readonly ILogger<MqttServer> _logger;
  16. private readonly MqttClientSessionsManager _clientSessionsManager;
  17. private readonly ICollection<IMqttServerAdapter> _adapters;
  18. private readonly MqttServerOptions _options;
  19. private CancellationTokenSource _cancellationTokenSource;
  20. public MqttServer(
  21. IOptions<MqttServerOptions> options,
  22. IEnumerable<IMqttServerAdapter> adapters,
  23. ILogger<MqttServer> logger,
  24. MqttClientSessionsManager clientSessionsManager,
  25. IMqttClientRetainedMessageManager clientRetainedMessageManager
  26. )
  27. {
  28. _options = options.Value ?? throw new ArgumentNullException(nameof(options));
  29. _logger = logger ?? throw new ArgumentNullException(nameof(logger));
  30. _clientSessionsManager = clientSessionsManager ?? throw new ArgumentNullException(nameof(clientSessionsManager));
  31. _clientRetainedMessageManager = clientRetainedMessageManager ?? throw new ArgumentNullException(nameof(clientRetainedMessageManager));
  32. if (adapters == null)
  33. {
  34. throw new ArgumentNullException(nameof(adapters));
  35. }
  36. _adapters = adapters.ToList();
  37. _clientSessionsManager.ApplicationMessageReceived += (s, e) => ApplicationMessageReceived?.Invoke(s, e);
  38. _clientSessionsManager.ClientConnected += OnClientConnected;
  39. _clientSessionsManager.ClientDisconnected += OnClientDisconnected;
  40. }
  41. public IList<ConnectedMqttClient> GetConnectedClients()
  42. {
  43. return _clientSessionsManager.GetConnectedClients();
  44. }
  45. public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
  46. public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
  47. public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
  48. public void Publish(IEnumerable<MqttApplicationMessage> applicationMessages)
  49. {
  50. if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
  51. if (_cancellationTokenSource == null)
  52. {
  53. throw new InvalidOperationException("The server is not started.");
  54. }
  55. foreach (var applicationMessage in applicationMessages)
  56. {
  57. var interceptorContext = new MqttApplicationMessageInterceptorContext
  58. {
  59. ApplicationMessage = applicationMessage
  60. };
  61. _options.ApplicationMessageInterceptor?.Invoke(interceptorContext);
  62. _clientSessionsManager.DispatchApplicationMessage(null, interceptorContext.ApplicationMessage);
  63. }
  64. }
  65. public Task PublishAsync(IEnumerable<MqttApplicationMessage> applicationMessages)
  66. {
  67. Publish(applicationMessages);
  68. return Task.FromResult(0);
  69. }
  70. public async Task StartAsync()
  71. {
  72. if (_cancellationTokenSource != null) throw new InvalidOperationException("The MQTT server is already started.");
  73. _cancellationTokenSource = new CancellationTokenSource();
  74. await _clientRetainedMessageManager.LoadMessagesAsync();
  75. foreach (var adapter in _adapters)
  76. {
  77. adapter.ClientAccepted += OnClientAccepted;
  78. await adapter.StartAsync(_options);
  79. }
  80. _logger.LogInformation("Started.");
  81. }
  82. public async Task StopAsync()
  83. {
  84. _cancellationTokenSource?.Cancel(false);
  85. _cancellationTokenSource?.Dispose();
  86. _cancellationTokenSource = null;
  87. foreach (var adapter in _adapters)
  88. {
  89. adapter.ClientAccepted -= OnClientAccepted;
  90. await adapter.StopAsync();
  91. }
  92. _clientSessionsManager.Clear();
  93. _logger.LogInformation("Stopped.");
  94. }
  95. private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs)
  96. {
  97. eventArgs.SessionTask = Task.Run(async () => await _clientSessionsManager.RunClientSessionAsync(eventArgs.Client, _cancellationTokenSource.Token), _cancellationTokenSource.Token);
  98. }
  99. private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs)
  100. {
  101. _logger.LogInformation("Client '{0}': Connected.", eventArgs.Client.ClientId);
  102. ClientConnected?.Invoke(this, eventArgs);
  103. }
  104. private void OnClientDisconnected(object sender, MqttClientDisconnectedEventArgs eventArgs)
  105. {
  106. _logger.LogInformation("Client '{0}': Disconnected.", eventArgs.Client.ClientId);
  107. ClientDisconnected?.Invoke(this, eventArgs);
  108. }
  109. }
  110. }