Как потоки повторно используются в Asp Net Core
Здравствуйте, я строю tcp сервер, где у меня будет несколько подключенных клиентов, которые будут отправлять и получать данные на сервер.
Я хочу знать, если среда не создает соотношение потоков кклиенту 1:1, но использует пул потоков, как происходит следующее:
1. Если метод, который выполняется после принятия сокета, содержит внутри себя цикл, не будет ли выделенный поток (пулом потоков) заблокирован в контексте клиента?
2. Где хранится контекст для каждого клиента?
PS На моем рисунке я не понимаю, как синий поток (предоставленный пулом потоков для обслуживания двух клиентов) используется повторно.
Код ниже содержит Handler
(содержит все соединения) и Client
(оболочка сокета, с основными функциями чтения / записи).
Обработчик сокетов
class Handler
{
private Dictionary<string, Client> clients = new Dictionary<string, Client>();
private object Lock = new object();
public Handler()
{
}
public async Task LoopAsync(WebSocketManager manager)
{
WebSocket clientSocket = await manager.AcceptWebSocketAsync();
string clientID = Ext.MakeId();
using(Client newClient = Client.Create(clientSocket, clientID))
{
while (newClient.KeepAlive)
{
await newClient.ReceiveFromSocketAsync();
}
}
}
public bool RemoveClient(string ID)
{
bool removed = false;
lock (Lock)
{
if (this.clients.TryGetValue(ID, out Client client))
{
removed= this.clients.Remove(ID);
}
}
return removed;
}
}
SocketWrapper
class Client:IDisposable
{
public static Client Create(WebSocket socket,string id)
{
return new Client(socket, id);
}
private readonly string ID;
private const int BUFFER_SIZE = 100;
private readonly byte[] Buffer;
public bool KeepAlive { get; private set; }
private readonly WebSocket socket;
private Client(WebSocket socket,string ID)
{
this.socket = socket;
this.ID = ID;
this.Buffer = new byte[BUFFER_SIZE];
}
public async Task<ReadOnlyMemory<byte>> ReceiveFromSocketAsync()
{
WebSocketReceiveResult result = await this.socket.ReceiveAsync(this.Buffer, CancellationToken.None);
this.KeepAlive = result.MessageType==WebSocketMessageType.Close?false:true;
return this.Buffer.AsMemory();
}
public async Task SendToSocketAsync(string message)
{
ReadOnlyMemory<byte> memory = Encoding.UTF8.GetBytes(message);
await this.socket.SendAsync(memory, WebSocketMessageType.Binary,true,CancellationToken.None);
}
public void Dispose()
{
this.socket.Dispose();
}
}
Сервис, который будет введен в приложение:
class SocketService
{
Handler hander;
public SocketService(Handler _handler)
{
this.hander = _handler;
}
RequestDelegate next;
public async Task Invoke(HttpContext context)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await this.next(context);
return;
}
await this.hander.AddClientAsync(context.WebSockets);
}
}