mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 17:23:22 +08:00
Implement client-side disconnection flow
This commit is contained in:
parent
bb2f38d189
commit
1c612e2e0c
@ -102,6 +102,8 @@ namespace osu.Game.Online
|
|||||||
return Task.FromResult((PersistentEndpointClient)new HubClient(newConnection));
|
return Task.FromResult((PersistentEndpointClient)new HubClient(newConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task IHubClientConnector.Disconnect() => base.Disconnect();
|
||||||
|
|
||||||
protected override string ClientName { get; }
|
protected override string ClientName { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,11 @@ namespace osu.Game.Online
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<HubConnection>? ConfigureConnection { get; set; }
|
public Action<HubConnection>? ConfigureConnection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forcefully disconnects the client from the server.
|
||||||
|
/// </summary>
|
||||||
|
Task Disconnect();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reconnect if already connected.
|
/// Reconnect if already connected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
18
osu.Game/Online/IStatefulUserHubClient.cs
Normal file
18
osu.Game/Online/IStatefulUserHubClient.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace osu.Game.Online
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Common interface for clients of "stateful user hubs", i.e. server-side hubs
|
||||||
|
/// that preserve user state.
|
||||||
|
/// In the case of such hubs, concurrency constraints are enforced (only one client
|
||||||
|
/// can be connected at a time).
|
||||||
|
/// </summary>
|
||||||
|
public interface IStatefulUserHubClient
|
||||||
|
{
|
||||||
|
Task DisconnectRequested();
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface defining a multiplayer client instance.
|
/// An interface defining a multiplayer client instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IMultiplayerClient
|
public interface IMultiplayerClient : IStatefulUserHubClient
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that the room has changed state.
|
/// Signals that the room has changed state.
|
||||||
|
@ -357,6 +357,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
public abstract Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability);
|
public abstract Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability);
|
||||||
|
|
||||||
|
public abstract Task DisconnectInternal();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Change the local user's mods in the currently joined room.
|
/// Change the local user's mods in the currently joined room.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -876,5 +878,11 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
return tcs.Task;
|
return tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task IStatefulUserHubClient.DisconnectRequested()
|
||||||
|
{
|
||||||
|
Schedule(() => DisconnectInternal());
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
connection.On<MultiplayerPlaylistItem>(nameof(IMultiplayerClient.PlaylistItemAdded), ((IMultiplayerClient)this).PlaylistItemAdded);
|
connection.On<MultiplayerPlaylistItem>(nameof(IMultiplayerClient.PlaylistItemAdded), ((IMultiplayerClient)this).PlaylistItemAdded);
|
||||||
connection.On<long>(nameof(IMultiplayerClient.PlaylistItemRemoved), ((IMultiplayerClient)this).PlaylistItemRemoved);
|
connection.On<long>(nameof(IMultiplayerClient.PlaylistItemRemoved), ((IMultiplayerClient)this).PlaylistItemRemoved);
|
||||||
connection.On<MultiplayerPlaylistItem>(nameof(IMultiplayerClient.PlaylistItemChanged), ((IMultiplayerClient)this).PlaylistItemChanged);
|
connection.On<MultiplayerPlaylistItem>(nameof(IMultiplayerClient.PlaylistItemChanged), ((IMultiplayerClient)this).PlaylistItemChanged);
|
||||||
|
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMultiplayerClient)this).DisconnectRequested);
|
||||||
};
|
};
|
||||||
|
|
||||||
IsConnected.BindTo(connector.IsConnected);
|
IsConnected.BindTo(connector.IsConnected);
|
||||||
@ -255,6 +256,14 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
return connection.InvokeAsync(nameof(IMultiplayerServer.RemovePlaylistItem), playlistItemId);
|
return connection.InvokeAsync(nameof(IMultiplayerServer.RemovePlaylistItem), playlistItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Task DisconnectInternal()
|
||||||
|
{
|
||||||
|
if (connector == null)
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
|
return connector.Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
@ -159,6 +159,8 @@ namespace osu.Game.Online
|
|||||||
await Task.Run(connect, default).ConfigureAwait(false);
|
await Task.Run(connect, default).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Task Disconnect() => disconnect(true);
|
||||||
|
|
||||||
private async Task disconnect(bool takeLock)
|
private async Task disconnect(bool takeLock)
|
||||||
{
|
{
|
||||||
cancelExistingConnect();
|
cancelExistingConnect();
|
||||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Online.Spectator
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface defining a spectator client instance.
|
/// An interface defining a spectator client instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISpectatorClient
|
public interface ISpectatorClient : IStatefulUserHubClient
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that a user has begun a new play session.
|
/// Signals that a user has begun a new play session.
|
||||||
|
@ -42,6 +42,7 @@ namespace osu.Game.Online.Spectator
|
|||||||
connection.On<int, FrameDataBundle>(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames);
|
connection.On<int, FrameDataBundle>(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames);
|
||||||
connection.On<int, SpectatorState>(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying);
|
connection.On<int, SpectatorState>(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying);
|
||||||
connection.On<int, long>(nameof(ISpectatorClient.UserScoreProcessed), ((ISpectatorClient)this).UserScoreProcessed);
|
connection.On<int, long>(nameof(ISpectatorClient.UserScoreProcessed), ((ISpectatorClient)this).UserScoreProcessed);
|
||||||
|
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IStatefulUserHubClient)this).DisconnectRequested);
|
||||||
};
|
};
|
||||||
|
|
||||||
IsConnected.BindTo(connector.IsConnected);
|
IsConnected.BindTo(connector.IsConnected);
|
||||||
@ -113,5 +114,13 @@ namespace osu.Game.Online.Spectator
|
|||||||
|
|
||||||
return connection.InvokeAsync(nameof(ISpectatorServer.EndWatchingUser), userId);
|
return connection.InvokeAsync(nameof(ISpectatorServer.EndWatchingUser), userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Task DisconnectInternal()
|
||||||
|
{
|
||||||
|
if (connector == null)
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
|
return connector.Disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,6 +174,12 @@ namespace osu.Game.Online.Spectator
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task IStatefulUserHubClient.DisconnectRequested()
|
||||||
|
{
|
||||||
|
Schedule(() => DisconnectInternal());
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
public void BeginPlaying(long? scoreToken, GameplayState state, Score score)
|
public void BeginPlaying(long? scoreToken, GameplayState state, Score score)
|
||||||
{
|
{
|
||||||
// This schedule is only here to match the one below in `EndPlaying`.
|
// This schedule is only here to match the one below in `EndPlaying`.
|
||||||
@ -291,6 +297,8 @@ namespace osu.Game.Online.Spectator
|
|||||||
|
|
||||||
protected abstract Task StopWatchingUserInternal(int userId);
|
protected abstract Task StopWatchingUserInternal(int userId);
|
||||||
|
|
||||||
|
protected abstract Task DisconnectInternal();
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
@ -658,5 +658,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
PlayedAt = item.PlayedAt,
|
PlayedAt = item.PlayedAt,
|
||||||
StarRating = item.Beatmap.StarRating,
|
StarRating = item.Beatmap.StarRating,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public override Task DisconnectInternal()
|
||||||
|
{
|
||||||
|
isConnected.Value = false;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,8 @@ namespace osu.Game.Tests.Visual.Spectator
|
|||||||
|
|
||||||
public int FrameSendAttempts { get; private set; }
|
public int FrameSendAttempts { get; private set; }
|
||||||
|
|
||||||
public override IBindable<bool> IsConnected { get; } = new Bindable<bool>(true);
|
public override IBindable<bool> IsConnected => isConnected;
|
||||||
|
private readonly BindableBool isConnected = new BindableBool(true);
|
||||||
|
|
||||||
public IReadOnlyDictionary<int, ReplayFrame> LastReceivedUserFrames => lastReceivedUserFrames;
|
public IReadOnlyDictionary<int, ReplayFrame> LastReceivedUserFrames => lastReceivedUserFrames;
|
||||||
|
|
||||||
@ -179,5 +180,11 @@ namespace osu.Game.Tests.Visual.Spectator
|
|||||||
State = SpectatedUserState.Playing
|
State = SpectatedUserState.Playing
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Task DisconnectInternal()
|
||||||
|
{
|
||||||
|
isConnected.Value = false;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user