Cysharp / MagicOnion

Unified Realtime/API framework for .NET platform and Unity.
MIT License
3.89k stars 433 forks source link

Introduce WaitForDisconnectAsync #837

Closed mayuki closed 2 months ago

mayuki commented 2 months ago

This PR introduces a new API WaitForDisconnectAsync to StreamingHubClient.

WaitForDisconnectAsync API is an updated version of the existing WaitForDisconnected, and it will be possible to receive the reason.

Unlike WaitForDisconnect, the new API is added as an extension method of the IStreamingHubMarker interface. This is to avoid breaking binary compatibility by changing the IStreamingHub interface.

New APIs

namespace MagicOnion.Client
{
    public static class StreamingHubClientExtensions
    {
        /// <summary>
        /// Wait for the disconnection and return the reason.
        /// </summary>
        public static Task<DisconnectionReason> WaitForDisconnectAsync<TStreamingHub>(this TStreamingHub hub) where TStreamingHub : IStreamingHubMarker =>
    }

    /// <summary>
    /// Provides the reason for the StreamingHub disconnection.
    /// </summary>
    public readonly struct DisconnectionReason
    {
        /// <summary>
        /// Gets the type of StreamingHub disconnection.
        /// </summary>
        public DisconnectionType Type { get; }

        /// <summary>
        /// Gets the exception that caused the disconnection.
        /// </summary>
        public Exception? Exception { get; }
    }

    /// <summary>
    /// Defines the types of StreamingHub disconnection.
    /// </summary>
    public enum DisconnectionType
    {
        /// <summary>
        /// Disconnected after completing successfully.
        /// </summary>
        CompletedNormally = 0,

        /// <summary>
        /// Disconnected due to exception while reading messages.
        /// </summary>
        Faulted = 1,

        /// <summary>
        /// Disconnected due to reaching the heartbeat timeout.
        /// </summary>
        TimedOut = 2,
    }
}

Usage

using MagicOnion.Client;

var client = await StreamingHubClient.ConnectAsync<IGreeterHub, IGreeterHubReceiver>(channel, receiver);
_ = WaitForDisconnectEventAsync();

async Task WaitForDisconnectEventAsync()
{
    var reason = await client.WaitForDisconnectAsync();
    if (reason.Type != DisconnectionType.CompletedNormally)
    {
        ...
    }
}