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.
 
 
 
 

97 lines
3.1 KiB

  1. using System;
  2. using System.IO;
  3. using System.Net.WebSockets;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using MQTTnet.Core.Adapter;
  7. using MQTTnet.Core.Channel;
  8. using MQTTnet.Core.Serializer;
  9. using MQTTnet.Core.Server;
  10. using MQTTnet.Implementations;
  11. using Microsoft.Extensions.Logging;
  12. namespace MQTTnet.TestApp.AspNetCore2
  13. {
  14. public class MqttWebSocketServerAdapter : IMqttServerAdapter, IDisposable
  15. {
  16. private readonly ILogger<MqttWebSocketServerAdapter> _logger;
  17. private readonly IMqttCommunicationAdapterFactory _mqttCommunicationAdapterFactory;
  18. public MqttWebSocketServerAdapter(ILogger<MqttWebSocketServerAdapter> logger, IMqttCommunicationAdapterFactory mqttCommunicationAdapterFactory)
  19. {
  20. _logger = logger ?? throw new ArgumentNullException(nameof(logger));
  21. _mqttCommunicationAdapterFactory = mqttCommunicationAdapterFactory ?? throw new ArgumentNullException(nameof(mqttCommunicationAdapterFactory));
  22. }
  23. public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted;
  24. public Task StartAsync(MqttServerOptions options)
  25. {
  26. return Task.CompletedTask;
  27. }
  28. public Task StopAsync()
  29. {
  30. return Task.FromResult(0);
  31. }
  32. public Task AcceptWebSocketAsync(WebSocket webSocket)
  33. {
  34. if (webSocket == null) throw new ArgumentNullException(nameof(webSocket));
  35. var channel = new MqttWebSocketServerChannel(webSocket);
  36. var clientAdapter = _mqttCommunicationAdapterFactory.CreateServerMqttCommunicationAdapter(channel);
  37. var eventArgs = new MqttServerAdapterClientAcceptedEventArgs(clientAdapter);
  38. ClientAccepted?.Invoke(this, eventArgs);
  39. return eventArgs.SessionTask;
  40. }
  41. public void Dispose()
  42. {
  43. StopAsync();
  44. }
  45. private class MqttWebSocketServerChannel : IMqttCommunicationChannel, IDisposable
  46. {
  47. private readonly WebSocket _webSocket;
  48. public MqttWebSocketServerChannel(WebSocket webSocket)
  49. {
  50. _webSocket = webSocket ?? throw new ArgumentNullException(nameof(webSocket));
  51. RawReceiveStream = new WebSocketStream(_webSocket);
  52. }
  53. public Stream SendStream => RawReceiveStream;
  54. public Stream ReceiveStream => RawReceiveStream;
  55. public Stream RawReceiveStream { get; }
  56. public Task ConnectAsync()
  57. {
  58. return Task.CompletedTask;
  59. }
  60. public Task DisconnectAsync()
  61. {
  62. RawReceiveStream?.Dispose();
  63. if (_webSocket == null)
  64. {
  65. return Task.CompletedTask;
  66. }
  67. return _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
  68. }
  69. public void Dispose()
  70. {
  71. RawReceiveStream?.Dispose();
  72. SendStream?.Dispose();
  73. ReceiveStream?.Dispose();
  74. _webSocket?.Dispose();
  75. }
  76. }
  77. }
  78. }