Handling disconnection
StreamingHub has a mechanism to detect disconnection on both the client and server sides. This is because StreamingHub establishes a continuous connection between the client and server to communicate, and it may be disconnected for some reason. MagicOnion provides a mechanism for the application to detect disconnection on both the server and client sides.
Disconnection is detected at different timings on the server and client sides. This means that even if the client detects disconnection, the server may not yet recognize it. Therefore, it is important to detect disconnection on both the client and server sides.
Detecting disconnection on the server
When you want to detect disconnection from the StreamingHub on the server side, use the OnDisconnected
method.
protected override ValueTask OnDisconnected()
{
return ValueTask.CompletedTask;
}
Detecting disconnection on the client
When you want to detect disconnection from the StreamingHub on the client side, use the WaitForDisconnected
or WaitForDisconnectAsync
API.
These APIs return a Task
that waits until the StreamingHub client is disconnected for some reason.
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)
{
...
}
}
WaitForDisconnectAsync
API
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.
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,
}
}
Improving disconnection detection
To achieve early detection of communication deterioration and disconnection, MagicOnion provides a heartbeat feature. For more information on the heartbeat feature, see Heartbeat.