Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

121 wiersze
3.8 KiB

  1. using System;
  2. using System.IO;
  3. using System.Net.Security;
  4. using System.Net.Sockets;
  5. using System.Security.Authentication;
  6. using System.Threading.Tasks;
  7. using MQTTnet.Core.Channel;
  8. using MQTTnet.Core.Client;
  9. using MQTTnet.Core.Exceptions;
  10. namespace MQTTnet
  11. {
  12. /// <summary>
  13. /// Describes an SSL channel to an MQTT server.
  14. /// </summary>
  15. public class MqttClientSslChannel : IMqttCommunicationChannel, IDisposable
  16. {
  17. private readonly Socket _socket;
  18. private SslStream _sslStream;
  19. /// <summary>
  20. /// Creates a new <see cref="MqttClientSslChannel"/>.
  21. /// </summary>
  22. public MqttClientSslChannel()
  23. {
  24. _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
  25. }
  26. /// <summary>
  27. /// Creates a new <see cref="MqttClientSslChannel"/> with a predefined <paramref name="socket"/>.
  28. /// </summary>
  29. /// <param name="socket"></param>
  30. public MqttClientSslChannel(Socket socket)
  31. {
  32. _socket = socket ?? throw new ArgumentNullException(nameof(socket));
  33. }
  34. /// <summary>
  35. /// Asynchronously connects to the host described in the <see cref="MqttClientOptions"/>.
  36. /// </summary>
  37. /// <param name="options">The <see cref="MqttClientOptions"/> describing the connection.</param>
  38. public async Task ConnectAsync(MqttClientOptions options)
  39. {
  40. try
  41. {
  42. await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.Port,
  43. null);
  44. NetworkStream ns = new NetworkStream(_socket, true);
  45. _sslStream = new SslStream(ns);
  46. await _sslStream.AuthenticateAsClientAsync(options.Server, null, SslProtocols.Tls12, false);
  47. }
  48. catch (SocketException exception)
  49. {
  50. throw new MqttCommunicationException(exception);
  51. }
  52. }
  53. /// <summary>
  54. /// Asynchronously disconnects the client from the server.
  55. /// </summary>
  56. public Task DisconnectAsync()
  57. {
  58. try
  59. {
  60. return Task.Factory.FromAsync(_socket.BeginDisconnect, _socket.EndDisconnect, true, null);
  61. }
  62. catch (SocketException exception)
  63. {
  64. throw new MqttCommunicationException(exception);
  65. }
  66. }
  67. /// <summary>
  68. /// Asynchronously writes a sequence of bytes to the socket.
  69. /// </summary>
  70. /// <param name="buffer">The buffer to write data from.</param>
  71. public Task WriteAsync(byte[] buffer)
  72. {
  73. if (buffer == null)
  74. throw new ArgumentNullException(nameof(buffer));
  75. try
  76. {
  77. return _sslStream.WriteAsync(buffer, 0, buffer.Length);
  78. }
  79. catch (Exception ex)
  80. when (ex is SocketException || ex is IOException)
  81. {
  82. throw new MqttCommunicationException(ex);
  83. }
  84. }
  85. /// <summary>
  86. /// Asynchronously reads a sequence of bytes from the socket.
  87. /// </summary>
  88. /// <param name="buffer">The buffer to write the data into.</param>
  89. public Task ReadAsync(byte[] buffer)
  90. {
  91. try
  92. {
  93. return _sslStream.ReadAsync(buffer, 0, buffer.Length);
  94. }
  95. catch (Exception ex)
  96. when (ex is SocketException || ex is IOException)
  97. {
  98. throw new MqttCommunicationException(ex);
  99. }
  100. }
  101. /// <summary>
  102. /// Releases all resources used by the <see cref="MqttClientSslChannel"/>.
  103. /// </summary>
  104. public void Dispose()
  105. {
  106. _sslStream?.Dispose();
  107. _socket?.Dispose();
  108. }
  109. }
  110. }