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.
 
 
 
 

540 wiersze
19 KiB

  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using MQTTnet.Client;
  3. using MQTTnet.Diagnostics;
  4. using MQTTnet.Protocol;
  5. using MQTTnet.Server;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using MQTTnet.Implementations;
  12. namespace MQTTnet.Core.Tests
  13. {
  14. [TestClass]
  15. public class MqttServerTests
  16. {
  17. [TestMethod]
  18. public void MqttServer_PublishSimple_AtMostOnce()
  19. {
  20. TestPublishAsync(
  21. "A/B/C",
  22. MqttQualityOfServiceLevel.AtMostOnce,
  23. "A/B/C",
  24. MqttQualityOfServiceLevel.AtMostOnce,
  25. 1).Wait();
  26. }
  27. [TestMethod]
  28. public void MqttServer_PublishSimple_AtLeastOnce()
  29. {
  30. TestPublishAsync(
  31. "A/B/C",
  32. MqttQualityOfServiceLevel.AtLeastOnce,
  33. "A/B/C",
  34. MqttQualityOfServiceLevel.AtLeastOnce,
  35. 1).Wait();
  36. }
  37. [TestMethod]
  38. public void MqttServer_PublishSimple_ExactlyOnce()
  39. {
  40. TestPublishAsync(
  41. "A/B/C",
  42. MqttQualityOfServiceLevel.ExactlyOnce,
  43. "A/B/C",
  44. MqttQualityOfServiceLevel.ExactlyOnce,
  45. 1).Wait();
  46. }
  47. [TestMethod]
  48. public async Task MqttServer_WillMessage()
  49. {
  50. var serverAdapter = new TestMqttServerAdapter();
  51. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  52. var receivedMessagesCount = 0;
  53. try
  54. {
  55. await s.StartAsync(new MqttServerOptions());
  56. var willMessage = new MqttApplicationMessageBuilder().WithTopic("My/last/will").WithAtMostOnceQoS().Build();
  57. var c1 = await serverAdapter.ConnectTestClient("c1");
  58. var c2 = await serverAdapter.ConnectTestClient("c2", willMessage);
  59. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  60. await c1.SubscribeAsync(new TopicFilterBuilder().WithTopic("#").Build());
  61. await c2.DisconnectAsync();
  62. await Task.Delay(1000);
  63. await c1.DisconnectAsync();
  64. }
  65. finally
  66. {
  67. await s.StopAsync();
  68. }
  69. Assert.AreEqual(0, receivedMessagesCount);
  70. }
  71. [TestMethod]
  72. public async Task MqttServer_SubscribeUnsubscribe()
  73. {
  74. var serverAdapter = new TestMqttServerAdapter();
  75. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  76. var receivedMessagesCount = 0;
  77. try
  78. {
  79. await s.StartAsync(new MqttServerOptions());
  80. var c1 = await serverAdapter.ConnectTestClient("c1");
  81. var c2 = await serverAdapter.ConnectTestClient("c2");
  82. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  83. var message = new MqttApplicationMessageBuilder().WithTopic("a").WithAtLeastOnceQoS().Build();
  84. await c2.PublishAsync(message);
  85. await Task.Delay(1000);
  86. Assert.AreEqual(0, receivedMessagesCount);
  87. var subscribeEventCalled = false;
  88. s.ClientSubscribedTopic += (_, e) =>
  89. {
  90. subscribeEventCalled = e.TopicFilter.Topic == "a" && e.ClientId == "c1";
  91. };
  92. await c1.SubscribeAsync(new TopicFilter("a", MqttQualityOfServiceLevel.AtLeastOnce));
  93. await Task.Delay(500);
  94. Assert.IsTrue(subscribeEventCalled, "Subscribe event not called.");
  95. await c2.PublishAsync(message);
  96. await Task.Delay(500);
  97. Assert.AreEqual(1, receivedMessagesCount);
  98. var unsubscribeEventCalled = false;
  99. s.ClientUnsubscribedTopic += (_, e) =>
  100. {
  101. unsubscribeEventCalled = e.TopicFilter == "a" && e.ClientId == "c1";
  102. };
  103. await c1.UnsubscribeAsync("a");
  104. await Task.Delay(500);
  105. Assert.IsTrue(unsubscribeEventCalled, "Unsubscribe event not called.");
  106. await c2.PublishAsync(message);
  107. await Task.Delay(1000);
  108. Assert.AreEqual(1, receivedMessagesCount);
  109. }
  110. finally
  111. {
  112. await s.StopAsync();
  113. }
  114. await Task.Delay(500);
  115. Assert.AreEqual(1, receivedMessagesCount);
  116. }
  117. [TestMethod]
  118. public async Task MqttServer_Publish()
  119. {
  120. var serverAdapter = new TestMqttServerAdapter();
  121. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  122. var receivedMessagesCount = 0;
  123. try
  124. {
  125. await s.StartAsync(new MqttServerOptions());
  126. var c1 = await serverAdapter.ConnectTestClient("c1");
  127. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  128. var message = new MqttApplicationMessageBuilder().WithTopic("a").WithAtLeastOnceQoS().Build();
  129. await c1.SubscribeAsync(new TopicFilter("a", MqttQualityOfServiceLevel.AtLeastOnce));
  130. await s.PublishAsync(message);
  131. await Task.Delay(500);
  132. }
  133. finally
  134. {
  135. await s.StopAsync();
  136. }
  137. Assert.AreEqual(1, receivedMessagesCount);
  138. }
  139. [TestMethod]
  140. public async Task MqttServer_Publish_MultipleClients()
  141. {
  142. var serverAdapter = new MqttTcpServerAdapter(new MqttNetLogger().CreateChildLogger());
  143. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  144. var receivedMessagesCount = 0;
  145. var locked = new object();
  146. var clientOptions = new MqttClientOptionsBuilder()
  147. .WithTcpServer("localhost")
  148. .Build();
  149. var clientOptions2 = new MqttClientOptionsBuilder()
  150. .WithTcpServer("localhost")
  151. .Build();
  152. try
  153. {
  154. await s.StartAsync(new MqttServerOptions());
  155. var c1 = new MqttFactory().CreateMqttClient();
  156. var c2 = new MqttFactory().CreateMqttClient();
  157. await c1.ConnectAsync(clientOptions);
  158. await c2.ConnectAsync(clientOptions2);
  159. c1.ApplicationMessageReceived += (_, __) =>
  160. {
  161. lock (locked)
  162. {
  163. receivedMessagesCount++;
  164. }
  165. };
  166. c2.ApplicationMessageReceived += (_, __) =>
  167. {
  168. lock (locked)
  169. {
  170. receivedMessagesCount++;
  171. }
  172. };
  173. var message = new MqttApplicationMessageBuilder().WithTopic("a").WithAtLeastOnceQoS().Build();
  174. await c1.SubscribeAsync(new TopicFilter("a", MqttQualityOfServiceLevel.AtLeastOnce));
  175. await c2.SubscribeAsync(new TopicFilter("a", MqttQualityOfServiceLevel.AtLeastOnce));
  176. //await Task.WhenAll(Publish(c1, message), Publish(c2, message));
  177. await Publish(c1, message);
  178. await Task.Delay(500);
  179. }
  180. finally
  181. {
  182. await s.StopAsync();
  183. }
  184. Assert.AreEqual(2000, receivedMessagesCount);
  185. }
  186. private static async Task Publish(IMqttClient c1, MqttApplicationMessage message)
  187. {
  188. for (int i = 0; i < 1000; i++)
  189. {
  190. await c1.PublishAsync(message);
  191. }
  192. }
  193. [TestMethod]
  194. public async Task MqttServer_RetainedMessagesFlow()
  195. {
  196. var retainedMessage = new MqttApplicationMessageBuilder().WithTopic("r").WithPayload("r").WithRetainFlag().Build();
  197. var serverAdapter = new TestMqttServerAdapter();
  198. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  199. await s.StartAsync(new MqttServerOptions());
  200. var c1 = await serverAdapter.ConnectTestClient("c1");
  201. await c1.PublishAsync(retainedMessage);
  202. Thread.Sleep(500);
  203. await c1.DisconnectAsync();
  204. Thread.Sleep(500);
  205. var receivedMessages = 0;
  206. var c2 = await serverAdapter.ConnectTestClient("c2");
  207. c2.ApplicationMessageReceived += (_, e) =>
  208. {
  209. receivedMessages++;
  210. };
  211. for (var i = 0; i < 5; i++)
  212. {
  213. await c2.UnsubscribeAsync("r");
  214. await Task.Delay(500);
  215. Assert.AreEqual(i, receivedMessages);
  216. await c2.SubscribeAsync("r");
  217. await Task.Delay(500);
  218. Assert.AreEqual(i + 1, receivedMessages);
  219. }
  220. await c2.DisconnectAsync();
  221. }
  222. [TestMethod]
  223. public async Task MqttServer_NoRetainedMessage()
  224. {
  225. var serverAdapter = new TestMqttServerAdapter();
  226. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  227. var receivedMessagesCount = 0;
  228. try
  229. {
  230. await s.StartAsync(new MqttServerOptions());
  231. var c1 = await serverAdapter.ConnectTestClient("c1");
  232. await c1.PublishAsync(builder => builder.WithTopic("retained").WithPayload(new byte[3]));
  233. await c1.DisconnectAsync();
  234. var c2 = await serverAdapter.ConnectTestClient("c2");
  235. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  236. await c2.SubscribeAsync(new TopicFilterBuilder().WithTopic("retained").Build());
  237. await Task.Delay(500);
  238. }
  239. finally
  240. {
  241. await s.StopAsync();
  242. }
  243. Assert.AreEqual(0, receivedMessagesCount);
  244. }
  245. [TestMethod]
  246. public async Task MqttServer_RetainedMessage()
  247. {
  248. var serverAdapter = new TestMqttServerAdapter();
  249. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  250. var receivedMessagesCount = 0;
  251. try
  252. {
  253. await s.StartAsync(new MqttServerOptions());
  254. var c1 = await serverAdapter.ConnectTestClient("c1");
  255. await c1.PublishAndWaitForAsync(s, new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
  256. await c1.DisconnectAsync();
  257. var c2 = await serverAdapter.ConnectTestClient("c2");
  258. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  259. await c2.SubscribeAsync(new TopicFilterBuilder().WithTopic("retained").Build());
  260. await Task.Delay(500);
  261. }
  262. finally
  263. {
  264. await s.StopAsync();
  265. }
  266. Assert.AreEqual(1, receivedMessagesCount);
  267. }
  268. [TestMethod]
  269. public async Task MqttServer_ClearRetainedMessage()
  270. {
  271. var serverAdapter = new TestMqttServerAdapter();
  272. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  273. var receivedMessagesCount = 0;
  274. try
  275. {
  276. await s.StartAsync(new MqttServerOptions());
  277. var c1 = await serverAdapter.ConnectTestClient("c1");
  278. await c1.PublishAsync(builder => builder.WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag());
  279. await c1.PublishAsync(builder => builder.WithTopic("retained").WithPayload(new byte[0]).WithRetainFlag());
  280. await c1.DisconnectAsync();
  281. var c2 = await serverAdapter.ConnectTestClient("c2");
  282. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  283. await Task.Delay(200);
  284. await c2.SubscribeAsync(new TopicFilter("retained", MqttQualityOfServiceLevel.AtMostOnce));
  285. await Task.Delay(500);
  286. }
  287. finally
  288. {
  289. await s.StopAsync();
  290. }
  291. Assert.AreEqual(0, receivedMessagesCount);
  292. }
  293. [TestMethod]
  294. public async Task MqttServer_PersistRetainedMessage()
  295. {
  296. var storage = new TestStorage();
  297. var serverAdapter = new TestMqttServerAdapter();
  298. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  299. try
  300. {
  301. var options = new MqttServerOptions { Storage = storage };
  302. await s.StartAsync(options);
  303. var c1 = await serverAdapter.ConnectTestClient("c1");
  304. await c1.PublishAndWaitForAsync(s, new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
  305. await Task.Delay(250);
  306. await c1.DisconnectAsync();
  307. }
  308. finally
  309. {
  310. await s.StopAsync();
  311. }
  312. Assert.AreEqual(1, storage.Messages.Count);
  313. s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  314. var receivedMessagesCount = 0;
  315. try
  316. {
  317. var options = new MqttServerOptions { Storage = storage };
  318. await s.StartAsync(options);
  319. var c2 = await serverAdapter.ConnectTestClient("c2");
  320. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  321. await c2.SubscribeAsync(new TopicFilterBuilder().WithTopic("retained").Build());
  322. await Task.Delay(250);
  323. }
  324. finally
  325. {
  326. await s.StopAsync();
  327. }
  328. Assert.AreEqual(1, receivedMessagesCount);
  329. }
  330. [TestMethod]
  331. public async Task MqttServer_InterceptMessage()
  332. {
  333. void Interceptor(MqttApplicationMessageInterceptorContext context)
  334. {
  335. context.ApplicationMessage.Payload = Encoding.ASCII.GetBytes("extended");
  336. }
  337. var serverAdapter = new TestMqttServerAdapter();
  338. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  339. try
  340. {
  341. var options = new MqttServerOptions { ApplicationMessageInterceptor = Interceptor };
  342. await s.StartAsync(options);
  343. var c1 = await serverAdapter.ConnectTestClient("c1");
  344. var c2 = await serverAdapter.ConnectTestClient("c2");
  345. await c2.SubscribeAsync(new TopicFilterBuilder().WithTopic("test").Build());
  346. var isIntercepted = false;
  347. c2.ApplicationMessageReceived += (sender, args) =>
  348. {
  349. isIntercepted = string.Compare("extended", Encoding.UTF8.GetString(args.ApplicationMessage.Payload), StringComparison.Ordinal) == 0;
  350. };
  351. await c1.PublishAsync(builder => builder.WithTopic("test"));
  352. await c1.DisconnectAsync();
  353. await Task.Delay(500);
  354. Assert.IsTrue(isIntercepted);
  355. }
  356. finally
  357. {
  358. await s.StopAsync();
  359. }
  360. }
  361. [TestMethod]
  362. public async Task MqttServer_Body()
  363. {
  364. var serverAdapter = new TestMqttServerAdapter();
  365. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  366. var bodyIsMatching = false;
  367. try
  368. {
  369. await s.StartAsync(new MqttServerOptions());
  370. var c1 = await serverAdapter.ConnectTestClient("c1");
  371. var c2 = await serverAdapter.ConnectTestClient("c2");
  372. c1.ApplicationMessageReceived += (_, e) =>
  373. {
  374. if (Encoding.UTF8.GetString(e.ApplicationMessage.Payload) == "The body")
  375. {
  376. bodyIsMatching = true;
  377. }
  378. };
  379. await c1.SubscribeAsync("A", MqttQualityOfServiceLevel.AtMostOnce);
  380. await c2.PublishAsync(builder => builder.WithTopic("A").WithPayload(Encoding.UTF8.GetBytes("The body")));
  381. await Task.Delay(1000);
  382. }
  383. finally
  384. {
  385. await s.StopAsync();
  386. }
  387. Assert.IsTrue(bodyIsMatching);
  388. }
  389. private class TestStorage : IMqttServerStorage
  390. {
  391. public IList<MqttApplicationMessage> Messages = new List<MqttApplicationMessage>();
  392. public Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
  393. {
  394. Messages = messages;
  395. return Task.CompletedTask;
  396. }
  397. public Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
  398. {
  399. return Task.FromResult(Messages);
  400. }
  401. }
  402. private static async Task TestPublishAsync(
  403. string topic,
  404. MqttQualityOfServiceLevel qualityOfServiceLevel,
  405. string topicFilter,
  406. MqttQualityOfServiceLevel filterQualityOfServiceLevel,
  407. int expectedReceivedMessagesCount)
  408. {
  409. var serverAdapter = new TestMqttServerAdapter();
  410. var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
  411. var receivedMessagesCount = 0;
  412. try
  413. {
  414. await s.StartAsync(new MqttServerOptions());
  415. var c1 = await serverAdapter.ConnectTestClient("c1");
  416. var c2 = await serverAdapter.ConnectTestClient("c2");
  417. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  418. await c1.SubscribeAsync(new TopicFilterBuilder().WithTopic(topicFilter).WithQualityOfServiceLevel(filterQualityOfServiceLevel).Build());
  419. await c2.PublishAsync(builder => builder.WithTopic(topic).WithPayload(new byte[0]).WithQualityOfServiceLevel(qualityOfServiceLevel));
  420. await Task.Delay(500);
  421. await c1.UnsubscribeAsync(topicFilter);
  422. await Task.Delay(500);
  423. }
  424. finally
  425. {
  426. await s.StopAsync();
  427. }
  428. Assert.AreEqual(expectedReceivedMessagesCount, receivedMessagesCount);
  429. }
  430. }
  431. }