diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..11d5f15
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,71 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "HTTP/JSON Server",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "${workspaceFolder}/Server/bin/Debug/net8.0/Server.dll",
+ "args": [ "http", "json" ],
+ "cwd": "${workspaceFolder}/Server",
+ "console": "integratedTerminal",
+ "stopAtEntry": false,
+ "presentation": {
+ "hidden": true
+ }
+ },
+ {
+ "name": "HTTP/JSON Client",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "${workspaceFolder}/Client/bin/Debug/net8.0/Client.dll",
+ "args": [ "http", "json" ],
+ "cwd": "${workspaceFolder}/Client",
+ "console": "integratedTerminal",
+ "stopAtEntry": false,
+ "presentation": {
+ "hidden": true
+ }
+ },
+ {
+ "name": "HTTP/BIN Server",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "${workspaceFolder}/Server/bin/Debug/net8.0/Server.dll",
+ "args": [ "http", "bin" ],
+ "cwd": "${workspaceFolder}/Server",
+ "console": "integratedTerminal",
+ "stopAtEntry": false,
+ "presentation": {
+ "hidden": true
+ }
+ },
+ {
+ "name": "HTTP/BIN Client",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "${workspaceFolder}/Client/bin/Debug/net8.0/Client.dll",
+ "args": [ "http", "bin" ],
+ "cwd": "${workspaceFolder}/Client",
+ "console": "integratedTerminal",
+ "stopAtEntry": false,
+ "presentation": {
+ "hidden": true
+ }
+ }
+ ],
+ "compounds": [
+ {
+ "name": "HTTP/JSON: Server and Client",
+ "configurations": ["HTTP/JSON Server", "HTTP/JSON Client"],
+ "preLaunchTask": "dotnet: build",
+ "stopAll": true
+ },
+ {
+ "name": "HTTP/BIN: Server and Client",
+ "configurations": ["HTTP/BIN Server", "HTTP/BIN Client"],
+ "preLaunchTask": "dotnet: build",
+ "stopAll": true
+ }
+ ]
+}
diff --git a/Client/Client.csproj b/Client/Client.csproj
new file mode 100644
index 0000000..c861d57
--- /dev/null
+++ b/Client/Client.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/HttpClient.cs b/Client/HttpClient.cs
new file mode 100644
index 0000000..0ab7d3b
--- /dev/null
+++ b/Client/HttpClient.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Diagnostics;
+using System.Net.Http;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using Domain;
+using Domain.Dto;
+using MessagePack;
+
+namespace Client;
+
+public class HttpClientWrapper : IClient
+{
+ private readonly HttpClient _httpClient;
+ private readonly string _baseUrl;
+ private CancellationTokenSource _cts = new CancellationTokenSource();
+ private Task? _runningTask;
+ private Func>? _responseConverter;
+
+ public HttpClientWrapper(Func> responseConverter, string baseUrl = "http://localhost:5555/")
+ {
+ _httpClient = new HttpClient();
+ _baseUrl = baseUrl;
+ _responseConverter = responseConverter;
+ }
+
+
+ public void Start()
+ {
+ _cts = new CancellationTokenSource();
+ _runningTask = Task.Run(() => RunAsync(_cts.Token));
+ }
+
+ public void Stop()
+ {
+ _cts.Cancel();
+ _runningTask?.Wait();
+ _httpClient.Dispose();
+ }
+
+ private async Task RunAsync(CancellationToken token)
+ {
+ long index = 0;
+ var sw = Stopwatch.StartNew();
+ var lastMs = 0L;
+ var lastIndex = 0L;
+ var ms = 1000;
+ while (!token.IsCancellationRequested)
+ {
+ try
+ {
+ var url = $"{_baseUrl}fetchpackage?index={index}";
+ var response = await _httpClient.GetAsync(url, token);
+ if (response.IsSuccessStatusCode)
+ {
+ if (_responseConverter != null)
+ {
+ var data = await _responseConverter(response);
+ if (data != null)
+ {
+ var diff = sw.ElapsedMilliseconds - lastMs;
+ if (diff >= ms)
+ {
+ var fetched = index - lastIndex;
+ System.Console.WriteLine($"Fetched {fetched} data packages in {diff} ms.");
+ lastIndex = index;
+ lastMs = sw.ElapsedMilliseconds;
+ }
+ //System.Console.WriteLine(data);
+ }
+ }
+ else
+ {
+ Console.WriteLine("Response converter not set.");
+ }
+ }
+ else
+ {
+ Console.WriteLine($"Failed to fetch data for index {index}: {response.StatusCode}");
+ }
+ index++;
+ //await Task.Delay(100, token); // Wait 1 second between requests
+ }
+ catch (TaskCanceledException)
+ {
+ break;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error: {ex.Message}");
+ await Task.Delay(1000, token);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Client/IClient.cs b/Client/IClient.cs
new file mode 100644
index 0000000..06e1712
--- /dev/null
+++ b/Client/IClient.cs
@@ -0,0 +1,7 @@
+namespace Client;
+
+interface IClient
+{
+ public void Start();
+ public void Stop();
+}
\ No newline at end of file
diff --git a/Client/Program.cs b/Client/Program.cs
new file mode 100644
index 0000000..50245b0
--- /dev/null
+++ b/Client/Program.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Net.Http;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using Client;
+using Domain;
+using Domain.Dto;
+using MessagePack;
+
+if (args.Length < 2)
+{
+ System.Console.WriteLine("Pass two args: http/tcp and json/bin");
+ return -1;
+}
+
+var protocol = args[0];
+var serialization = args[1];
+IClient? client = protocol == "http" ? new HttpClientWrapper(serialization == "json" ? ConvertJsonResponse : ConvertMessagePackResponse) : null;
+
+client?.Start();
+System.Console.WriteLine("Client started:");
+System.Console.WriteLine(client);
+
+// Обработка выхода по Ctrl+C
+Console.CancelKeyPress += (sender, e) =>
+{
+ e.Cancel = true; // Prevent immediate termination
+ Console.WriteLine("Shutdown signal received. Stopping client...");
+ client?.Stop();
+ Console.WriteLine("Goodbye!");
+ Environment.Exit(0);
+};
+
+// Бесконечный цикл ожидания
+while (true)
+{
+ Thread.Sleep(1000);
+}
+
+static async Task ConvertJsonResponse(HttpResponseMessage response)
+{
+ var json = await response.Content.ReadAsStringAsync();
+ var jsonData = JsonSerializer.Deserialize(json);
+ return jsonData?.ToData();
+}
+
+static async Task ConvertMessagePackResponse(HttpResponseMessage response)
+{
+ var bytes = await response.Content.ReadAsByteArrayAsync();
+ var msgPackData = MessagePackSerializer.Deserialize(bytes);
+ return msgPackData?.ToData();
+}
diff --git a/Domain/Data.cs b/Domain/Data.cs
new file mode 100644
index 0000000..a0918eb
--- /dev/null
+++ b/Domain/Data.cs
@@ -0,0 +1,17 @@
+namespace Domain;
+
+public record class Data(
+ double ConcentrationIndex,
+ double RelaxationIndex,
+ double CognitiveControl,
+ double CognitiveLoad,
+ double Alpha,
+ double Beta,
+ double Theta,
+ double Smr,
+ double MuWave,
+ bool Artifact,
+ double SignalQuality,
+ long PackageIndex,
+ DateTime TimeOfDataGenerate
+);
\ No newline at end of file
diff --git a/Domain/Domain.csproj b/Domain/Domain.csproj
new file mode 100644
index 0000000..3702e1f
--- /dev/null
+++ b/Domain/Domain.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Library
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Domain/Dto/JsonData.cs b/Domain/Dto/JsonData.cs
new file mode 100644
index 0000000..6aeae46
--- /dev/null
+++ b/Domain/Dto/JsonData.cs
@@ -0,0 +1,71 @@
+namespace Domain.Dto;
+
+using System.Text.Json.Serialization;
+
+public class JsonData
+{
+ [JsonPropertyName("concentrationIndex")]
+ public double ConcentrationIndex { get; set; }
+ [JsonPropertyName("relaxationIndex")]
+ public double RelaxationIndex { get; set; }
+ [JsonPropertyName("cognitiveControl")]
+ public double CognitiveControl { get; set; }
+ [JsonPropertyName("cognitiveLoad")]
+ public double CognitiveLoad { get; set; }
+ [JsonPropertyName("alpha")]
+ public double Alpha { get; set; }
+ [JsonPropertyName("beta")]
+ public double Beta { get; set; }
+ [JsonPropertyName("theta")]
+ public double Theta { get; set; }
+ [JsonPropertyName("smr")]
+ public double Smr { get; set; }
+ [JsonPropertyName("muWave")]
+ public double MuWave { get; set; }
+ [JsonPropertyName("artifact")]
+ public bool Artifact { get; set; }
+ [JsonPropertyName("signalQuality")]
+ public double SignalQuality { get; set; }
+ [JsonPropertyName("packageIndex")]
+ public long PackageIndex { get; set; }
+ [JsonPropertyName("timeOfDataGenerate")]
+ public DateTime TimeOfDataGenerate { get; set; }
+
+ public JsonData() { }
+
+ public JsonData(Data data)
+ {
+ ConcentrationIndex = data.ConcentrationIndex;
+ RelaxationIndex = data.RelaxationIndex;
+ CognitiveControl = data.CognitiveControl;
+ CognitiveLoad = data.CognitiveLoad;
+ Alpha = data.Alpha;
+ Beta = data.Beta;
+ Theta = data.Theta;
+ Smr = data.Smr;
+ MuWave = data.MuWave;
+ Artifact = data.Artifact;
+ SignalQuality = data.SignalQuality;
+ PackageIndex = data.PackageIndex;
+ TimeOfDataGenerate = data.TimeOfDataGenerate;
+ }
+
+ public Data ToData()
+ {
+ return new Data(
+ ConcentrationIndex,
+ RelaxationIndex,
+ CognitiveControl,
+ CognitiveLoad,
+ Alpha,
+ Beta,
+ Theta,
+ Smr,
+ MuWave,
+ Artifact,
+ SignalQuality,
+ PackageIndex,
+ TimeOfDataGenerate
+ );
+ }
+}
\ No newline at end of file
diff --git a/Domain/Dto/MessagePackData.cs b/Domain/Dto/MessagePackData.cs
new file mode 100644
index 0000000..054d086
--- /dev/null
+++ b/Domain/Dto/MessagePackData.cs
@@ -0,0 +1,72 @@
+namespace Domain.Dto;
+
+using MessagePack;
+
+[MessagePackObject]
+public class MessagePackData
+{
+ [Key("concentrationIndex")]
+ public double ConcentrationIndex { get; set; }
+ [Key("relaxationIndex")]
+ public double RelaxationIndex { get; set; }
+ [Key("cognitiveControl")]
+ public double CognitiveControl { get; set; }
+ [Key("cognitiveLoad")]
+ public double CognitiveLoad { get; set; }
+ [Key("alpha")]
+ public double Alpha { get; set; }
+ [Key("beta")]
+ public double Beta { get; set; }
+ [Key("theta")]
+ public double Theta { get; set; }
+ [Key("smr")]
+ public double Smr { get; set; }
+ [Key("muWave")]
+ public double MuWave { get; set; }
+ [Key("artifact")]
+ public bool Artifact { get; set; }
+ [Key("signalQuality")]
+ public double SignalQuality { get; set; }
+ [Key("packageIndex")]
+ public long PackageIndex { get; set; }
+ [Key("timeOfDataGenerate")]
+ public DateTime TimeOfDataGenerate { get; set; }
+
+ public MessagePackData() { }
+
+ public MessagePackData(Data data)
+ {
+ ConcentrationIndex = data.ConcentrationIndex;
+ RelaxationIndex = data.RelaxationIndex;
+ CognitiveControl = data.CognitiveControl;
+ CognitiveLoad = data.CognitiveLoad;
+ Alpha = data.Alpha;
+ Beta = data.Beta;
+ Theta = data.Theta;
+ Smr = data.Smr;
+ MuWave = data.MuWave;
+ Artifact = data.Artifact;
+ SignalQuality = data.SignalQuality;
+ PackageIndex = data.PackageIndex;
+ TimeOfDataGenerate = data.TimeOfDataGenerate;
+ }
+
+ public Data ToData()
+ {
+ return new Data(
+ ConcentrationIndex,
+ RelaxationIndex,
+ CognitiveControl,
+ CognitiveLoad,
+ Alpha,
+ Beta,
+ Theta,
+ Smr,
+ MuWave,
+ Artifact,
+ SignalQuality,
+ PackageIndex,
+ TimeOfDataGenerate
+ );
+ }
+}
\ No newline at end of file
diff --git a/NetworkTest.sln b/NetworkTest.sln
new file mode 100644
index 0000000..1a26716
--- /dev/null
+++ b/NetworkTest.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{A33376EF-FB88-4A2F-A1FD-0F9B0F89B976}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{B4ABD6BA-1C0A-49A4-8580-E5A5B9A4DD4D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "Domain\Domain.csproj", "{7EFE01A5-B489-4460-988D-E34D6C67711D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A33376EF-FB88-4A2F-A1FD-0F9B0F89B976}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A33376EF-FB88-4A2F-A1FD-0F9B0F89B976}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A33376EF-FB88-4A2F-A1FD-0F9B0F89B976}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A33376EF-FB88-4A2F-A1FD-0F9B0F89B976}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B4ABD6BA-1C0A-49A4-8580-E5A5B9A4DD4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4ABD6BA-1C0A-49A4-8580-E5A5B9A4DD4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4ABD6BA-1C0A-49A4-8580-E5A5B9A4DD4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4ABD6BA-1C0A-49A4-8580-E5A5B9A4DD4D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EFE01A5-B489-4460-988D-E34D6C67711D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7EFE01A5-B489-4460-988D-E34D6C67711D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7EFE01A5-B489-4460-988D-E34D6C67711D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7EFE01A5-B489-4460-988D-E34D6C67711D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/Server/DataGenerator.cs b/Server/DataGenerator.cs
new file mode 100644
index 0000000..56f9166
--- /dev/null
+++ b/Server/DataGenerator.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Domain;
+
+namespace Server;
+
+public class DataGenerator
+{
+ private static readonly Random _random = new Random();
+
+ private readonly int _minNewPackages;
+ private readonly int _maxPreviousPackages;
+ private readonly TimeSpan _generationInterval;
+ private readonly LinkedList _cache = new LinkedList();
+ private readonly ConcurrentDictionary _dict = [];
+ private readonly object _lock = new object();
+ private long _maxRequestedIndex = 0;
+ private Task _generationTask;
+ private CancellationTokenSource _cts = new();
+
+ public DataGenerator(int minNewPackages = 50, int maxPreviousPackages = 50, TimeSpan? generationInterval = null)
+ {
+ _minNewPackages = Math.Max(minNewPackages, 5);
+ _maxPreviousPackages = Math.Max(maxPreviousPackages, 5);
+ _generationInterval = generationInterval ?? TimeSpan.FromSeconds(1);
+ _generationTask = Task.Run(() => GenerateInBackground(_cts.Token));
+ }
+
+ private void GenerateInBackground(CancellationToken token)
+ {
+ var firstData = GenerateRandomData(0);
+ _cache.AddLast(firstData);
+ _dict[firstData.PackageIndex] = firstData;
+
+ while (!token.IsCancellationRequested)
+ {
+ //await Task.Delay(_generationInterval, token);
+ var first = _cache.First!.Value;
+ var last = _cache.Last!.Value;
+ if (last.PackageIndex - _maxRequestedIndex < _minNewPackages)
+ {
+ var data = GenerateRandomData(last.PackageIndex + 1);
+ _cache.AddLast(data);
+ _dict[data.PackageIndex] = data;
+ }
+ if (_maxRequestedIndex - first.PackageIndex > _maxPreviousPackages)
+ {
+ _cache.RemoveFirst();
+ _dict.TryRemove(first.PackageIndex, out _);
+ }
+ //System.Console.WriteLine($"[{first.PackageIndex}; {last.PackageIndex}]");
+ }
+ }
+
+ public Data? GetPackage(long packageIndex)
+ {
+ var res = _dict.TryGetValue(packageIndex, out var value);
+ _maxRequestedIndex = Math.Max(_maxRequestedIndex, packageIndex);
+ return res ? value : null;
+ }
+
+ private Data GenerateRandomData(long packageNumber)
+ {
+ var alpha = _random.NextDouble();
+ var beta = _random.NextDouble() * (1 - alpha);
+ var theta = 1 - alpha - beta;
+ var signalQuality = _random.NextDouble();
+
+ return new Data(
+ ConcentrationIndex: _random.NextDouble(),
+ RelaxationIndex: _random.NextDouble(),
+ CognitiveControl: _random.NextDouble(),
+ CognitiveLoad: _random.NextDouble(),
+ Alpha: alpha,
+ Beta: beta,
+ Theta: theta,
+ Smr: _random.NextDouble(),
+ MuWave: _random.NextDouble(),
+ Artifact: signalQuality < 0.5,
+ SignalQuality: signalQuality,
+ PackageIndex: packageNumber,
+ TimeOfDataGenerate: DateTime.Now
+ );
+ }
+}
\ No newline at end of file
diff --git a/Server/HttpServer.cs b/Server/HttpServer.cs
new file mode 100644
index 0000000..9c9bc9e
--- /dev/null
+++ b/Server/HttpServer.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Net;
+using System.Text;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using Domain;
+using Domain.Dto;
+
+namespace NetworkTest;
+
+public class HttpServer : IServer
+{
+ private readonly HttpListener _listener;
+ private readonly string _url;
+ private CancellationTokenSource _cts = new CancellationTokenSource();
+ private Func _getData;
+ private Action _writeResponse;
+
+ public HttpServer(Func getData, Action writeResponse, string url = "http://*:5555/")
+ {
+ _getData = getData;
+ _writeResponse = writeResponse;
+ _url = url;
+ _listener = new HttpListener();
+ _listener.Prefixes.Add(_url);
+ }
+
+ public void Start()
+ {
+ _cts = new CancellationTokenSource();
+ _listener.Start();
+ Task.Run(() => ListenAsync(_cts.Token));
+ }
+
+ public void Stop()
+ {
+ _cts.Cancel();
+ _listener.Stop();
+ }
+
+ private async Task ListenAsync(CancellationToken token)
+ {
+ while (!token.IsCancellationRequested)
+ {
+ try
+ {
+ var context = await _listener.GetContextAsync();
+ _ = Task.Run(() => HandleRequest(context));
+ }
+ catch (HttpListenerException)
+ {
+ break;
+ }
+ catch (ObjectDisposedException)
+ {
+ break;
+ }
+ }
+ }
+
+ private void HandleRequest(HttpListenerContext context)
+ {
+ if (context.Request.Url?.AbsolutePath.Equals("/fetchpackage", StringComparison.OrdinalIgnoreCase) == true)
+ {
+ string? indexStr = context.Request.QueryString["index"];
+ if (indexStr != null && long.TryParse(indexStr, out long index))
+ {
+ var data = _getData(index);
+ if (data != null)
+ {
+ _writeResponse(data, context.Response);
+ }
+ else
+ {
+ var responseText = JsonSerializer.Serialize(new { error = "Data not found" });
+ context.Response.StatusCode = 404;
+ byte[] buffer = Encoding.UTF8.GetBytes(responseText);
+ context.Response.ContentType = "application/json";
+ context.Response.ContentLength64 = buffer.Length;
+ context.Response.OutputStream.Write(buffer, 0, buffer.Length);
+ }
+ }
+ else
+ {
+ context.Response.StatusCode = 400;
+ byte[] buffer = Encoding.UTF8.GetBytes("Invalid or missing 'index' parameter.");
+ context.Response.OutputStream.Write(buffer, 0, buffer.Length);
+ }
+ }
+ else
+ {
+ context.Response.StatusCode = 404;
+ byte[] buffer = Encoding.UTF8.GetBytes("Not Found");
+ context.Response.OutputStream.Write(buffer, 0, buffer.Length);
+ }
+ context.Response.OutputStream.Close();
+ }
+
+ public override string ToString()
+ {
+ return $"HTTP: [{string.Join(", ", _listener.Prefixes)}]";
+ }
+}
+
diff --git a/Server/IServer.cs b/Server/IServer.cs
new file mode 100644
index 0000000..5bcc516
--- /dev/null
+++ b/Server/IServer.cs
@@ -0,0 +1,8 @@
+namespace NetworkTest;
+
+interface IServer
+{
+ public void Start();
+ public void Stop();
+
+}
\ No newline at end of file
diff --git a/Server/Program.cs b/Server/Program.cs
new file mode 100644
index 0000000..b35c6b9
--- /dev/null
+++ b/Server/Program.cs
@@ -0,0 +1,111 @@
+using System.Diagnostics;
+using System.Net;
+using System.Text;
+using System.Text.Json;
+using Domain;
+using Domain.Dto;
+using MessagePack;
+using NetworkTest;
+using Server;
+
+if (args.Length < 2)
+{
+ System.Console.WriteLine("Pass twp arg: test/http/tcp and json/bin");
+ return -1;
+}
+
+var dataGenerator = new DataGenerator(generationInterval: TimeSpan.FromMilliseconds(1));
+
+var protocol = args[0];
+var serialization = args[1];
+
+if (protocol == "test")
+{
+ int nullCount = 0;
+ long index = 0;
+ var sw = Stopwatch.StartNew();
+ var lastMs = 0L;
+ var lastIndex = 0L;
+ var ms = 1000;
+
+ var json = serialization == "json";
+ while (true)
+ {
+ var data = dataGenerator.GetPackage(index);
+ if (data == null)
+ {
+ nullCount++;
+ continue;
+ }
+
+ if (json)
+ {
+ JsonData jsonData = new JsonData(data);
+ var responseText = JsonSerializer.Serialize(jsonData);
+ byte[] buffer = Encoding.UTF8.GetBytes(responseText);
+ }
+ else
+ {
+ MessagePackData msgPackData = new MessagePackData(data);
+ byte[] buffer = MessagePackSerializer.Serialize(msgPackData);
+ }
+
+ index++;
+
+ var diff = sw.ElapsedMilliseconds - lastMs;
+ if (diff >= ms)
+ {
+ var serializrd = index - lastIndex;
+ System.Console.WriteLine($"Serialized {serializrd} data packages in {diff} ms.");
+ lastIndex = index;
+ lastMs = sw.ElapsedMilliseconds;
+ }
+ }
+}
+
+IServer? server = protocol == "http" ?
+ new HttpServer(index => dataGenerator.GetPackage(index),
+ serialization == "json" ? PrepareResponseJson : PrepareResponseMessagePack) :
+ null;
+
+server?.Start();
+System.Console.WriteLine("Server started:");
+System.Console.WriteLine(server);
+
+// Обработка выхода по Ctrl+C
+Console.CancelKeyPress += (sender, e) =>
+{
+ e.Cancel = true; // Prevent immediate termination
+ Console.WriteLine("Shutdown signal received. Stopping server...");
+ server?.Stop();
+ Console.WriteLine("Goodbye!");
+ Environment.Exit(0);
+};
+
+
+// Бесконечный цикл ожидания
+while (true)
+{
+ Thread.Sleep(1000);
+}
+
+
+void PrepareResponseJson(Data data, HttpListenerResponse response)
+{
+ JsonData jsonData = new JsonData(data);
+ var responseText = JsonSerializer.Serialize(jsonData);
+ byte[] buffer = Encoding.UTF8.GetBytes(responseText);
+ response.ContentType = "application/json";
+ response.ContentLength64 = buffer.Length;
+ response.OutputStream.Write(buffer, 0, buffer.Length);
+}
+
+void PrepareResponseMessagePack(Data data, HttpListenerResponse response)
+{
+ MessagePackData msgPackData = new MessagePackData(data);
+ byte[] buffer = MessagePackSerializer.Serialize(msgPackData);
+ response.ContentType = "application/x-msgpack";
+ response.ContentLength64 = buffer.Length;
+ response.OutputStream.Write(buffer, 0, buffer.Length);
+}
+
diff --git a/Server/Server.csproj b/Server/Server.csproj
new file mode 100644
index 0000000..ace2cb9
--- /dev/null
+++ b/Server/Server.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+