public async Task InvokeAsync(HttpContext context) { if (!context.WebSockets.IsWebSocketRequest) { await _next(context); return; } if (!context.User.Identity.IsAuthenticated) { context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return; } var socket = await context.WebSockets.AcceptWebSocketAsync(); var wrapper = new WebSocketWrapper(socket, _options.PackageBufferSize); var server = new MazeServer(wrapper, _options.PackageBufferSize, _options.MaxHeaderSize, ArrayPool <byte> .Shared); if (context.User.IsAdministrator()) { var accountId = context.User.GetAccountId(); var connection = new AdministrationConnection(accountId, wrapper, server); _connectionManager.AdministrationConnections.TryAdd(accountId, connection); try { await connection.BeginListen(); } finally { _connectionManager.AdministrationConnections.TryRemove(accountId, out _); } } else { var clientId = context.User.GetClientId(); var connection = new ClientConnection(clientId, wrapper, server); _connectionManager.ClientConnections.TryAdd(clientId, connection); _serviceProvider.Execute <IClientConnectedAction, IClientConnection>(connection).Forget(); try { await connection.BeginListen(); } finally { _connectionManager.ClientConnections.TryRemove(clientId, out _); } await _serviceProvider.Execute <IClientDisconnectedAction, int>(connection.ClientId); } }