Добавлен транспорт TCP
This commit is contained in:
@@ -63,32 +63,40 @@ if (protocol == "test")
|
||||
}
|
||||
}
|
||||
|
||||
IServer? server = protocol == "http" ?
|
||||
new HttpServer(index => dataGenerator.GetPackage(index),
|
||||
serialization == "json" ? PrepareResponseJson : PrepareResponseMessagePack) :
|
||||
null;
|
||||
IServer? server = protocol switch
|
||||
{
|
||||
"http" => new HttpServer(index => dataGenerator.GetPackage(index),
|
||||
serialization == "json" ? PrepareResponseJson : PrepareResponseMessagePack),
|
||||
"tcp" => new TcpServer(index => dataGenerator.GetPackage(index),
|
||||
serialization == "json" ? PrepareBytesJson : PrepareBytesMessagePack),
|
||||
_ => null
|
||||
};
|
||||
|
||||
server?.Start();
|
||||
System.Console.WriteLine("Server started:");
|
||||
System.Console.WriteLine(server);
|
||||
|
||||
// Создаем CancellationTokenSource для управления остановкой
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
// Обработка выхода по Ctrl+C
|
||||
Console.CancelKeyPress += (sender, e) =>
|
||||
{
|
||||
e.Cancel = true; // Prevent immediate termination
|
||||
Console.WriteLine("Shutdown signal received. Stopping server...");
|
||||
cts.Cancel();
|
||||
server?.Stop();
|
||||
Console.WriteLine("Goodbye!");
|
||||
Environment.Exit(0);
|
||||
};
|
||||
|
||||
|
||||
// Бесконечный цикл ожидания
|
||||
while (true)
|
||||
// Бесконечный цикл ожидания с возможностью прерывания
|
||||
while (!cts.Token.IsCancellationRequested)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
cts.Token.WaitHandle.WaitOne(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
void PrepareResponseJson(Data data, HttpListenerResponse response)
|
||||
{
|
||||
@@ -109,3 +117,16 @@ void PrepareResponseMessagePack(Data data, HttpListenerResponse response)
|
||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
static byte[] PrepareBytesJson(Data data)
|
||||
{
|
||||
JsonData jsonData = new JsonData(data);
|
||||
var responseText = JsonSerializer.Serialize(jsonData);
|
||||
return Encoding.UTF8.GetBytes(responseText);
|
||||
}
|
||||
|
||||
static byte[] PrepareBytesMessagePack(Data data)
|
||||
{
|
||||
MessagePackData msgPackData = new MessagePackData(data);
|
||||
return MessagePackSerializer.Serialize(msgPackData);
|
||||
}
|
||||
|
||||
|
||||
86
Server/TcpServer.cs
Normal file
86
Server/TcpServer.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Domain;
|
||||
|
||||
namespace NetworkTest;
|
||||
|
||||
public class TcpServer : IServer
|
||||
{
|
||||
private readonly TcpListener _listener;
|
||||
private readonly Func<long, Data?> _getData;
|
||||
private readonly Func<Data, byte[]> _prepareBytes;
|
||||
private readonly int _port;
|
||||
private CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
|
||||
public TcpServer(Func<long, Data?> getData, Func<Data, byte[]> prepareBytes, int port = 5555)
|
||||
{
|
||||
_getData = getData;
|
||||
_prepareBytes = prepareBytes;
|
||||
_port = port;
|
||||
_listener = new TcpListener(IPAddress.Any, _port);
|
||||
}
|
||||
|
||||
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 client = await _listener.AcceptTcpClientAsync(token);
|
||||
_ = Task.Run(() => HandleClientAsync(client, token));
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleClientAsync(TcpClient client, CancellationToken token)
|
||||
{
|
||||
using (client)
|
||||
using (var stream = client.GetStream())
|
||||
{
|
||||
var index = 0L;
|
||||
while (!token.IsCancellationRequested && client.Connected)
|
||||
{
|
||||
var data = _getData(index);
|
||||
if (data != null)
|
||||
{
|
||||
var bytes = _prepareBytes(data);
|
||||
var lengthBytes = BitConverter.GetBytes(bytes.Length);
|
||||
await stream.WriteAsync(lengthBytes, 0, lengthBytes.Length, token);
|
||||
await stream.WriteAsync(bytes, 0, bytes.Length, token);
|
||||
index++;
|
||||
}
|
||||
// await Task.Delay(50, token); // Removed delay to test maximum throughput
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"TcpServer listening on port {_port}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user