Esempio n. 1
0
        private HubConnection buildConnection(CancellationToken cancellationToken)
        {
            var builder = new HubConnectionBuilder()
                          .WithUrl(endpoint, options =>
            {
                options.Headers.Add("Authorization", $"Bearer {api.AccessToken}");
                options.Headers.Add("OsuVersionHash", versionHash);
            });

            if (RuntimeInfo.SupportsJIT)
            {
                builder.AddMessagePackProtocol();
            }
            else
            {
                // eventually we will precompile resolvers for messagepack, but this isn't working currently
                // see https://github.com/neuecc/MessagePack-CSharp/issues/780#issuecomment-768794308.
                builder.AddNewtonsoftJsonProtocol(options => { options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
            }

            var newConnection = builder.Build();

            ConfigureConnection?.Invoke(newConnection);

            newConnection.Closed += ex => onConnectionClosed(ex, cancellationToken);
            return(newConnection);
        }
Esempio n. 2
0
        public void AddJsonProtocolAddsProtocol()
        {
            var connectionBuilder = new HubConnectionBuilder();

            connectionBuilder.AddNewtonsoftJsonProtocol();

            var serviceProvider = connectionBuilder.Services.BuildServiceProvider();

            var resolvedHubProtocol = serviceProvider.GetService <IHubProtocol>();

            Assert.IsType <NewtonsoftJsonHubProtocol>(resolvedHubProtocol);
        }
Esempio n. 3
0
        private HubConnection createConnection(CancellationToken cancellationToken)
        {
            var builder = new HubConnectionBuilder()
                          .WithUrl(endpoint, options => { options.Headers.Add("Authorization", $"Bearer {api.AccessToken}"); });

            if (RuntimeInfo.SupportsJIT)
            {
                builder.AddMessagePackProtocol();
            }
            else
            {
                // eventually we will precompile resolvers for messagepack, but this isn't working currently
                // see https://github.com/neuecc/MessagePack-CSharp/issues/780#issuecomment-768794308.
                builder.AddNewtonsoftJsonProtocol(options => { options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
            }

            var newConnection = builder.Build();

            // this is kind of SILLY
            // https://github.com/dotnet/aspnetcore/issues/15198
            newConnection.On <MultiplayerRoomState>(nameof(IMultiplayerClient.RoomStateChanged), ((IMultiplayerClient)this).RoomStateChanged);
            newConnection.On <MultiplayerRoomUser>(nameof(IMultiplayerClient.UserJoined), ((IMultiplayerClient)this).UserJoined);
            newConnection.On <MultiplayerRoomUser>(nameof(IMultiplayerClient.UserLeft), ((IMultiplayerClient)this).UserLeft);
            newConnection.On <int>(nameof(IMultiplayerClient.HostChanged), ((IMultiplayerClient)this).HostChanged);
            newConnection.On <MultiplayerRoomSettings>(nameof(IMultiplayerClient.SettingsChanged), ((IMultiplayerClient)this).SettingsChanged);
            newConnection.On <int, MultiplayerUserState>(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 <int, IEnumerable <APIMod> >(nameof(IMultiplayerClient.UserModsChanged), ((IMultiplayerClient)this).UserModsChanged);
            newConnection.On <int, BeatmapAvailability>(nameof(IMultiplayerClient.UserBeatmapAvailabilityChanged), ((IMultiplayerClient)this).UserBeatmapAvailabilityChanged);

            newConnection.Closed += ex =>
            {
                isConnected.Value = false;

                Logger.Log(ex != null ? $"Multiplayer client lost connection: {ex}" : "Multiplayer client disconnected", LoggingTarget.Network);

                // make sure a disconnect wasn't triggered (and this is still the active connection).
                if (!cancellationToken.IsCancellationRequested)
                {
                    Task.Run(connect, default);
                }

                return(Task.CompletedTask);
            };
            return(newConnection);
        }
Esempio n. 4
0
        private HubConnection buildConnection(CancellationToken cancellationToken)
        {
            var builder = new HubConnectionBuilder()
                          .WithUrl(endpoint, options =>
            {
                // Use HttpClient.DefaultProxy once on net6 everywhere.
                // The credential setter can also be removed at this point.
                options.Proxy = WebRequest.DefaultWebProxy;
                if (options.Proxy != null)
                {
                    options.Proxy.Credentials = CredentialCache.DefaultCredentials;
                }

                options.Headers.Add("Authorization", $"Bearer {api.AccessToken}");
                options.Headers.Add("OsuVersionHash", versionHash);
            });

            if (RuntimeInfo.SupportsJIT && preferMessagePack)
            {
                builder.AddMessagePackProtocol(options =>
                {
                    options.SerializerOptions = SignalRUnionWorkaroundResolver.OPTIONS;
                });
            }
            else
            {
                // eventually we will precompile resolvers for messagepack, but this isn't working currently
                // see https://github.com/neuecc/MessagePack-CSharp/issues/780#issuecomment-768794308.
                builder.AddNewtonsoftJsonProtocol(options =>
                {
                    options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                    options.PayloadSerializerSettings.Converters            = new List <JsonConverter>
                    {
                        new SignalRDerivedTypeWorkaroundJsonConverter(),
                    };
                });
            }

            var newConnection = builder.Build();

            ConfigureConnection?.Invoke(newConnection);

            newConnection.Closed += ex => onConnectionClosed(ex, cancellationToken);
            return(newConnection);
        }
        /// <summary>
        /// Open connection
        /// </summary>
        /// <returns></returns>
        private async Task <HubConnection> OpenAsync()
        {
            var builder = new HubConnectionBuilder()
                          .WithAutomaticReconnect();

            if (_useMessagePack && _msgPack != null)
            {
                builder = builder.AddMessagePackProtocol(options => {
                    options.FormatterResolvers = _msgPack.GetResolvers().ToList();
                });
            }
            else
            {
                var jsonSettings = _jsonSettings?.Settings;
                if (jsonSettings != null)
                {
                    builder = builder.AddNewtonsoftJsonProtocol(options => {
                        options.PayloadSerializerSettings = jsonSettings;
                    });
                }
            }
            var connection = builder
                             .WithUrl(_endpointUri, options => {
                if (_provider != null)
                {
                    options.AccessTokenProvider = async() => {
                        var token = await _provider.GetTokenForAsync(_resourceId);
                        if (token?.RawToken == null)
                        {
                            _logger.Error("Failed to aquire token for hub calling " +
                                          "({resource}) - calling without...",
                                          _resourceId);
                        }
                        return(token?.RawToken);
                    };
                }
            })
                             .Build();

            connection.Closed += ex => OnClosedAsync(connection, ex);
            await connection.StartAsync();

            return(connection);
        }
Esempio n. 6
0
        private HubConnection buildConnection(CancellationToken cancellationToken)
        {
            var builder = new HubConnectionBuilder()
                          .WithUrl(endpoint, options =>
            {
                options.Headers.Add("Authorization", $"Bearer {api.AccessToken}");
                options.Headers.Add("OsuVersionHash", versionHash);
            });

            if (RuntimeInfo.SupportsJIT && preferMessagePack)
            {
                builder.AddMessagePackProtocol(options =>
                {
                    options.SerializerOptions = SignalRUnionWorkaroundResolver.OPTIONS;
                });
            }
            else
            {
                // eventually we will precompile resolvers for messagepack, but this isn't working currently
                // see https://github.com/neuecc/MessagePack-CSharp/issues/780#issuecomment-768794308.
                builder.AddNewtonsoftJsonProtocol(options =>
                {
                    options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                    // TODO: This should only be required to be `TypeNameHandling.Auto`.
                    // See usage in osu-server-spectator for further documentation as to why this is required.
                    options.PayloadSerializerSettings.TypeNameHandling = TypeNameHandling.All;
                });
            }

            var newConnection = builder.Build();

            ConfigureConnection?.Invoke(newConnection);

            newConnection.Closed += ex => onConnectionClosed(ex, cancellationToken);
            return(newConnection);
        }
Esempio n. 7
0
        protected virtual async Task Connect()
        {
            if (connection != null)
            {
                return;
            }

            var builder = new HubConnectionBuilder()
                          .WithUrl(endpoint, options => { options.Headers.Add("Authorization", $"Bearer {api.AccessToken}"); });

            if (RuntimeInfo.SupportsJIT)
            {
                builder.AddMessagePackProtocol();
            }
            else
            {
                // eventually we will precompile resolvers for messagepack, but this isn't working currently
                // see https://github.com/neuecc/MessagePack-CSharp/issues/780#issuecomment-768794308.
                builder.AddNewtonsoftJsonProtocol(options => { options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
            }

            connection = builder.Build();
            // until strong typed client support is added, each method must be manually bound (see https://github.com/dotnet/aspnetcore/issues/15198)
            connection.On <int, SpectatorState>(nameof(ISpectatorClient.UserBeganPlaying), ((ISpectatorClient)this).UserBeganPlaying);
            connection.On <int, FrameDataBundle>(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames);
            connection.On <int, SpectatorState>(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying);

            connection.Closed += async ex =>
            {
                isConnected = false;
                playingUsers.Clear();

                if (ex != null)
                {
                    Logger.Log($"Spectator client lost connection: {ex}", LoggingTarget.Network);
                    await tryUntilConnected();
                }
            };

            await tryUntilConnected();

            async Task tryUntilConnected()
            {
                Logger.Log("Spectator client connecting...", LoggingTarget.Network);

                while (api.State.Value == APIState.Online)
                {
                    try
                    {
                        // reconnect on any failure
                        await connection.StartAsync();

                        Logger.Log("Spectator client connected!", LoggingTarget.Network);

                        // get all the users that were previously being watched
                        int[] users;

                        lock (userLock)
                        {
                            users = watchingUsers.ToArray();
                            watchingUsers.Clear();
                        }

                        // success
                        isConnected = true;

                        // resubscribe to watched users
                        foreach (var userId in users)
                        {
                            WatchUser(userId);
                        }

                        // re-send state in case it wasn't received
                        if (isPlaying)
                        {
                            beginPlaying();
                        }

                        break;
                    }
                    catch (Exception e)
                    {
                        Logger.Log($"Spectator client connection error: {e}", LoggingTarget.Network);
                        await Task.Delay(5000);
                    }
                }
            }
        }
Esempio n. 8
0
        protected virtual async Task Connect()
        {
            if (connection != null)
            {
                return;
            }

            var builder = new HubConnectionBuilder()
                          .WithUrl(endpoint, options => { options.Headers.Add("Authorization", $"Bearer {api.AccessToken}"); });

            if (RuntimeInfo.SupportsJIT)
            {
                builder.AddMessagePackProtocol();
            }
            else
            {
                // eventually we will precompile resolvers for messagepack, but this isn't working currently
                // see https://github.com/neuecc/MessagePack-CSharp/issues/780#issuecomment-768794308.
                builder.AddNewtonsoftJsonProtocol(options => { options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
            }

            connection = builder.Build();

            // this is kind of SILLY
            // https://github.com/dotnet/aspnetcore/issues/15198
            connection.On <MultiplayerRoomState>(nameof(IMultiplayerClient.RoomStateChanged), ((IMultiplayerClient)this).RoomStateChanged);
            connection.On <MultiplayerRoomUser>(nameof(IMultiplayerClient.UserJoined), ((IMultiplayerClient)this).UserJoined);
            connection.On <MultiplayerRoomUser>(nameof(IMultiplayerClient.UserLeft), ((IMultiplayerClient)this).UserLeft);
            connection.On <int>(nameof(IMultiplayerClient.HostChanged), ((IMultiplayerClient)this).HostChanged);
            connection.On <MultiplayerRoomSettings>(nameof(IMultiplayerClient.SettingsChanged), ((IMultiplayerClient)this).SettingsChanged);
            connection.On <int, MultiplayerUserState>(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.Closed += async ex =>
            {
                isConnected.Value = false;

                Logger.Log(ex != null
                    ? $"Multiplayer client lost connection: {ex}"
                    : "Multiplayer client disconnected", LoggingTarget.Network);

                if (connection != null)
                {
                    await tryUntilConnected();
                }
            };

            await tryUntilConnected();

            async Task tryUntilConnected()
            {
                Logger.Log("Multiplayer client connecting...", LoggingTarget.Network);

                while (api.State.Value == APIState.Online)
                {
                    try
                    {
                        Debug.Assert(connection != null);

                        // reconnect on any failure
                        await connection.StartAsync();

                        Logger.Log("Multiplayer client connected!", LoggingTarget.Network);

                        // Success.
                        isConnected.Value = true;
                        break;
                    }
                    catch (Exception e)
                    {
                        Logger.Log($"Multiplayer client connection error: {e}", LoggingTarget.Network);
                        await Task.Delay(5000);
                    }
                }
            }
        }