/// <inheritdoc/>
        public async Task <GatewayConnectionResult> DisconnectAsync
        (
            bool reconnectionIntended,
            CancellationToken ct = default
        )
        {
            if (_clientWebSocket is null)
            {
                return(GatewayConnectionResult.FromError("The transport service is not connected."));
            }

            switch (_clientWebSocket.State)
            {
            case WebSocketState.Open:
            case WebSocketState.CloseReceived:
            case WebSocketState.CloseSent:
            {
                try
                {
                    // 1012 is used here instead of normal closure, because close codes 1000 and 1001 don't
                    // allow for reconnection. 1012 is referenced in the websocket protocol as "Service restart",
                    // which makes sense for our use case.
                    var closeCode = reconnectionIntended
                            ? (WebSocketCloseStatus)1012
                            : WebSocketCloseStatus.NormalClosure;

                    await _clientWebSocket.CloseAsync
                    (
                        closeCode,
                        "Terminating connection by user request.",
                        ct
                    );
                }
                catch (WebSocketException)
                {
                    // Most likely due to some kind of premature or forced disconnection; we'll live with it
                }

                break;
            }
            }

            _clientWebSocket.Dispose();
            _clientWebSocket = null;

            this.IsConnected = false;
            return(GatewayConnectionResult.FromSuccess());
        }
        /// <inheritdoc />
        public async Task <GatewayConnectionResult> ConnectAsync(Uri endpoint, CancellationToken ct = default)
        {
            if (_clientWebSocket is not null)
            {
                return(GatewayConnectionResult.FromError("The transport service is already connected."));
            }

            var socket = _services.GetRequiredService <ClientWebSocket>();

            try
            {
                await socket.ConnectAsync(endpoint, ct);

                switch (socket.State)
                {
                case WebSocketState.Open:
                case WebSocketState.Connecting:
                {
                    break;
                }

                default:
                {
                    socket.Dispose();
                    return(GatewayConnectionResult.FromError("Failed to connect to the endpoint."));
                }
                }
            }
            catch (Exception e)
            {
                socket.Dispose();
                return(GatewayConnectionResult.FromError(e));
            }

            _clientWebSocket = socket;

            this.IsConnected = true;
            return(GatewayConnectionResult.FromSuccess());
        }