25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

56 lines
1.9 KiB

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