internal MultiEndpointServiceConnectionContainer( string hub, Func <HubServiceEndpoint, IServiceConnectionContainer> generator, IServiceEndpointManager endpointManager, IMessageRouter router, ILoggerFactory loggerFactory) { if (generator == null) { throw new ArgumentNullException(nameof(generator)); } _logger = loggerFactory?.CreateLogger <MultiEndpointServiceConnectionContainer>() ?? throw new ArgumentNullException(nameof(loggerFactory)); // provides a copy to the endpoint per container _endpoints = endpointManager.GetEndpoints(hub); if (_endpoints.Count == 1) { _inner = generator(_endpoints[0]); } else { // router is required when endpoints > 1 _router = router ?? throw new ArgumentNullException(nameof(router)); ConnectionContainers = _endpoints.ToDictionary(s => (ServiceEndpoint)s, s => generator(s)); } }
public async Task <NegotiationResponse> NegotiateAsync(string hubName, HttpContext httpContext = null, string userId = null, IEnumerable <Claim> claims = null, TimeSpan?lifetime = null, bool isDiagnosticClient = false, CancellationToken cancellationToken = default) { try { if (cancellationToken == default && httpContext != null) { cancellationToken = httpContext.RequestAborted; } var candidateEndpoints = _serviceEndpointManager.GetEndpoints(hubName); var selectedEndpoint = _router.GetNegotiateEndpoint(httpContext, candidateEndpoints); var provider = _serviceEndpointManager.GetEndpointProvider(selectedEndpoint); Func <IEnumerable <Claim> > claimProvider = null; if (claims != null) { claimProvider = () => claims; } var claimsWithUserId = ClaimsUtility.BuildJwtClaims(httpContext?.User, userId: userId, claimProvider, isDiagnosticClient: isDiagnosticClient); var tokenTask = provider.GenerateClientAccessTokenAsync(hubName, claimsWithUserId, lifetime); await tokenTask.OrTimeout(cancellationToken, Timeout, GeneratingTokenTaskDescription); return(new NegotiationResponse { Url = provider.GetClientEndpoint(hubName, null, null), AccessToken = tokenTask.Result }); } catch (Exception e) { throw new AzureSignalRException(ErrorMsg, e); } }
private async Task CheckEndpointHealthAsync() { await Task.WhenAll(_serviceEndpointManager.GetEndpoints(_hubName).Select(async endpoint => { var retry = 0; var isHealthy = false; bool needRetry; do { try { using var client = _clientFactory.Create(endpoint); isHealthy = await client.IsServiceHealthy(default);
public async Task <NegotiationResponse> NegotiateAsync(string hubName, NegotiationOptions negotiationOptions, CancellationToken cancellationToken = default) { negotiationOptions ??= NegotiationOptions.Default; var httpContext = negotiationOptions.HttpContext; var userId = negotiationOptions.UserId; var claims = negotiationOptions.Claims; var isDiagnosticClient = negotiationOptions.IsDiagnosticClient; var enableDetailedErrors = negotiationOptions.EnableDetailedErrors; var lifetime = negotiationOptions.TokenLifetime; try { if (cancellationToken == default && httpContext != null) { cancellationToken = httpContext.RequestAborted; } var candidateEndpoints = _serviceEndpointManager.GetEndpoints(hubName); var selectedEndpoint = _router.GetNegotiateEndpoint(httpContext, candidateEndpoints); var provider = _serviceEndpointManager.GetEndpointProvider(selectedEndpoint); Func <IEnumerable <Claim> > claimProvider = null; if (claims != null) { claimProvider = () => claims; } var claimsWithUserId = ClaimsUtility.BuildJwtClaims(httpContext?.User, userId: userId, claimProvider, enableDetailedErrors: enableDetailedErrors, isDiagnosticClient: isDiagnosticClient); var tokenTask = provider.GenerateClientAccessTokenAsync(hubName, claimsWithUserId, lifetime); await tokenTask.OrTimeout(cancellationToken, Timeout, GeneratingTokenTaskDescription); return(new NegotiationResponse { Url = provider.GetClientEndpoint(hubName, null, null), AccessToken = tokenTask.Result }); } catch (Exception e) when(e is OperationCanceledException || e is TimeoutException) { throw new AzureSignalRException(ErrorMsg, e); } }
public NegotiationResponse Process(HttpContext context, string hubName) { var claims = BuildClaims(context); var request = context.Request; var originalPath = GetOriginalPath(request.Path); var provider = _endpointManager.GetEndpointProvider(_router.GetNegotiateEndpoint(context, _endpointManager.GetEndpoints(hubName))); if (provider == null) { return(null); } var queryString = GetQueryString(request.QueryString.HasValue ? request.QueryString.Value.Substring(1) : null); return(new NegotiationResponse { Url = provider.GetClientEndpoint(hubName, originalPath, queryString), AccessToken = provider.GenerateClientAccessToken(hubName, claims), // Need to set this even though it's technically protocol violation https://github.com/aspnet/SignalR/issues/2133 AvailableTransports = new List <AvailableTransport>() }); }
IEnumerable <ServiceEndpoint> IInternalServiceHubContext.GetServiceEndpoints() => _endpointManager.GetEndpoints(_hubName);