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.

MqttClient_Tests.cs 29 KiB

5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using MQTTnet.Client;
  3. using MQTTnet.Client.Connecting;
  4. using MQTTnet.Client.Disconnecting;
  5. using MQTTnet.Client.Options;
  6. using MQTTnet.Client.Subscribing;
  7. using MQTTnet.Exceptions;
  8. using MQTTnet.Protocol;
  9. using MQTTnet.Server;
  10. using MQTTnet.Tests.Mockups;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Linq;
  14. using System.Net.Sockets;
  15. using System.Text;
  16. using System.Threading;
  17. using System.Threading.Tasks;
  18. using MQTTnet.Client.Receiving;
  19. using MQTTnet.Diagnostics;
  20. using MQTTnet.Extensions.ManagedClient;
  21. using MQTTnet.Formatter;
  22. namespace MQTTnet.Tests
  23. {
  24. [TestClass]
  25. public class Client_Tests
  26. {
  27. public TestContext TestContext { get; set; }
  28. [TestMethod]
  29. public async Task Set_ClientWasConnected_On_ServerDisconnect()
  30. {
  31. using (var testEnvironment = new TestEnvironment(TestContext))
  32. {
  33. var server = await testEnvironment.StartServerAsync();
  34. var client = await testEnvironment.ConnectClientAsync();
  35. Assert.IsTrue(client.IsConnected);
  36. client.UseDisconnectedHandler(e => Assert.IsTrue(e.ClientWasConnected));
  37. await server.StopAsync();
  38. await Task.Delay(4000);
  39. }
  40. }
  41. [TestMethod]
  42. public async Task Set_ClientWasConnected_On_ClientDisconnect()
  43. {
  44. using (var testEnvironment = new TestEnvironment(TestContext))
  45. {
  46. var server = await testEnvironment.StartServerAsync();
  47. var client = await testEnvironment.ConnectClientAsync();
  48. Assert.IsTrue(client.IsConnected);
  49. client.UseDisconnectedHandler(e => Assert.IsTrue(e.ClientWasConnected));
  50. await client.DisconnectAsync();
  51. await Task.Delay(200);
  52. }
  53. }
  54. [TestMethod]
  55. [ExpectedException(typeof(MqttCommunicationTimedOutException))]
  56. public async Task Connect_To_Invalid_Server_Wrong_IP()
  57. {
  58. var client = new MqttFactory().CreateMqttClient();
  59. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("1.2.3.4").WithCommunicationTimeout(TimeSpan.FromSeconds(2)).Build());
  60. }
  61. [TestMethod]
  62. [ExpectedException(typeof(MqttCommunicationException))]
  63. public async Task Connect_To_Invalid_Server_Port_Not_Opened()
  64. {
  65. var client = new MqttFactory().CreateMqttClient();
  66. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", 12345).WithCommunicationTimeout(TimeSpan.FromSeconds(5)).Build());
  67. }
  68. [TestMethod]
  69. [ExpectedException(typeof(MqttCommunicationException))]
  70. public async Task Connect_To_Invalid_Server_Wrong_Protocol()
  71. {
  72. var client = new MqttFactory().CreateMqttClient();
  73. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("http://127.0.0.1", 12345).WithCommunicationTimeout(TimeSpan.FromSeconds(2)).Build());
  74. }
  75. [TestMethod]
  76. public async Task Send_Manual_Ping()
  77. {
  78. using (var testEnvironment = new TestEnvironment(TestContext))
  79. {
  80. await testEnvironment.StartServerAsync();
  81. var client = await testEnvironment.ConnectClientAsync();
  82. await client.PingAsync(CancellationToken.None);
  83. }
  84. }
  85. [TestMethod]
  86. public async Task Send_Reply_In_Message_Handler_For_Same_Client()
  87. {
  88. using (var testEnvironment = new TestEnvironment(TestContext))
  89. {
  90. await testEnvironment.StartServerAsync();
  91. var client = await testEnvironment.ConnectClientAsync();
  92. await client.SubscribeAsync("#");
  93. var replyReceived = false;
  94. client.UseApplicationMessageReceivedHandler(c =>
  95. {
  96. if (c.ApplicationMessage.Topic == "request")
  97. {
  98. #pragma warning disable 4014
  99. Task.Run(() => client.PublishAsync("reply", null, MqttQualityOfServiceLevel.AtLeastOnce));
  100. #pragma warning restore 4014
  101. }
  102. else
  103. {
  104. replyReceived = true;
  105. }
  106. });
  107. await client.PublishAsync("request", null, MqttQualityOfServiceLevel.AtLeastOnce);
  108. SpinWait.SpinUntil(() => replyReceived, TimeSpan.FromSeconds(10));
  109. Assert.IsTrue(replyReceived);
  110. }
  111. }
  112. [TestMethod]
  113. public async Task Send_Reply_In_Message_Handler()
  114. {
  115. using (var testEnvironment = new TestEnvironment())
  116. {
  117. await testEnvironment.StartServerAsync();
  118. var client1 = await testEnvironment.ConnectClientAsync();
  119. var client2 = await testEnvironment.ConnectClientAsync();
  120. await client1.SubscribeAsync("#");
  121. await client2.SubscribeAsync("#");
  122. var replyReceived = false;
  123. client1.UseApplicationMessageReceivedHandler(c =>
  124. {
  125. if (c.ApplicationMessage.Topic == "reply")
  126. {
  127. replyReceived = true;
  128. }
  129. });
  130. client2.UseApplicationMessageReceivedHandler(async c =>
  131. {
  132. // Use AtMostOnce here because with QoS 1 or even QoS 2 the process waits for
  133. // the ACK etc. The problem is that the SpinUntil below only waits until the
  134. // flag is set. It does not wait until the client has sent the ACK
  135. await client2.PublishAsync("reply", null, MqttQualityOfServiceLevel.AtMostOnce);
  136. });
  137. await client1.PublishAsync("request", null, MqttQualityOfServiceLevel.AtLeastOnce);
  138. await Task.Delay(500);
  139. SpinWait.SpinUntil(() => replyReceived, TimeSpan.FromSeconds(10));
  140. await Task.Delay(500);
  141. Assert.IsTrue(replyReceived);
  142. }
  143. }
  144. [TestMethod]
  145. public async Task Reconnect()
  146. {
  147. using (var testEnvironment = new TestEnvironment(TestContext))
  148. {
  149. var server = await testEnvironment.StartServerAsync();
  150. var client = await testEnvironment.ConnectClientAsync();
  151. await Task.Delay(500);
  152. Assert.IsTrue(client.IsConnected);
  153. await server.StopAsync();
  154. await Task.Delay(500);
  155. Assert.IsFalse(client.IsConnected);
  156. await server.StartAsync(new MqttServerOptionsBuilder().WithDefaultEndpointPort(testEnvironment.ServerPort).Build());
  157. await Task.Delay(500);
  158. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
  159. Assert.IsTrue(client.IsConnected);
  160. }
  161. }
  162. [TestMethod]
  163. public async Task Reconnect_While_Server_Offline()
  164. {
  165. using (var testEnvironment = new TestEnvironment(TestContext))
  166. {
  167. testEnvironment.IgnoreClientLogErrors = true;
  168. var server = await testEnvironment.StartServerAsync();
  169. var client = await testEnvironment.ConnectClientAsync();
  170. await Task.Delay(500);
  171. Assert.IsTrue(client.IsConnected);
  172. await server.StopAsync();
  173. await Task.Delay(500);
  174. Assert.IsFalse(client.IsConnected);
  175. for (var i = 0; i < 5; i++)
  176. {
  177. try
  178. {
  179. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
  180. Assert.Fail("Must fail!");
  181. }
  182. catch
  183. {
  184. }
  185. }
  186. await server.StartAsync(new MqttServerOptionsBuilder().WithDefaultEndpointPort(testEnvironment.ServerPort).Build());
  187. await Task.Delay(500);
  188. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
  189. Assert.IsTrue(client.IsConnected);
  190. }
  191. }
  192. [TestMethod]
  193. public async Task Reconnect_From_Disconnected_Event()
  194. {
  195. using (var testEnvironment = new TestEnvironment(TestContext))
  196. {
  197. testEnvironment.IgnoreClientLogErrors = true;
  198. var client = testEnvironment.CreateClient();
  199. var tries = 0;
  200. var maxTries = 3;
  201. client.UseDisconnectedHandler(async e =>
  202. {
  203. if (tries >= maxTries)
  204. {
  205. return;
  206. }
  207. Interlocked.Increment(ref tries);
  208. await Task.Delay(100);
  209. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
  210. });
  211. try
  212. {
  213. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
  214. Assert.Fail("Must fail!");
  215. }
  216. catch
  217. {
  218. }
  219. SpinWait.SpinUntil(() => tries >= maxTries, 10000);
  220. Assert.AreEqual(maxTries, tries);
  221. }
  222. }
  223. [TestMethod]
  224. public async Task PacketIdentifier_In_Publish_Result()
  225. {
  226. using (var testEnvironment = new TestEnvironment(TestContext))
  227. {
  228. await testEnvironment.StartServerAsync();
  229. var client = await testEnvironment.ConnectClientAsync();
  230. var result = await client.PublishAsync("a", "a", MqttQualityOfServiceLevel.AtMostOnce);
  231. Assert.AreEqual(null, result.PacketIdentifier);
  232. result = await client.PublishAsync("b", "b", MqttQualityOfServiceLevel.AtMostOnce);
  233. Assert.AreEqual(null, result.PacketIdentifier);
  234. result = await client.PublishAsync("a", "a", MqttQualityOfServiceLevel.AtLeastOnce);
  235. Assert.AreEqual((ushort)1, result.PacketIdentifier);
  236. result = await client.PublishAsync("b", "b", MqttQualityOfServiceLevel.AtLeastOnce);
  237. Assert.AreEqual((ushort)2, result.PacketIdentifier);
  238. result = await client.PublishAsync("a", "a", MqttQualityOfServiceLevel.ExactlyOnce);
  239. Assert.AreEqual((ushort)3, result.PacketIdentifier);
  240. result = await client.PublishAsync("b", "b", MqttQualityOfServiceLevel.ExactlyOnce);
  241. Assert.AreEqual((ushort)4, result.PacketIdentifier);
  242. }
  243. }
  244. [TestMethod]
  245. public async Task Invalid_Connect_Throws_Exception()
  246. {
  247. var factory = new MqttFactory();
  248. using (var client = factory.CreateMqttClient())
  249. {
  250. try
  251. {
  252. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("wrong-server").Build());
  253. Assert.Fail("Must fail!");
  254. }
  255. catch (Exception exception)
  256. {
  257. Assert.IsNotNull(exception);
  258. Assert.IsInstanceOfType(exception, typeof(MqttCommunicationException));
  259. Assert.IsInstanceOfType(exception.InnerException, typeof(SocketException));
  260. }
  261. }
  262. }
  263. [TestMethod]
  264. public async Task ConnectTimeout_Throws_Exception()
  265. {
  266. var factory = new MqttFactory();
  267. using (var client = factory.CreateMqttClient())
  268. {
  269. bool disconnectHandlerCalled = false;
  270. try
  271. {
  272. client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(args =>
  273. {
  274. disconnectHandlerCalled = true;
  275. });
  276. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("1.2.3.4").Build());
  277. Assert.Fail("Must fail!");
  278. }
  279. catch (Exception exception)
  280. {
  281. Assert.IsNotNull(exception);
  282. Assert.IsInstanceOfType(exception, typeof(MqttCommunicationException));
  283. //Assert.IsInstanceOfType(exception.InnerException, typeof(SocketException));
  284. }
  285. await Task.Delay(100); // disconnected handler is called async
  286. Assert.IsTrue(disconnectHandlerCalled);
  287. }
  288. }
  289. [TestMethod]
  290. public async Task Fire_Disconnected_Event_On_Server_Shutdown()
  291. {
  292. using (var testEnvironment = new TestEnvironment(TestContext))
  293. {
  294. var server = await testEnvironment.StartServerAsync();
  295. var client = await testEnvironment.ConnectClientAsync();
  296. var handlerFired = false;
  297. client.UseDisconnectedHandler(e => handlerFired = true);
  298. await server.StopAsync();
  299. await Task.Delay(4000);
  300. Assert.IsTrue(handlerFired);
  301. }
  302. }
  303. [TestMethod]
  304. public async Task Disconnect_Event_Contains_Exception()
  305. {
  306. var factory = new MqttFactory();
  307. using (var client = factory.CreateMqttClient())
  308. {
  309. Exception ex = null;
  310. client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(e =>
  311. {
  312. ex = e.Exception;
  313. });
  314. try
  315. {
  316. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("wrong-server").Build());
  317. }
  318. catch
  319. {
  320. }
  321. await Task.Delay(500);
  322. Assert.IsNotNull(ex);
  323. Assert.IsInstanceOfType(ex, typeof(MqttCommunicationException));
  324. Assert.IsInstanceOfType(ex.InnerException, typeof(SocketException));
  325. }
  326. }
  327. [TestMethod]
  328. public async Task Preserve_Message_Order()
  329. {
  330. // The messages are sent in reverse or to ensure that the delay in the handler
  331. // needs longer for the first messages and later messages may be processed earlier (if there
  332. // is an issue).
  333. const int MessagesCount = 50;
  334. using (var testEnvironment = new TestEnvironment(TestContext))
  335. {
  336. await testEnvironment.StartServerAsync();
  337. var client1 = await testEnvironment.ConnectClientAsync();
  338. await client1.SubscribeAsync("x");
  339. var receivedValues = new List<int>();
  340. async Task Handler1(MqttApplicationMessageReceivedEventArgs eventArgs)
  341. {
  342. var value = int.Parse(eventArgs.ApplicationMessage.ConvertPayloadToString());
  343. await Task.Delay(value);
  344. lock (receivedValues)
  345. {
  346. receivedValues.Add(value);
  347. }
  348. }
  349. client1.UseApplicationMessageReceivedHandler(Handler1);
  350. var client2 = await testEnvironment.ConnectClientAsync();
  351. for (var i = MessagesCount; i > 0; i--)
  352. {
  353. await client2.PublishAsync("x", i.ToString());
  354. }
  355. await Task.Delay(5000);
  356. for (var i = MessagesCount; i > 0; i--)
  357. {
  358. Assert.AreEqual(i, receivedValues[MessagesCount - i]);
  359. }
  360. }
  361. }
  362. [TestMethod]
  363. public async Task Send_Reply_For_Any_Received_Message()
  364. {
  365. using (var testEnvironment = new TestEnvironment(TestContext))
  366. {
  367. await testEnvironment.StartServerAsync();
  368. var client1 = await testEnvironment.ConnectClientAsync();
  369. await client1.SubscribeAsync("request/+");
  370. async Task Handler1(MqttApplicationMessageReceivedEventArgs eventArgs)
  371. {
  372. await client1.PublishAsync($"reply/{eventArgs.ApplicationMessage.Topic}");
  373. }
  374. client1.UseApplicationMessageReceivedHandler(Handler1);
  375. var client2 = await testEnvironment.ConnectClientAsync();
  376. await client2.SubscribeAsync("reply/#");
  377. var replies = new List<string>();
  378. void Handler2(MqttApplicationMessageReceivedEventArgs eventArgs)
  379. {
  380. lock (replies)
  381. {
  382. replies.Add(eventArgs.ApplicationMessage.Topic);
  383. }
  384. }
  385. client2.UseApplicationMessageReceivedHandler((Action<MqttApplicationMessageReceivedEventArgs>)Handler2);
  386. await Task.Delay(500);
  387. await client2.PublishAsync("request/a");
  388. await client2.PublishAsync("request/b");
  389. await client2.PublishAsync("request/c");
  390. await Task.Delay(500);
  391. Assert.AreEqual("reply/request/a,reply/request/b,reply/request/c", string.Join(",", replies));
  392. }
  393. }
  394. [TestMethod]
  395. public async Task Publish_With_Correct_Retain_Flag()
  396. {
  397. using (var testEnvironment = new TestEnvironment(TestContext))
  398. {
  399. await testEnvironment.StartServerAsync();
  400. var receivedMessages = new List<MqttApplicationMessage>();
  401. var client1 = await testEnvironment.ConnectClientAsync();
  402. client1.UseApplicationMessageReceivedHandler(c =>
  403. {
  404. lock (receivedMessages)
  405. {
  406. receivedMessages.Add(c.ApplicationMessage);
  407. }
  408. });
  409. await client1.SubscribeAsync("a");
  410. var client2 = await testEnvironment.ConnectClientAsync();
  411. var message = new MqttApplicationMessageBuilder().WithTopic("a").WithRetainFlag().Build();
  412. await client2.PublishAsync(message);
  413. await Task.Delay(500);
  414. Assert.AreEqual(1, receivedMessages.Count);
  415. Assert.IsFalse(receivedMessages.First().Retain); // Must be false even if set above!
  416. }
  417. }
  418. [TestMethod]
  419. public async Task Publish_QoS_1_In_ApplicationMessageReceiveHandler()
  420. {
  421. using (var testEnvironment = new TestEnvironment(TestContext))
  422. {
  423. await testEnvironment.StartServerAsync();
  424. const string client1Topic = "client1/topic";
  425. const string client2Topic = "client2/topic";
  426. const string expectedClient2Message = "hello client2";
  427. var client1 = await testEnvironment.ConnectClientAsync();
  428. client1.UseApplicationMessageReceivedHandler(async c =>
  429. {
  430. await client1.PublishAsync(client2Topic, expectedClient2Message, MqttQualityOfServiceLevel.AtLeastOnce);
  431. });
  432. await client1.SubscribeAsync(client1Topic, MqttQualityOfServiceLevel.AtLeastOnce);
  433. var client2 = await testEnvironment.ConnectClientAsync();
  434. var client2TopicResults = new List<string>();
  435. client2.UseApplicationMessageReceivedHandler(c =>
  436. {
  437. client2TopicResults.Add(Encoding.UTF8.GetString(c.ApplicationMessage.Payload));
  438. });
  439. await client2.SubscribeAsync(client2Topic);
  440. var client3 = await testEnvironment.ConnectClientAsync();
  441. var message = new MqttApplicationMessageBuilder().WithTopic(client1Topic).Build();
  442. await client3.PublishAsync(message);
  443. await client3.PublishAsync(message);
  444. await Task.Delay(500);
  445. Assert.AreEqual(2, client2TopicResults.Count);
  446. Assert.AreEqual(expectedClient2Message, client2TopicResults[0]);
  447. Assert.AreEqual(expectedClient2Message, client2TopicResults[1]);
  448. }
  449. }
  450. [TestMethod]
  451. public async Task Subscribe_In_Callback_Events()
  452. {
  453. using (var testEnvironment = new TestEnvironment(TestContext))
  454. {
  455. await testEnvironment.StartServerAsync();
  456. var receivedMessages = new List<MqttApplicationMessage>();
  457. var client = testEnvironment.CreateClient();
  458. client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(async e =>
  459. {
  460. await client.SubscribeAsync("RCU/P1/H0001/R0003");
  461. var msg = new MqttApplicationMessageBuilder()
  462. .WithPayload("DA|18RS00SC00XI0000RV00R100R200R300R400L100L200L300L400Y100Y200AC0102031800BELK0000BM0000|")
  463. .WithTopic("RCU/P1/H0001/R0003");
  464. await client.PublishAsync(msg.Build());
  465. });
  466. client.UseApplicationMessageReceivedHandler(c =>
  467. {
  468. lock (receivedMessages)
  469. {
  470. receivedMessages.Add(c.ApplicationMessage);
  471. }
  472. });
  473. await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort).Build());
  474. await Task.Delay(500);
  475. Assert.AreEqual(1, receivedMessages.Count);
  476. Assert.AreEqual("DA|18RS00SC00XI0000RV00R100R200R300R400L100L200L300L400Y100Y200AC0102031800BELK0000BM0000|", receivedMessages.First().ConvertPayloadToString());
  477. }
  478. }
  479. [TestMethod]
  480. public async Task Message_Send_Retry()
  481. {
  482. using (var testEnvironment = new TestEnvironment(TestContext))
  483. {
  484. testEnvironment.IgnoreClientLogErrors = true;
  485. testEnvironment.IgnoreServerLogErrors = true;
  486. await testEnvironment.StartServerAsync(
  487. new MqttServerOptionsBuilder()
  488. .WithPersistentSessions()
  489. .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(250)));
  490. var client1 = await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithCleanSession(false));
  491. await client1.SubscribeAsync("x", MqttQualityOfServiceLevel.AtLeastOnce);
  492. var retries = 0;
  493. async Task Handler1(MqttApplicationMessageReceivedEventArgs eventArgs)
  494. {
  495. retries++;
  496. await Task.Delay(1000);
  497. throw new Exception("Broken!");
  498. }
  499. client1.UseApplicationMessageReceivedHandler(Handler1);
  500. var client2 = await testEnvironment.ConnectClientAsync();
  501. await client2.PublishAsync("x");
  502. await Task.Delay(3000);
  503. // The server should disconnect clients which are not responding.
  504. Assert.IsFalse(client1.IsConnected);
  505. await client1.ReconnectAsync().ConfigureAwait(false);
  506. await Task.Delay(1000);
  507. Assert.AreEqual(2, retries);
  508. }
  509. }
  510. [TestMethod]
  511. public async Task NoConnectedHandler_Connect_DoesNotThrowException()
  512. {
  513. using (var testEnvironment = new TestEnvironment(TestContext))
  514. {
  515. await testEnvironment.StartServerAsync();
  516. var client = await testEnvironment.ConnectClientAsync();
  517. Assert.IsTrue(client.IsConnected);
  518. }
  519. }
  520. [TestMethod]
  521. public async Task NoDisconnectedHandler_Disconnect_DoesNotThrowException()
  522. {
  523. using (var testEnvironment = new TestEnvironment(TestContext))
  524. {
  525. await testEnvironment.StartServerAsync();
  526. var client = await testEnvironment.ConnectClientAsync();
  527. Assert.IsTrue(client.IsConnected);
  528. await client.DisconnectAsync();
  529. Assert.IsFalse(client.IsConnected);
  530. }
  531. }
  532. [TestMethod]
  533. public async Task Frequent_Connects()
  534. {
  535. using (var testEnvironment = new TestEnvironment(TestContext))
  536. {
  537. await testEnvironment.StartServerAsync();
  538. var clients = new List<IMqttClient>();
  539. for (var i = 0; i < 100; i++)
  540. {
  541. clients.Add(await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithClientId("a")));
  542. }
  543. await Task.Delay(500);
  544. var clientStatus = await testEnvironment.Server.GetClientStatusAsync();
  545. var sessionStatus = await testEnvironment.Server.GetSessionStatusAsync();
  546. for (var i = 0; i < 98; i++)
  547. {
  548. Assert.IsFalse(clients[i].IsConnected, $"clients[{i}] is not connected");
  549. }
  550. Assert.IsTrue(clients[99].IsConnected);
  551. Assert.AreEqual(1, clientStatus.Count);
  552. Assert.AreEqual(1, sessionStatus.Count);
  553. var receiveClient = clients[99];
  554. object receivedPayload = null;
  555. receiveClient.UseApplicationMessageReceivedHandler(e =>
  556. {
  557. receivedPayload = e.ApplicationMessage.ConvertPayloadToString();
  558. });
  559. await receiveClient.SubscribeAsync("x");
  560. var sendClient = await testEnvironment.ConnectClientAsync();
  561. await sendClient.PublishAsync("x", "1");
  562. await Task.Delay(250);
  563. Assert.AreEqual("1", receivedPayload);
  564. }
  565. }
  566. [TestMethod]
  567. public async Task No_Payload()
  568. {
  569. using (var testEnvironment = new TestEnvironment(TestContext))
  570. {
  571. await testEnvironment.StartServerAsync();
  572. var sender = await testEnvironment.ConnectClientAsync();
  573. var receiver = await testEnvironment.ConnectClientAsync();
  574. var message = new MqttApplicationMessageBuilder()
  575. .WithTopic("A");
  576. await receiver.SubscribeAsync(new MqttClientSubscribeOptions
  577. {
  578. TopicFilters = new List<MqttTopicFilter> { new MqttTopicFilter { Topic = "#" } }
  579. }, CancellationToken.None);
  580. MqttApplicationMessage receivedMessage = null;
  581. receiver.UseApplicationMessageReceivedHandler(e => receivedMessage = e.ApplicationMessage);
  582. await sender.PublishAsync(message.Build(), CancellationToken.None);
  583. await Task.Delay(1000);
  584. Assert.IsNotNull(receivedMessage);
  585. Assert.AreEqual("A", receivedMessage.Topic);
  586. Assert.AreEqual(null, receivedMessage.Payload);
  587. }
  588. }
  589. [TestMethod]
  590. public async Task Subscribe_With_QoS2()
  591. {
  592. using (var testEnvironment = new TestEnvironment())
  593. {
  594. await testEnvironment.StartServerAsync();
  595. var client1 = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  596. var client2 = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  597. var disconnectedFired = false;
  598. client1.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(c =>
  599. {
  600. disconnectedFired = true;
  601. });
  602. var messageReceived = false;
  603. client1.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(c =>
  604. {
  605. messageReceived = true;
  606. });
  607. await client1.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("topic1").WithExactlyOnceQoS().Build());
  608. await Task.Delay(500);
  609. var message = new MqttApplicationMessageBuilder().WithTopic("topic1").WithPayload("Hello World").WithExactlyOnceQoS().WithRetainFlag().Build();
  610. await client2.PublishAsync(message);
  611. await Task.Delay(500);
  612. Assert.IsTrue(messageReceived);
  613. Assert.IsTrue(client1.IsConnected);
  614. Assert.IsFalse(disconnectedFired);
  615. }
  616. }
  617. }
  618. }