private async void Process(System.Net.Sockets.TcpClient client)
        {
            var clientId = _nextClientId++;

            var wsClient = new WebSocketClient(client)
            {
                Id           = clientId,
                ServerClient = true
            };

            Clients.Add(wsClient);

            OnClientConnected(wsClient);

            try
            {
                //check if it's a websocket connection
                while (client.Connected)
                {
                    if (await ProcessWebsocketUpgrade(wsClient).ConfigureAwait(false))
                    {
                        wsClient.UpgradedConnection = true;
                        break;
                    }
                    else
                    {
                        await Task.Delay(50).ConfigureAwait(false);
                    }
                }

                while (client.IsConnected())
                {
                    var messages = await wsClient.GetMessages().ConfigureAwait(false);

                    ProcessMessage(wsClient, messages);
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
            }

            client?.Dispose();

            Clients.Remove(wsClient);
        }
		private async Task<bool> TryReadAsync(TcpClient client, NetworkStream stream, byte[] buffer, int length, CancellationToken token)
		{
			int readBytes = 0;

			while (readBytes < length)
			{
				if (token.IsCancellationRequested || !client.IsConnected())
					return false;

				readBytes += await stream.ReadAsync(buffer, readBytes, length - readBytes, token);
			}

			return true;
		}