diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs index 61b0961638..4a0e1282c4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs @@ -232,8 +232,6 @@ namespace osu.Game.Tests.Visual.Gameplay public class TestSpectatorStreamingClient : SpectatorStreamingClient { - protected override IBindable IsConnected { get; } = new BindableBool(false); - public readonly User StreamingUser = new User { Id = 55, Username = "Test user" }; public new BindableList PlayingUsers => (BindableList)base.PlayingUsers; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs index 6a777e2a78..aab69d687a 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs @@ -95,8 +95,6 @@ namespace osu.Game.Tests.Visual.Multiplayer public class TestMultiplayerStreaming : SpectatorStreamingClient { - protected override IBindable IsConnected { get; } = new BindableBool(false); - public new BindableList PlayingUsers => (BindableList)base.PlayingUsers; private readonly int totalUsers; diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index 07036e7ffc..6b67954351 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR.Client; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Online.API; using osu.Game.Online.Rooms; @@ -15,32 +16,41 @@ namespace osu.Game.Online.Multiplayer { public class MultiplayerClient : StatefulMultiplayerClient { - private readonly HubClientConnector connector; + private readonly string endpoint; + private HubClientConnector? connector; - public override IBindable IsConnected => connector.IsConnected; + public override IBindable IsConnected { get; } = new BindableBool(); - private HubConnection? connection => connector.CurrentConnection; + private HubConnection? connection => connector?.CurrentConnection; public MultiplayerClient(EndpointConfiguration endpoints) { - InternalChild = connector = new HubClientConnector("Multiplayer client", endpoints.MultiplayerEndpointUrl) + endpoint = endpoints.MultiplayerEndpointUrl; + } + + [BackgroundDependencyLoader] + private void load(IAPIProvider api) + { + connector = new HubClientConnector(nameof(MultiplayerClient), endpoint, api) { - OnNewConnection = newConnection => + OnNewConnection = connection => { // this is kind of SILLY // https://github.com/dotnet/aspnetcore/issues/15198 - newConnection.On(nameof(IMultiplayerClient.RoomStateChanged), ((IMultiplayerClient)this).RoomStateChanged); - newConnection.On(nameof(IMultiplayerClient.UserJoined), ((IMultiplayerClient)this).UserJoined); - newConnection.On(nameof(IMultiplayerClient.UserLeft), ((IMultiplayerClient)this).UserLeft); - newConnection.On(nameof(IMultiplayerClient.HostChanged), ((IMultiplayerClient)this).HostChanged); - newConnection.On(nameof(IMultiplayerClient.SettingsChanged), ((IMultiplayerClient)this).SettingsChanged); - newConnection.On(nameof(IMultiplayerClient.UserStateChanged), ((IMultiplayerClient)this).UserStateChanged); - newConnection.On(nameof(IMultiplayerClient.LoadRequested), ((IMultiplayerClient)this).LoadRequested); - newConnection.On(nameof(IMultiplayerClient.MatchStarted), ((IMultiplayerClient)this).MatchStarted); - newConnection.On(nameof(IMultiplayerClient.ResultsReady), ((IMultiplayerClient)this).ResultsReady); - newConnection.On>(nameof(IMultiplayerClient.UserModsChanged), ((IMultiplayerClient)this).UserModsChanged); + connection.On(nameof(IMultiplayerClient.RoomStateChanged), ((IMultiplayerClient)this).RoomStateChanged); + connection.On(nameof(IMultiplayerClient.UserJoined), ((IMultiplayerClient)this).UserJoined); + connection.On(nameof(IMultiplayerClient.UserLeft), ((IMultiplayerClient)this).UserLeft); + connection.On(nameof(IMultiplayerClient.HostChanged), ((IMultiplayerClient)this).HostChanged); + connection.On(nameof(IMultiplayerClient.SettingsChanged), ((IMultiplayerClient)this).SettingsChanged); + connection.On(nameof(IMultiplayerClient.UserStateChanged), ((IMultiplayerClient)this).UserStateChanged); + connection.On(nameof(IMultiplayerClient.LoadRequested), ((IMultiplayerClient)this).LoadRequested); + connection.On(nameof(IMultiplayerClient.MatchStarted), ((IMultiplayerClient)this).MatchStarted); + connection.On(nameof(IMultiplayerClient.ResultsReady), ((IMultiplayerClient)this).ResultsReady); + connection.On>(nameof(IMultiplayerClient.UserModsChanged), ((IMultiplayerClient)this).UserModsChanged); }, }; + + IsConnected.BindTo(connector.IsConnected); } protected override Task JoinRoom(long roomId) @@ -106,5 +116,11 @@ namespace osu.Game.Online.Multiplayer return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch)); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + connector?.Dispose(); + } } } diff --git a/osu.Game/Online/Spectator/SpectatorStreamingClient.cs b/osu.Game/Online/Spectator/SpectatorStreamingClient.cs index 33ebe27937..4ef59b5e47 100644 --- a/osu.Game/Online/Spectator/SpectatorStreamingClient.cs +++ b/osu.Game/Online/Spectator/SpectatorStreamingClient.cs @@ -30,9 +30,11 @@ namespace osu.Game.Online.Spectator /// public const double TIME_BETWEEN_SENDS = 200; - private readonly HubClientConnector connector; + private readonly string endpoint; - protected virtual IBindable IsConnected => connector.IsConnected; + private HubClientConnector connector; + + private readonly IBindable isConnected = new BindableBool(); private HubConnection connection => connector.CurrentConnection; @@ -77,23 +79,24 @@ namespace osu.Game.Online.Spectator public SpectatorStreamingClient(EndpointConfiguration endpoints) { - InternalChild = connector = new HubClientConnector("Spectator client", endpoints.SpectatorEndpointUrl) - { - OnNewConnection = newConnection => - { - // until strong typed client support is added, each method must be manually bound - // (see https://github.com/dotnet/aspnetcore/issues/15198) - newConnection.On(nameof(ISpectatorClient.UserBeganPlaying), ((ISpectatorClient)this).UserBeganPlaying); - newConnection.On(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames); - newConnection.On(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying); - } - }; + endpoint = endpoints.SpectatorEndpointUrl; } [BackgroundDependencyLoader] - private void load() + private void load(IAPIProvider api) { - IsConnected.BindValueChanged(connected => + connector = CreateConnector(nameof(SpectatorStreamingClient), endpoint, api); + connector.OnNewConnection = connection => + { + // until strong typed client support is added, each method must be manually bound + // (see https://github.com/dotnet/aspnetcore/issues/15198) + connection.On(nameof(ISpectatorClient.UserBeganPlaying), ((ISpectatorClient)this).UserBeganPlaying); + connection.On(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames); + connection.On(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying); + }; + + isConnected.BindTo(connector.IsConnected); + isConnected.BindValueChanged(connected => { if (connected.NewValue) { @@ -121,6 +124,8 @@ namespace osu.Game.Online.Spectator }, true); } + protected virtual HubClientConnector CreateConnector(string name, string endpoint, IAPIProvider api) => new HubClientConnector(name, endpoint, api); + Task ISpectatorClient.UserBeganPlaying(int userId, SpectatorState state) { if (!playingUsers.Contains(userId)) @@ -169,14 +174,14 @@ namespace osu.Game.Online.Spectator { Debug.Assert(isPlaying); - if (!IsConnected.Value) return; + if (!isConnected.Value) return; connection.SendAsync(nameof(ISpectatorServer.BeginPlaySession), currentState); } public void SendFrames(FrameDataBundle data) { - if (!IsConnected.Value) return; + if (!isConnected.Value) return; lastSend = connection.SendAsync(nameof(ISpectatorServer.SendFrameData), data); } @@ -186,7 +191,7 @@ namespace osu.Game.Online.Spectator isPlaying = false; currentBeatmap = null; - if (!IsConnected.Value) return; + if (!isConnected.Value) return; connection.SendAsync(nameof(ISpectatorServer.EndPlaySession), currentState); } @@ -200,7 +205,7 @@ namespace osu.Game.Online.Spectator watchingUsers.Add(userId); - if (!IsConnected.Value) + if (!isConnected.Value) return; } @@ -213,7 +218,7 @@ namespace osu.Game.Online.Spectator { watchingUsers.Remove(userId); - if (!IsConnected.Value) + if (!isConnected.Value) return; }