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.
 
 
 
 

179 lines
6.1 KiB

  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using MQTTnet.Client;
  8. using MQTTnet.Protocol;
  9. using MQTTnet.Server;
  10. namespace MQTTnet.TestApp.NetCore
  11. {
  12. public static class PerformanceTest
  13. {
  14. public static async Task RunAsync()
  15. {
  16. Console.WriteLine("Press 'c' for concurrent sends. Otherwise in one batch.");
  17. var concurrent = Console.ReadKey(true).KeyChar == 'c';
  18. var server = Task.Run(RunServerAsync);
  19. var client = Task.Run(() => RunClientAsync(2000, TimeSpan.FromMilliseconds(10), concurrent));
  20. await Task.WhenAll(server, client).ConfigureAwait(false);
  21. }
  22. private static Task RunClientsAsync(int msgChunkSize, TimeSpan interval, bool concurrent)
  23. {
  24. return Task.WhenAll(Enumerable.Range(0, 3).Select(i => Task.Run(() => RunClientAsync(msgChunkSize, interval, concurrent))));
  25. }
  26. private static async Task RunClientAsync(int msgChunkSize, TimeSpan interval, bool concurrent)
  27. {
  28. try
  29. {
  30. var options = new MqttClientOptions
  31. {
  32. ChannelOptions = new MqttClientTcpOptions { Server = "localhost" },
  33. ClientId = "Client1",
  34. CleanSession = true,
  35. CommunicationTimeout = TimeSpan.FromMinutes(10)
  36. };
  37. var client = new MqttFactory().CreateMqttClient();
  38. try
  39. {
  40. await client.ConnectAsync(options).ConfigureAwait(false);
  41. }
  42. catch (Exception exception)
  43. {
  44. Console.WriteLine("### CONNECTING FAILED ###" + Environment.NewLine + exception);
  45. }
  46. var message = CreateMessage();
  47. var messages = new[] { message };
  48. var stopwatch = Stopwatch.StartNew();
  49. var sentMessagesCount = 0;
  50. while (stopwatch.ElapsedMilliseconds < 1000)
  51. {
  52. client.PublishAsync(messages).GetAwaiter().GetResult();
  53. sentMessagesCount++;
  54. }
  55. Console.WriteLine($"Sending {sentMessagesCount} messages per second. #1");
  56. sentMessagesCount = 0;
  57. stopwatch.Restart();
  58. while (stopwatch.ElapsedMilliseconds < 1000)
  59. {
  60. await client.PublishAsync(messages).ConfigureAwait(false);
  61. sentMessagesCount++;
  62. }
  63. Console.WriteLine($"Sending {sentMessagesCount} messages per second. #2");
  64. var testMessageCount = 10000;
  65. for (var i = 0; i < testMessageCount; i++)
  66. {
  67. await client.PublishAsync(message);
  68. }
  69. stopwatch.Stop();
  70. Console.WriteLine($"Sent 10.000 messages within {stopwatch.ElapsedMilliseconds} ms ({stopwatch.ElapsedMilliseconds / (float)testMessageCount} ms / message).");
  71. var last = DateTime.Now;
  72. var msgCount = 0;
  73. while (true)
  74. {
  75. var msgs = Enumerable.Range(0, msgChunkSize)
  76. .Select(i => CreateMessage())
  77. .ToList();
  78. if (concurrent)
  79. {
  80. //send concurrent (test for raceconditions)
  81. var sendTasks = msgs
  82. .Select(msg => PublishSingleMessage(client, msg, ref msgCount))
  83. .ToList();
  84. await Task.WhenAll(sendTasks);
  85. }
  86. else
  87. {
  88. await client.PublishAsync(msgs);
  89. msgCount += msgs.Count;
  90. //send multiple
  91. }
  92. var now = DateTime.Now;
  93. if (last < now - TimeSpan.FromSeconds(1))
  94. {
  95. Console.WriteLine($"sending {msgCount} intended {msgChunkSize / interval.TotalSeconds}");
  96. msgCount = 0;
  97. last = now;
  98. }
  99. await Task.Delay(interval).ConfigureAwait(false);
  100. }
  101. }
  102. catch (Exception exception)
  103. {
  104. Console.WriteLine(exception);
  105. }
  106. }
  107. private static MqttApplicationMessage CreateMessage()
  108. {
  109. return new MqttApplicationMessage
  110. {
  111. Topic = "A/B/C",
  112. Payload = Encoding.UTF8.GetBytes("Hello World"),
  113. QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce
  114. };
  115. }
  116. private static Task PublishSingleMessage(IMqttClient client, MqttApplicationMessage applicationMessage, ref int count)
  117. {
  118. Interlocked.Increment(ref count);
  119. return Task.Run(() => client.PublishAsync(applicationMessage));
  120. }
  121. private static async Task RunServerAsync()
  122. {
  123. try
  124. {
  125. var mqttServer = new MqttFactory().CreateMqttServer();
  126. ////var msgs = 0;
  127. ////var stopwatch = Stopwatch.StartNew();
  128. ////mqttServer.ApplicationMessageReceived += (sender, args) =>
  129. ////{
  130. //// msgs++;
  131. //// if (stopwatch.ElapsedMilliseconds > 1000)
  132. //// {
  133. //// Console.WriteLine($"received {msgs}");
  134. //// msgs = 0;
  135. //// stopwatch.Restart();
  136. //// }
  137. ////};
  138. await mqttServer.StartAsync(new MqttServerOptions());
  139. Console.WriteLine("Press any key to exit.");
  140. Console.ReadLine();
  141. await mqttServer.StopAsync().ConfigureAwait(false);
  142. }
  143. catch (Exception e)
  144. {
  145. Console.WriteLine(e);
  146. }
  147. Console.ReadLine();
  148. }
  149. }
  150. }