Как потоки повторно используются в Asp Net Core - PullRequest
0 голосов
/ 09 июня 2018

Здравствуйте, я создаю tcp сервер, к которому у меня будет подключено несколько клиентов, которые будут отправлять и получать данные на сервер.

Я хочу знать, если фреймворк не создает 1: 1 Поток к Клиент , но использует пул потоков , как происходит следующее:

1 .Ifметод, который выполняется после принятия сокета, содержит внутри себя цикл, не будет ли выделенный поток (пулом потоков) заблокирован в контексте клиента?
2 . Где контекст для каждогоклиент хранится?

enter image description here

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);

        }
    }
...