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.
 
 
 
 

100 linhas
3.9 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 MQTTnet.Core.Diagnostics;
  7. using MQTTnet.Core.Internal;
  8. namespace MQTTnet.Core.Server
  9. {
  10. public sealed class MqttServer : IMqttServer
  11. {
  12. private readonly MqttNetTrace _trace;
  13. private readonly MqttClientSessionsManager _clientSessionsManager;
  14. private readonly ICollection<IMqttServerAdapter> _adapters;
  15. private readonly MqttServerOptions _options;
  16. private CancellationTokenSource _cancellationTokenSource;
  17. public MqttServer(MqttServerOptions options, ICollection<IMqttServerAdapter> adapters, MqttNetTrace trace)
  18. {
  19. _trace = trace ?? throw new ArgumentNullException(nameof(trace));
  20. _options = options ?? throw new ArgumentNullException(nameof(options));
  21. _adapters = adapters ?? throw new ArgumentNullException(nameof(adapters));
  22. _clientSessionsManager = new MqttClientSessionsManager(options, trace);
  23. _clientSessionsManager.ApplicationMessageReceived += (s, e) => ApplicationMessageReceived?.Invoke(s, e);
  24. _clientSessionsManager.ClientConnected += OnClientConnected;
  25. _clientSessionsManager.ClientDisconnected += OnClientDisconnected;
  26. }
  27. public IList<ConnectedMqttClient> GetConnectedClients()
  28. {
  29. return _clientSessionsManager.GetConnectedClients();
  30. }
  31. public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
  32. public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
  33. public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
  34. public void Publish(MqttApplicationMessage applicationMessage)
  35. {
  36. if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
  37. _clientSessionsManager.DispatchPublishPacket(null, applicationMessage.ToPublishPacket());
  38. }
  39. public async Task StartAsync()
  40. {
  41. if (_cancellationTokenSource != null) throw new InvalidOperationException("The MQTT server is already started.");
  42. _cancellationTokenSource = new CancellationTokenSource();
  43. await _clientSessionsManager.RetainedMessagesManager.LoadMessagesAsync();
  44. foreach (var adapter in _adapters)
  45. {
  46. adapter.ClientAccepted += OnClientAccepted;
  47. await adapter.StartAsync(_options);
  48. }
  49. _trace.Information(nameof(MqttServer), "Started.");
  50. }
  51. public async Task StopAsync()
  52. {
  53. _cancellationTokenSource?.Cancel(false);
  54. _cancellationTokenSource?.Dispose();
  55. _cancellationTokenSource = null;
  56. foreach (var adapter in _adapters)
  57. {
  58. adapter.ClientAccepted -= OnClientAccepted;
  59. await adapter.StopAsync();
  60. }
  61. _clientSessionsManager.Clear();
  62. _trace.Information(nameof(MqttServer), "Stopped.");
  63. }
  64. private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs)
  65. {
  66. eventArgs.SessionTask = Task.Run(async () => await _clientSessionsManager.RunClientSessionAsync(eventArgs.Client), _cancellationTokenSource.Token);
  67. }
  68. private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs)
  69. {
  70. _trace.Information(nameof(MqttServer), "Client '{0}': Connected.", eventArgs.Client.ClientId);
  71. ClientConnected?.Invoke(this, eventArgs);
  72. }
  73. private void OnClientDisconnected(object sender, MqttClientDisconnectedEventArgs eventArgs)
  74. {
  75. _trace.Information(nameof(MqttServer), "Client '{0}': Disconnected.", eventArgs.Client.ClientId);
  76. ClientDisconnected?.Invoke(this, eventArgs);
  77. }
  78. }
  79. }