Skip to content

Commit e346c41

Browse files
AntyaDevmangystx
andauthored
MQTT Plugin (#678)
Co-authored-by: Andrey <[email protected]>
1 parent 73d4868 commit e346c41

File tree

7 files changed

+50
-168
lines changed

7 files changed

+50
-168
lines changed

examples/Demo/Demo.csproj

+5-3
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@
4949
<PackageReference Include="Dapper.Contrib" Version="2.0.78" />
5050
<PackageReference Include="LiteDB" Version="5.0.15" />
5151
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
52-
<PackageReference Include="NBomber" Version="5.6.0-beta.13" />
52+
53+
<PackageReference Include="NBomber" Version="5.6.0" />
5354
<PackageReference Include="NBomber.Data" Version="5.0.0" />
54-
<PackageReference Include="NBomber.Http" Version="5.1.0-beta.4" />
55+
<PackageReference Include="NBomber.Http" Version="5.1.0" />
56+
<PackageReference Include="NBomber.MQTT" Version="0.1.0" />
5557
<PackageReference Include="NBomber.WebSockets" Version="0.1.0" />
5658
<PackageReference Include="NBomber.Sinks.InfluxDB" Version="5.0.2" />
57-
<PackageReference Include="MQTTnet" Version="3.1.2" />
59+
5860
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="9.0.0" />
5961
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
6062
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.117" />

examples/Demo/MQTT/ClientPool/ClientPoolMqttExample.cs

+21-31
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
using System.Collections.Concurrent;
2-
using Microsoft.Extensions.Configuration;
1+
using Microsoft.Extensions.Configuration;
32
using MQTTnet;
43
using MQTTnet.Client;
5-
using MQTTnet.Client.Connecting;
6-
using MQTTnet.Client.Options;
74
using NBomber;
85
using NBomber.CSharp;
96
using NBomber.Data;
7+
using MqttClient = NBomber.MQTT.MqttClient;
108

119
namespace Demo.MQTT.ClientPool;
1210

@@ -21,30 +19,33 @@ public class ClientPoolMqttExample
2119
{
2220
public void Run()
2321
{
24-
var clientPool = new ClientPool<IMqttClient>();
25-
var responsePromises = new ConcurrentDictionary<IMqttClient, TaskCompletionSource<MqttApplicationMessage>>();
22+
var clientPool = new ClientPool<MqttClient>();
2623
var message = Array.Empty<byte>();
2724

2825
var scenario = Scenario.Create("mqtt_scenario", async ctx =>
2926
{
3027
var client = clientPool.GetClient(ctx.ScenarioInfo);
31-
var promise = responsePromises[client];
3228

3329
var publish = await Step.Run("publish", ctx, async () =>
3430
{
35-
await client.PublishAsync(client.Options.ClientId, message);
36-
return Response.Ok(sizeBytes: message.Length);
31+
var msg = new MqttApplicationMessageBuilder()
32+
.WithTopic(client.Client.Options.ClientId)
33+
.WithPayload(message)
34+
.Build();
35+
36+
var response = await client.Publish(msg);
37+
return response;
3738
});
3839

3940
var receive = await Step.Run("receive", ctx, async () =>
4041
{
41-
var response = await promise.Task;
42-
return Response.Ok(sizeBytes: response.Payload.Length);
42+
var response = await client.Receive();
43+
return response;
4344
});
4445

4546
return Response.Ok();
4647
})
47-
.WithoutWarmUp()
48+
.WithWarmUpDuration(TimeSpan.FromSeconds(3))
4849
.WithLoadSimulations(Simulation.KeepConstant(copies: 1, during: TimeSpan.FromSeconds(30)))
4950
.WithInit(async context =>
5051
{
@@ -58,29 +59,18 @@ public void Run()
5859
{
5960
counter++;
6061

61-
var client = mqttFactory.CreateMqttClient();
62+
var client = new MqttClient(mqttFactory.CreateMqttClient());
6263
var clientOptions = new MqttClientOptionsBuilder()
63-
.WithWebSocketServer(config.MqttServerUrl)
64+
.WithWebSocketServer(optionsBuilder => optionsBuilder.WithUri(config.MqttServerUrl))
6465
.WithCleanSession()
6566
.WithClientId($"client_{i}")
6667
.Build();
6768

68-
var result = await client.ConnectAsync(clientOptions);
69+
var result = await client.Connect(clientOptions);
6970

70-
if (result.ResultCode == MqttClientConnectResultCode.Success)
71+
if (!result.IsError)
7172
{
72-
// register client and push response promise
73-
responsePromises[client] = new TaskCompletionSource<MqttApplicationMessage>();
74-
75-
client.UseApplicationMessageReceivedHandler(msg =>
76-
{
77-
var promise = responsePromises[client];
78-
responsePromises[client] = new TaskCompletionSource<MqttApplicationMessage>(); // set new promise
79-
promise.TrySetResult(msg.ApplicationMessage);
80-
});
81-
82-
await client.SubscribeAsync(client.Options.ClientId);
83-
73+
await client.Subscribe(client.Client.Options.ClientId);
8474
clientPool.AddClient(client);
8575
}
8676
else
@@ -89,13 +79,13 @@ public void Run()
8979
if (counter == 10)
9080
{
9181
counter = 0;
92-
await Task.Delay(500);
82+
await Task.Delay(500); // pause, to do not overload MQTT broker
9383
}
9484
}
9585
})
96-
.WithClean(context =>
86+
.WithClean(ctx =>
9787
{
98-
clientPool.DisposeClients(client => client.DisconnectAsync().Wait());
88+
clientPool.DisposeClients(client => client.Disconnect().Wait());
9989
return Task.CompletedTask;
10090
});
10191

examples/Demo/MQTT/ClientPool/config.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
{
1010
"ScenarioName": "mqtt_scenario",
1111

12+
"WarmUpDuration": "00:00:03",
13+
1214
"LoadSimulationsSettings": [
13-
{ "KeepConstant": [500, "00:00:20"] }
15+
{ "KeepConstant": [100, "00:00:20"] }
1416
],
1517

1618
"CustomSettings": {
1719
"MqttServerUrl": "ws://localhost:8083/mqtt",
18-
"ClientCount": 500,
20+
"ClientCount": 100,
1921
"MsgSizeBytes": 200
2022
}
2123
}

examples/Demo/MQTT/ConstantRate/ConstantPublishRate.cs

-86
This file was deleted.

examples/Demo/MQTT/ConstantRate/docker-compose.yaml

-9
This file was deleted.

examples/Demo/MQTT/PingPongMqttTest.cs

+19-35
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
using MQTTnet;
22
using MQTTnet.Client;
3-
using MQTTnet.Client.Connecting;
4-
using MQTTnet.Client.Options;
53
using NBomber.CSharp;
64
using NBomber.Data;
5+
using MqttClient = NBomber.MQTT.MqttClient;
76

87
namespace Demo.MQTT;
98

@@ -15,60 +14,45 @@ public void Run()
1514

1615
var scenario = Scenario.Create("ping_pong_mqtt_scenario", async ctx =>
1716
{
18-
using var mqttClient = new MqttFactory().CreateMqttClient();
19-
var topic = $"/clients/{ctx.ScenarioInfo.ThreadId}";
20-
var promise = new TaskCompletionSource<MqttApplicationMessage>();
17+
using var client = new MqttClient(new MqttFactory().CreateMqttClient());
18+
var topic = $"/clients/{ctx.ScenarioInfo.InstanceId}";
2119

2220
var connect = await Step.Run("connect", ctx, async () =>
2321
{
2422
var clientOptions = new MqttClientOptionsBuilder()
25-
.WithWebSocketServer("ws://localhost:8083/mqtt")
23+
.WithWebSocketServer(options => options.WithUri("ws://localhost:8083/mqtt"))
2624
.WithCleanSession()
27-
.WithClientId($"client_{ctx.ScenarioInfo.ThreadId}")
25+
.WithClientId($"client_{ctx.ScenarioInfo.InstanceId}")
2826
.Build();
2927

30-
var result = await mqttClient.ConnectAsync(clientOptions);
31-
return result.ResultCode == MqttClientConnectResultCode.Success
32-
? Response.Ok()
33-
: Response.Fail(
34-
statusCode: MqttClientConnectResultCode.Success.ToString(),
35-
message: $"MQTT connection code is: {result.ResultCode}, reason: {result.ReasonString}"
36-
);
28+
var response = await client.Connect(clientOptions);
29+
return response;
3730
});
3831

39-
var subscribe = await Step.Run("subscribe", ctx, async () =>
40-
{
41-
mqttClient.UseApplicationMessageReceivedHandler(msg =>
42-
{
43-
promise.TrySetResult(msg.ApplicationMessage);
44-
});
45-
46-
await mqttClient.SubscribeAsync(topic);
47-
48-
return Response.Ok();
49-
});
32+
var subscribe = await Step.Run("subscribe", ctx, () => client.Subscribe(topic));
5033

5134
var publish = await Step.Run("publish", ctx, async () =>
5235
{
53-
await mqttClient.PublishAsync(topic, payload);
54-
return Response.Ok(sizeBytes: payload.Length);
36+
var msg = new MqttApplicationMessageBuilder()
37+
.WithTopic(topic)
38+
.WithPayload(payload)
39+
.Build();
40+
41+
var response = await client.Publish(msg);
42+
return response;
5543
});
5644

5745
var receive = await Step.Run("receive", ctx, async () =>
5846
{
59-
var msg = await promise.Task;
60-
return Response.Ok(sizeBytes: msg.Payload.Length);
47+
var response = await client.Receive();
48+
return response;
6149
});
6250

63-
var disconnect = await Step.Run("disconnect", ctx, async () =>
64-
{
65-
await mqttClient.DisconnectAsync();
66-
return Response.Ok();
67-
});
51+
var disconnect = await Step.Run("disconnect", ctx, () => client.Disconnect());
6852

6953
return Response.Ok();
7054
})
71-
.WithoutWarmUp()
55+
.WithWarmUpDuration(TimeSpan.FromSeconds(3))
7256
.WithLoadSimulations(
7357
Simulation.KeepConstant(1, TimeSpan.FromSeconds(30))
7458
);

examples/Demo/Program.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
using Demo.MQTT;
1919
using Demo.HTTP.WebAppSimulator;
2020
using Demo.HTTP.SimpleBookstore;
21-
using Demo.MQTT.ConstantRate;
21+
using Demo.MQTT.ClientPool;
2222
using Demo.WebSockets;
2323

2424
// -------------------------------
@@ -92,7 +92,6 @@
9292
// ----- MQTT -----
9393
// ----------------
9494
// new PingPongMqttTest().Run();
95-
// new ConstantPublishToMqtt().Run();
9695
// new ClientPoolMqttExample().Run();
9796

9897
// ----------------

0 commit comments

Comments
 (0)