You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

64 lines
2.2 KiB

  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Security.Cryptography.X509Certificates;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using MQTTnet.Core.Adapter;
  8. using MQTTnet.Core.Serializer;
  9. using MQTTnet.Core.Server;
  10. namespace MQTTnet
  11. {
  12. public class MqttSslServerAdapter : IMqttServerAdapter, IDisposable
  13. {
  14. private CancellationTokenSource _cancellationTokenSource;
  15. private Socket _socket;
  16. private X509Certificate2 _x590Certificate2;
  17. public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
  18. public void Start(MqttServerOptions options)
  19. {
  20. if (_socket != null) throw new InvalidOperationException("Server is already started.");
  21. _cancellationTokenSource = new CancellationTokenSource();
  22. _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
  23. _socket.Bind(new IPEndPoint(IPAddress.Any, options.Port));
  24. _socket.Listen(options.ConnectionBacklog);
  25. Task.Run(async () => await AcceptConnectionsAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token);
  26. _x590Certificate2 = new X509Certificate2(options.CertificatePath);
  27. }
  28. public void Stop()
  29. {
  30. _cancellationTokenSource?.Dispose();
  31. _cancellationTokenSource = null;
  32. _socket?.Dispose();
  33. _socket = null;
  34. }
  35. public void Dispose()
  36. {
  37. Stop();
  38. }
  39. private async Task AcceptConnectionsAsync(CancellationToken cancellationToken)
  40. {
  41. while (!cancellationToken.IsCancellationRequested)
  42. {
  43. var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null);
  44. MqttServerSslChannel mssc = new MqttServerSslChannel(clientSocket, _x590Certificate2);
  45. await mssc.Authenticate();
  46. var clientAdapter = new MqttChannelCommunicationAdapter(mssc, new DefaultMqttV311PacketSerializer());
  47. ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter));
  48. }
  49. }
  50. }
  51. }