mirror of
https://github.com/osukey/osukey.git
synced 2025-06-05 21:07:18 +09:00
Merge pull request #18421 from peppy/reconnect-on-server-shutdown-exception
Handle server shutdown messages in room creation and spectator initialisation
This commit is contained in:
commit
ca9b2648a3
@ -20,6 +20,8 @@ namespace osu.Game.Online
|
|||||||
{
|
{
|
||||||
public class HubClientConnector : IHubClientConnector
|
public class HubClientConnector : IHubClientConnector
|
||||||
{
|
{
|
||||||
|
public const string SERVER_SHUTDOWN_MESSAGE = "Server is shutting down.";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked whenever a new hub connection is built, to configure it before it's started.
|
/// Invoked whenever a new hub connection is built, to configure it before it's started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -64,20 +66,28 @@ namespace osu.Game.Online
|
|||||||
this.preferMessagePack = preferMessagePack;
|
this.preferMessagePack = preferMessagePack;
|
||||||
|
|
||||||
apiState.BindTo(api.State);
|
apiState.BindTo(api.State);
|
||||||
apiState.BindValueChanged(state =>
|
apiState.BindValueChanged(state => connectIfPossible(), true);
|
||||||
{
|
}
|
||||||
switch (state.NewValue)
|
|
||||||
{
|
|
||||||
case APIState.Failing:
|
|
||||||
case APIState.Offline:
|
|
||||||
Task.Run(() => disconnect(true));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case APIState.Online:
|
public void Reconnect()
|
||||||
Task.Run(connect);
|
{
|
||||||
break;
|
Logger.Log($"{clientName} reconnecting...", LoggingTarget.Network);
|
||||||
}
|
Task.Run(connectIfPossible);
|
||||||
}, true);
|
}
|
||||||
|
|
||||||
|
private void connectIfPossible()
|
||||||
|
{
|
||||||
|
switch (apiState.Value)
|
||||||
|
{
|
||||||
|
case APIState.Failing:
|
||||||
|
case APIState.Offline:
|
||||||
|
Task.Run(() => disconnect(true));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case APIState.Online:
|
||||||
|
Task.Run(connect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task connect()
|
private async Task connect()
|
||||||
|
@ -30,5 +30,10 @@ namespace osu.Game.Online
|
|||||||
/// Invoked whenever a new hub connection is built, to configure it before it's started.
|
/// Invoked whenever a new hub connection is built, to configure it before it's started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<HubConnection>? ConfigureConnection { get; set; }
|
public Action<HubConnection>? ConfigureConnection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reconnect if already connected.
|
||||||
|
/// </summary>
|
||||||
|
void Reconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
Debug.Assert(exception != null);
|
Debug.Assert(exception != null);
|
||||||
|
|
||||||
string message = exception is HubException
|
string message = exception.GetHubExceptionMessage() ?? exception.Message;
|
||||||
// HubExceptions arrive with additional message context added, but we want to display the human readable message:
|
|
||||||
// "An unexpected error occurred invoking 'AddPlaylistItem' on the server.InvalidStateException: Can't enqueue more than 3 items at once."
|
|
||||||
// We generally use the message field for a user-parseable error (eventually to be replaced), so drop the first part for now.
|
|
||||||
? exception.Message.Substring(exception.Message.IndexOf(':') + 1).Trim()
|
|
||||||
: exception.Message;
|
|
||||||
|
|
||||||
Logger.Log(message, level: LogLevel.Important);
|
Logger.Log(message, level: LogLevel.Important);
|
||||||
onError?.Invoke(exception);
|
onError?.Invoke(exception);
|
||||||
@ -40,5 +35,16 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
onSuccess?.Invoke();
|
onSuccess?.Invoke();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public static string? GetHubExceptionMessage(this Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is HubException hubException)
|
||||||
|
// HubExceptions arrive with additional message context added, but we want to display the human readable message:
|
||||||
|
// "An unexpected error occurred invoking 'AddPlaylistItem' on the server.InvalidStateException: Can't enqueue more than 3 items at once."
|
||||||
|
// We generally use the message field for a user-parseable error (eventually to be replaced), so drop the first part for now.
|
||||||
|
return hubException.Message.Substring(exception.Message.IndexOf(':') + 1).Trim();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -71,14 +73,23 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task<MultiplayerRoom> JoinRoom(long roomId, string? password = null)
|
protected override async Task<MultiplayerRoom> JoinRoom(long roomId, string? password = null)
|
||||||
{
|
{
|
||||||
if (!IsConnected.Value)
|
if (!IsConnected.Value)
|
||||||
return Task.FromCanceled<MultiplayerRoom>(new CancellationToken(true));
|
throw new OperationCanceledException();
|
||||||
|
|
||||||
Debug.Assert(connection != null);
|
Debug.Assert(connection != null);
|
||||||
|
|
||||||
return connection.InvokeAsync<MultiplayerRoom>(nameof(IMultiplayerServer.JoinRoomWithPassword), roomId, password ?? string.Empty);
|
try
|
||||||
|
{
|
||||||
|
return await connection.InvokeAsync<MultiplayerRoom>(nameof(IMultiplayerServer.JoinRoomWithPassword), roomId, password ?? string.Empty);
|
||||||
|
}
|
||||||
|
catch (HubException exception)
|
||||||
|
{
|
||||||
|
if (exception.GetHubExceptionMessage() == HubClientConnector.SERVER_SHUTDOWN_MESSAGE)
|
||||||
|
connector?.Reconnect();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task LeaveRoomInternal()
|
protected override Task LeaveRoomInternal()
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
|
||||||
namespace osu.Game.Online.Spectator
|
namespace osu.Game.Online.Spectator
|
||||||
{
|
{
|
||||||
@ -47,14 +49,23 @@ namespace osu.Game.Online.Spectator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task BeginPlayingInternal(SpectatorState state)
|
protected override async Task BeginPlayingInternal(SpectatorState state)
|
||||||
{
|
{
|
||||||
if (!IsConnected.Value)
|
if (!IsConnected.Value)
|
||||||
return Task.CompletedTask;
|
return;
|
||||||
|
|
||||||
Debug.Assert(connection != null);
|
Debug.Assert(connection != null);
|
||||||
|
|
||||||
return connection.SendAsync(nameof(ISpectatorServer.BeginPlaySession), state);
|
try
|
||||||
|
{
|
||||||
|
await connection.SendAsync(nameof(ISpectatorServer.BeginPlaySession), state);
|
||||||
|
}
|
||||||
|
catch (HubException exception)
|
||||||
|
{
|
||||||
|
if (exception.GetHubExceptionMessage() == HubClientConnector.SERVER_SHUTDOWN_MESSAGE)
|
||||||
|
connector?.Reconnect();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task SendFramesInternal(FrameDataBundle bundle)
|
protected override Task SendFramesInternal(FrameDataBundle bundle)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user