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); }
public void AddJsonProtocolAddsProtocol() { var connectionBuilder = new HubConnectionBuilder(); connectionBuilder.AddNewtonsoftJsonProtocol(); var serviceProvider = connectionBuilder.Services.BuildServiceProvider(); var resolvedHubProtocol = serviceProvider.GetService <IHubProtocol>(); Assert.IsType <NewtonsoftJsonHubProtocol>(resolvedHubProtocol); }
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); }
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); }
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); }
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); } } } }
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); } } } }