diff --git a/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml b/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml
index 0dd07f8453..97dca18d7e 100644
--- a/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml
+++ b/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml
@@ -17,6 +17,6 @@
-
+ Active client count: @Model.Simulation.ActiveClients.Count
\ No newline at end of file
diff --git a/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml.cs b/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml.cs
index 5c7defc384..99b60bbcfc 100644
--- a/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml.cs
+++ b/utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml.cs
@@ -20,13 +20,13 @@ namespace Volo.ClientSimulation.Web.Pages
public async Task OnPostStartAsync()
{
- await Simulation.StartAsync();
+ Simulation.Start();
return new NoContentResult();
}
public async Task OnPostStopAsync()
{
- await Simulation.StopAsync();
+ Simulation.Stop();
return new NoContentResult();
}
}
diff --git a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationModule.cs b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationModule.cs
index f44a4a5cc1..5bf3380a8a 100644
--- a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationModule.cs
+++ b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationModule.cs
@@ -8,5 +8,6 @@ namespace Volo.ClientSimulation
)]
public class ClientSimulationModule : AbpModule
{
+
}
}
diff --git a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs
new file mode 100644
index 0000000000..a9df1fd974
--- /dev/null
+++ b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Threading;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.ClientSimulation.Clients
+{
+ public class Client : IClient, ITransientDependency
+ {
+ public event EventHandler Stopped;
+
+ public ClientState State { get; private set; }
+
+ private Thread _thread;
+
+ public Client()
+ {
+
+ }
+
+ public void Start()
+ {
+ if (State != ClientState.Stopped)
+ {
+ throw new ApplicationException("State is not stopped. It is " + State);
+ }
+
+ State = ClientState.Running;
+
+ _thread = new Thread(Run);
+ _thread.Start();
+ }
+
+ public void Stop()
+ {
+ State = ClientState.Stopping;
+ }
+
+ private void Run()
+ {
+ while (State == ClientState.Running)
+ {
+ Thread.Sleep(1);
+ }
+
+ State = ClientState.Stopped;
+ Stopped.InvokeSafely(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/ClientState.cs b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/ClientState.cs
new file mode 100644
index 0000000000..87ec5b4c5f
--- /dev/null
+++ b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/ClientState.cs
@@ -0,0 +1,9 @@
+namespace Volo.ClientSimulation.Clients
+{
+ public enum ClientState
+ {
+ Stopped,
+ Running,
+ Stopping
+ }
+}
\ No newline at end of file
diff --git a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs
new file mode 100644
index 0000000000..869645392c
--- /dev/null
+++ b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Volo.ClientSimulation.Clients
+{
+ public interface IClient
+ {
+ event EventHandler Stopped;
+
+ ClientState State { get; }
+
+ void Start();
+
+ void Stop();
+ }
+}
\ No newline at end of file
diff --git a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/GlobalOptions.cs b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/GlobalOptions.cs
new file mode 100644
index 0000000000..56e094a421
--- /dev/null
+++ b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/GlobalOptions.cs
@@ -0,0 +1,17 @@
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.ClientSimulation
+{
+ public class GlobalOptions : ISingletonDependency
+ {
+ public int MaxClientCount { get; set; } = 2;
+
+ public GlobalOptions Clone()
+ {
+ return new GlobalOptions
+ {
+ MaxClientCount = MaxClientCount
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs
index dc0ca3e51f..314eb6318f 100644
--- a/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs
+++ b/utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs
@@ -1,26 +1,85 @@
-using System.Threading.Tasks;
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
+using Volo.ClientSimulation.Clients;
namespace Volo.ClientSimulation
{
- public class Simulation : ISingletonDependency
+ public class Simulation : ISingletonDependency, IDisposable
{
+ public GlobalOptions GlobalOptions { get; }
+
+ public GlobalOptions CurrentOptions { get; private set; }
+
public SimulationState State { get; private set; }
- public Task StartAsync()
+ public List ActiveClients { get; }
+
+ private readonly IServiceScope _serviceScope;
+
+ public Simulation(
+ GlobalOptions globalOptions,
+ IServiceScopeFactory serviceScopeFactory)
+ {
+ _serviceScope = serviceScopeFactory.CreateScope();
+ GlobalOptions = globalOptions;
+ ActiveClients = new List();
+ }
+
+ public void Start()
{
State = SimulationState.Starting;
- State = SimulationState.Started;
- return Task.CompletedTask;
+ CurrentOptions = GlobalOptions.Clone();
+
+ lock (ActiveClients)
+ {
+ ActiveClients.Clear();
+
+ for (int i = 0; i < CurrentOptions.MaxClientCount; i++)
+ {
+ ActiveClients.Add(_serviceScope.ServiceProvider.GetRequiredService());
+ }
+
+ foreach (var activeClient in ActiveClients)
+ {
+ activeClient.Stopped += ActiveClientOnStopped;
+ activeClient.Start();
+ }
+ }
+
+ State = SimulationState.Started;
}
- public Task StopAsync()
+ public void Stop()
{
State = SimulationState.Stopping;
+
+ lock (ActiveClients)
+ {
+ foreach (var activeClient in ActiveClients)
+ {
+ activeClient.Stop();
+ }
+ }
+
State = SimulationState.Stopped;
+ }
- return Task.CompletedTask;
+ private void ActiveClientOnStopped(object sender, EventArgs e)
+ {
+ var client = (IClient) sender;
+
+ lock (ActiveClients)
+ {
+ ActiveClients.Remove(client);
+ }
+ }
+
+ public void Dispose()
+ {
+ _serviceScope.Dispose();
}
}
}