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