選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

MqttTcpChannel.cs 3.8 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. using System;
  2. using System.Linq;
  3. using System.Net.Sockets;
  4. using System.Runtime.InteropServices.WindowsRuntime;
  5. using System.Threading.Tasks;
  6. using Windows.Networking;
  7. using Windows.Networking.Sockets;
  8. using Windows.Security.Cryptography.Certificates;
  9. using Windows.Storage.Streams;
  10. using MQTTnet.Core.Channel;
  11. using MQTTnet.Core.Client;
  12. using MQTTnet.Core.Exceptions;
  13. namespace MQTTnet.Implementations
  14. {
  15. public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable
  16. {
  17. private readonly StreamSocket _socket;
  18. public MqttTcpChannel()
  19. {
  20. _socket = new StreamSocket();
  21. }
  22. public MqttTcpChannel(StreamSocket socket)
  23. {
  24. _socket = socket ?? throw new ArgumentNullException(nameof(socket));
  25. }
  26. public async Task ConnectAsync(MqttClientOptions options)
  27. {
  28. if (options == null) throw new ArgumentNullException(nameof(options));
  29. try
  30. {
  31. if (!options.TlsOptions.UseTls)
  32. {
  33. await _socket.ConnectAsync(new HostName(options.Server), options.GetPort().ToString());
  34. }
  35. else
  36. {
  37. _socket.Control.ClientCertificate = LoadCertificate(options);
  38. if (!options.TlsOptions.CheckCertificateRevocation)
  39. {
  40. _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain);
  41. _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationInformationMissing);
  42. }
  43. await _socket.ConnectAsync(new HostName(options.Server), options.GetPort().ToString(), SocketProtectionLevel.Tls12);
  44. }
  45. }
  46. catch (SocketException exception)
  47. {
  48. throw new MqttCommunicationException(exception);
  49. }
  50. }
  51. public Task DisconnectAsync()
  52. {
  53. try
  54. {
  55. _socket.Dispose();
  56. return Task.FromResult(0);
  57. }
  58. catch (SocketException exception)
  59. {
  60. throw new MqttCommunicationException(exception);
  61. }
  62. }
  63. public async Task WriteAsync(byte[] buffer)
  64. {
  65. if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  66. try
  67. {
  68. await _socket.OutputStream.WriteAsync(buffer.AsBuffer());
  69. await _socket.OutputStream.FlushAsync();
  70. }
  71. catch (SocketException exception)
  72. {
  73. throw new MqttCommunicationException(exception);
  74. }
  75. }
  76. public async Task ReadAsync(byte[] buffer)
  77. {
  78. if (buffer == null) throw new ArgumentNullException(nameof(buffer));
  79. try
  80. {
  81. await _socket.InputStream.ReadAsync(buffer.AsBuffer(), (uint)buffer.Length, InputStreamOptions.None);
  82. }
  83. catch (SocketException exception)
  84. {
  85. throw new MqttCommunicationException(exception);
  86. }
  87. }
  88. public void Dispose()
  89. {
  90. _socket?.Dispose();
  91. }
  92. private static Certificate LoadCertificate(MqttClientOptions options)
  93. {
  94. if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any())
  95. {
  96. return null;
  97. }
  98. if (options.TlsOptions.Certificates.Count > 1)
  99. {
  100. throw new NotSupportedException("Only one client certificate is supported for UWP.");
  101. }
  102. return new Certificate(options.TlsOptions.Certificates.First().AsBuffer());
  103. }
  104. }
  105. }