Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 

299 рядки
10 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Threading.Tasks;
  6. using Microsoft.VisualStudio.TestTools.UnitTesting;
  7. using MQTTnet.Client;
  8. using MQTTnet.Client.Options;
  9. using MQTTnet.Client.Receiving;
  10. using MQTTnet.Exceptions;
  11. using MQTTnet.Protocol;
  12. using MQTTnet.Server;
  13. using MQTTnet.Tests.Mockups;
  14. namespace MQTTnet.Tests
  15. {
  16. [TestClass]
  17. public class Client_Tests
  18. {
  19. [TestMethod]
  20. public async Task Invalid_Connect_Throws_Exception()
  21. {
  22. var factory = new MqttFactory();
  23. using (var client = factory.CreateMqttClient())
  24. {
  25. try
  26. {
  27. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("wrong-server").Build());
  28. Assert.Fail("Must fail!");
  29. }
  30. catch (Exception exception)
  31. {
  32. Assert.IsNotNull(exception);
  33. Assert.IsInstanceOfType(exception, typeof(MqttCommunicationException));
  34. Assert.IsInstanceOfType(exception.InnerException, typeof(SocketException));
  35. }
  36. }
  37. }
  38. [TestMethod]
  39. public async Task Disconnect_Event_Contains_Exception()
  40. {
  41. var factory = new MqttFactory();
  42. using (var client = factory.CreateMqttClient())
  43. {
  44. Exception ex = null;
  45. client.Disconnected += (s, e) =>
  46. {
  47. ex = e.Exception;
  48. };
  49. try
  50. {
  51. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("wrong-server").Build());
  52. }
  53. catch
  54. {
  55. }
  56. Assert.IsNotNull(ex);
  57. Assert.IsInstanceOfType(ex, typeof(MqttCommunicationException));
  58. Assert.IsInstanceOfType(ex.InnerException, typeof(SocketException));
  59. }
  60. }
  61. [TestMethod]
  62. public async Task Preserve_Message_Order()
  63. {
  64. // The messages are sent in reverse or to ensure that the delay in the handler
  65. // needs longer for the first messages and later messages may be processed earlier (if there
  66. // is an issue).
  67. const int MessagesCount = 50;
  68. using (var testEnvironment = new TestEnvironment())
  69. {
  70. await testEnvironment.StartServerAsync();
  71. var client1 = await testEnvironment.ConnectClientAsync();
  72. await client1.SubscribeAsync("x");
  73. var receivedValues = new List<int>();
  74. async Task Handler1(MqttApplicationMessageHandlerContext context)
  75. {
  76. var value = int.Parse(context.ApplicationMessage.ConvertPayloadToString());
  77. await Task.Delay(value);
  78. lock (receivedValues)
  79. {
  80. receivedValues.Add(value);
  81. }
  82. }
  83. client1.UseReceivedApplicationMessageHandler(Handler1);
  84. var client2 = await testEnvironment.ConnectClientAsync();
  85. for (var i = MessagesCount; i > 0; i--)
  86. {
  87. await client2.PublishAsync("x", i.ToString());
  88. }
  89. await Task.Delay(5000);
  90. for (var i = MessagesCount; i > 0; i--)
  91. {
  92. Assert.AreEqual(i, receivedValues[MessagesCount - i]);
  93. }
  94. }
  95. }
  96. [TestMethod]
  97. public async Task Send_Reply_For_Any_Received_Message()
  98. {
  99. using (var testEnvironment = new TestEnvironment())
  100. {
  101. await testEnvironment.StartServerAsync();
  102. var client1 = await testEnvironment.ConnectClientAsync();
  103. await client1.SubscribeAsync("request/+");
  104. async Task Handler1(MqttApplicationMessageHandlerContext context)
  105. {
  106. await client1.PublishAsync($"reply/{context.ApplicationMessage.Topic}");
  107. }
  108. client1.UseReceivedApplicationMessageHandler(Handler1);
  109. var client2 = await testEnvironment.ConnectClientAsync();
  110. await client2.SubscribeAsync("reply/#");
  111. var replies = new List<string>();
  112. void Handler2(MqttApplicationMessageHandlerContext context)
  113. {
  114. lock (replies)
  115. {
  116. replies.Add(context.ApplicationMessage.Topic);
  117. }
  118. }
  119. client2.UseReceivedApplicationMessageHandler((Action<MqttApplicationMessageHandlerContext>)Handler2);
  120. await Task.Delay(500);
  121. await client2.PublishAsync("request/a");
  122. await client2.PublishAsync("request/b");
  123. await client2.PublishAsync("request/c");
  124. await Task.Delay(500);
  125. Assert.AreEqual("reply/request/a,reply/request/b,reply/request/c", string.Join(",", replies));
  126. }
  127. }
  128. [TestMethod]
  129. public async Task Publish_With_Correct_Retain_Flag()
  130. {
  131. using (var testEnvironment = new TestEnvironment())
  132. {
  133. await testEnvironment.StartServerAsync();
  134. var receivedMessages = new List<MqttApplicationMessage>();
  135. var client1 = await testEnvironment.ConnectClientAsync();
  136. client1.UseReceivedApplicationMessageHandler(c =>
  137. {
  138. lock (receivedMessages)
  139. {
  140. receivedMessages.Add(c.ApplicationMessage);
  141. }
  142. });
  143. await client1.SubscribeAsync("a");
  144. var client2 = await testEnvironment.ConnectClientAsync();
  145. var message = new MqttApplicationMessageBuilder().WithTopic("a").WithRetainFlag().Build();
  146. await client2.PublishAsync(message);
  147. await Task.Delay(500);
  148. Assert.AreEqual(1, receivedMessages.Count);
  149. Assert.IsFalse(receivedMessages.First().Retain); // Must be false even if set above!
  150. }
  151. }
  152. [TestMethod]
  153. public async Task Subscribe_In_Callback_Events()
  154. {
  155. using (var testEnvironment = new TestEnvironment())
  156. {
  157. await testEnvironment.StartServerAsync();
  158. var receivedMessages = new List<MqttApplicationMessage>();
  159. var client = testEnvironment.CreateClient();
  160. client.Connected += async (s, e) =>
  161. {
  162. await client.SubscribeAsync("RCU/P1/H0001/R0003");
  163. var msg = new MqttApplicationMessageBuilder()
  164. .WithPayload("DA|18RS00SC00XI0000RV00R100R200R300R400L100L200L300L400Y100Y200AC0102031800BELK0000BM0000|")
  165. .WithTopic("RCU/P1/H0001/R0003");
  166. await client.PublishAsync(msg.Build());
  167. };
  168. client.UseReceivedApplicationMessageHandler(c =>
  169. {
  170. lock (receivedMessages)
  171. {
  172. receivedMessages.Add(c.ApplicationMessage);
  173. }
  174. });
  175. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort).Build());
  176. await Task.Delay(500);
  177. Assert.AreEqual(1, receivedMessages.Count);
  178. Assert.AreEqual("DA|18RS00SC00XI0000RV00R100R200R300R400L100L200L300L400Y100Y200AC0102031800BELK0000BM0000|", receivedMessages.First().ConvertPayloadToString());
  179. }
  180. }
  181. [TestMethod]
  182. public async Task Message_Send_Retry()
  183. {
  184. using (var testEnvironment = new TestEnvironment())
  185. {
  186. testEnvironment.IgnoreClientLogErrors = true;
  187. testEnvironment.IgnoreServerLogErrors = true;
  188. await testEnvironment.StartServerAsync(
  189. new MqttServerOptionsBuilder()
  190. .WithPersistentSessions()
  191. .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(250)));
  192. var client1 = await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithCleanSession(false));
  193. await client1.SubscribeAsync("x", MqttQualityOfServiceLevel.AtLeastOnce);
  194. var retries = 0;
  195. async Task Handler1(MqttApplicationMessageHandlerContext context)
  196. {
  197. retries++;
  198. await Task.Delay(1000);
  199. throw new Exception("Broken!");
  200. }
  201. client1.UseReceivedApplicationMessageHandler(Handler1);
  202. var client2 = await testEnvironment.ConnectClientAsync();
  203. await client2.PublishAsync("x");
  204. await Task.Delay(3000);
  205. // The server should disconnect clients which are not responding.
  206. Assert.IsFalse(client1.IsConnected);
  207. await client1.ReconnectAsync().ConfigureAwait(false);
  208. await Task.Delay(1000);
  209. Assert.AreEqual(2, retries);
  210. }
  211. }
  212. [TestMethod]
  213. public async Task NoConnectedHandler_Connect_DoesNotThrowException()
  214. {
  215. using (var testEnvironment = new TestEnvironment())
  216. {
  217. await testEnvironment.StartServerAsync();
  218. var client = await testEnvironment.ConnectClientAsync();
  219. Assert.IsTrue(client.IsConnected);
  220. }
  221. }
  222. [TestMethod]
  223. public async Task NoDisconnectedHandler_Disconnect_DoesNotThrowException()
  224. {
  225. using (var testEnvironment = new TestEnvironment())
  226. {
  227. await testEnvironment.StartServerAsync();
  228. var client = await testEnvironment.ConnectClientAsync();
  229. Assert.IsTrue(client.IsConnected);
  230. await client.DisconnectAsync();
  231. Assert.IsFalse(client.IsConnected);
  232. }
  233. }
  234. }
  235. }