Skip to content

Commit

Permalink
added WebSockets example
Browse files Browse the repository at this point in the history
  • Loading branch information
AntyaDev committed Jan 16, 2024
1 parent cb93fd8 commit 7713835
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 11 deletions.
6 changes: 2 additions & 4 deletions examples/Demo/Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@
<PackageReference Include="Bogus" Version="34.0.2" />
<PackageReference Include="Dapper.Contrib" Version="2.0.78" />
<PackageReference Include="LiteDB" Version="5.0.15" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="NBomber" Version="5.5.0-beta.0" />
<PackageReference Include="NBomber.Data" Version="5.0.0" />
<PackageReference Include="NBomber.Http" Version="5.0.1" />
<PackageReference Include="NBomber.Sinks.InfluxDB" Version="5.0.2" />
<PackageReference Include="MQTTnet" Version="3.1.2" />
<PackageReference Include="NBomber.WebSockets" Version="0.1.0-beta.1" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="9.0.0" />
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.117" />
Expand All @@ -70,9 +71,6 @@
<None Update="Features\DataFeed\users-feed-data.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Features\ClientPool\config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Features\CliArgs\config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void Run()

NBomberRunner
.RegisterScenarios(scenario)
.LoadConfig("./Features/ClientPool/config.json")
.LoadConfig("./MQTT/ClientPool/config.json")
.Run();

}
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions examples/Demo/MQTT/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
version: '3.4'
services:

emqx:
image: "emqx/emqx:4.2.0"
image: "emqx/emqx:5.0.12"
ports:
- "1883:1883"
- "18083:18083"
Expand Down
6 changes: 6 additions & 0 deletions examples/Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Demo.MQTT;
using Demo.HTTP.WebAppSimulator;
using Demo.HTTP.SimpleBookstore;
using Demo.WebSockets;

// -------------------------------
// ----- Hello World examples -----
Expand Down Expand Up @@ -73,6 +74,11 @@
// new WebAppSimulatorExample().RunHttpUserExample();
// new ExampleSimpleBookstore().Run();

// ----------------
// ----- WebSockets -----
// ----------------
// new PingPongWebSocketsTest().Run();

// ----------------
// ----- MQTT -----
// ----------------
Expand Down
57 changes: 57 additions & 0 deletions examples/Demo/WebSockets/PingPongWebSocketsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using NBomber.CSharp;
using NBomber.Data;
using NBomber.WebSockets;

namespace Demo.WebSockets;

public class PingPongWebSocketsTest
{
// To run this example you need to spin up local server examples/simulators/WebAppSimulator
// The server should run on localhost:5233, you should run http profile that configured in WebAppSimulator/Properties/launchSettings.json

public void Run()
{
var payload = Data.GenerateRandomBytes(1_000_000); // 1MB

var scenario = Scenario.Create("ping_pong_websockets", async ctx =>
{
using var websocket = new WebSocket(new WebSocketConfig());

var connect = await Step.Run("connect", ctx, async () =>
{
await websocket.Connect("ws://localhost:5233/ws");
return Response.Ok();
});

var ping = await Step.Run("ping", ctx, async () =>
{
await websocket.Send(payload);
return Response.Ok(sizeBytes: payload.Length);
});

var pong = await Step.Run("pong", ctx, async () =>
{
using var response = await websocket.Receive();
// var str = Encoding.UTF8.GetString(response.Data.Span);
// var user = JsonSerializer.Deserialize<T>(response.Data.Span);
return Response.Ok(sizeBytes: response.Data.Length);
});

var disconnect = await Step.Run("disconnect", ctx, async () =>
{
await websocket.Close();
return Response.Ok();
});

return Response.Ok();
})
.WithoutWarmUp()
.WithLoadSimulations(
Simulation.KeepConstant(10, TimeSpan.FromSeconds(30))
);

NBomberRunner
.RegisterScenarios(scenario)
.Run();
}
}
58 changes: 58 additions & 0 deletions examples/WebAppSimulator/Controllers/WebSocketController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Net.WebSockets;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IO;

namespace WebAppSimulator.Controllers;

public class WebSocketController : ControllerBase
{
private static readonly RecyclableMemoryStreamManager MsStreamManager = new();
private const int BufferSize = 1024 * 16;

[Route("/ws")]
public async Task Get()
{
if (HttpContext.WebSockets.IsWebSocketRequest)
{
using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
using var ms = MsStreamManager.GetStream();

await Receive(webSocket, ms);
await Send(webSocket, ms);

await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
}
else
{
HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
}
}

private async Task Receive(WebSocket webSocket, RecyclableMemoryStream ms)
{
var endOfMessage = false;

while (!endOfMessage)
{
var buffer = ms.GetMemory(BufferSize);
var message = await webSocket.ReceiveAsync(buffer, CancellationToken.None);

if (message.MessageType == WebSocketMessageType.Close)
{
break;
}

ms.Advance(message.Count);
endOfMessage = message.EndOfMessage;
}
}

private async Task Send(WebSocket webSocket, RecyclableMemoryStream ms)
{
if (ms.Length > 0)
{
var msg = ms.GetBuffer().AsMemory(0, (int) ms.Length);
await webSocket.SendAsync(msg, WebSocketMessageType.Binary, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
}
}
}
10 changes: 7 additions & 3 deletions examples/WebAppSimulator/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System.Buffers;
using System.IO.Pipelines;
using System.Text;
using WebAppSimulator.Infra.DAL;

namespace WebAppSimulator
Expand All @@ -6,11 +9,13 @@ public class SQLiteSettings
{
public string ConnectionString { get; set; }

Check warning on line 10 in examples/WebAppSimulator/Program.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'ConnectionString' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}

public class RedisSettings
{
public string ConnectionString { get; set; }

Check warning on line 15 in examples/WebAppSimulator/Program.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'ConnectionString' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public string ServerName { get; set; }

Check warning on line 16 in examples/WebAppSimulator/Program.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'ServerName' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}

public class Program
{
public static void Main(string[] args)
Expand All @@ -37,16 +42,13 @@ public static void Main(string[] args)
var rep = new RedisRepository(settings);

Check warning on line 42 in examples/WebAppSimulator/Program.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'settings' in 'RedisRepository.RedisRepository(RedisSettings settings)'.
builder.Services.AddSingleton<IUserRepository>(rep);
}
else
throw new Exception("The base for the test is not specified in the file appsettings.json");

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseHttpsRedirection();

if (app.Environment.IsDevelopment())
{
Expand All @@ -63,12 +65,14 @@ public static void Main(string[] args)
app.UseSwaggerUI();
}

// app.UseHttpsRedirection();
app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();
app.MapControllers();
app.UseWebSockets();

app.Run();
}
Expand Down
1 change: 1 addition & 0 deletions examples/WebAppSimulator/WebAppSimulator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<ItemGroup>
<PackageReference Include="Bogus" Version="34.0.2" />
<PackageReference Include="LiteDB" Version="5.0.15" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.117" />
Expand Down
2 changes: 1 addition & 1 deletion examples/WebAppSimulator/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"AllowedHosts": "*",

"DbUse": "SQLite",
"DbUse": "none",

"SQLiteSettings": {
"ConnectionString": "Data Source=DB/UsersDB.db"
Expand Down

0 comments on commit 7713835

Please sign in to comment.