/// <inheritdoc/> protected override async Task OnOpeningAsync(CancellationToken token = default) { if (RemoteEndpoint.Server == null) { // If specific endpoint is not provided, use discovery to select endpoint with highest // security level. var endpointUrl = RemoteEndpoint.EndpointUrl; var securityPolicyUri = RemoteEndpoint.SecurityPolicyUri; try { _logger?.LogInformation($"Discovering endpoints of '{endpointUrl}'."); var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } // We should rethink this line, once we support transport profiles. }; var getEndpointsResponse = await DiscoveryService.GetEndpointsAsync(getEndpointsRequest, _loggerFactory, stackProfile : StackProfile).ConfigureAwait(false); if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0) { throw new InvalidOperationException($"'{endpointUrl}' returned no endpoints."); } var selectedEndpoint = getEndpointsResponse.Endpoints .OfType <EndpointDescription>() .Where(e => string.IsNullOrEmpty(securityPolicyUri) || e.SecurityPolicyUri == securityPolicyUri) .OrderBy(e => e.SecurityLevel) .LastOrDefault(); if (selectedEndpoint is null) { throw new InvalidOperationException($"'{endpointUrl}' returned no endpoint for the requested security policy '{securityPolicyUri}'."); } RemoteEndpoint.Server = selectedEndpoint.Server; RemoteEndpoint.ServerCertificate = selectedEndpoint.ServerCertificate; RemoteEndpoint.SecurityMode = selectedEndpoint.SecurityMode; RemoteEndpoint.SecurityPolicyUri = selectedEndpoint.SecurityPolicyUri; RemoteEndpoint.UserIdentityTokens = selectedEndpoint.UserIdentityTokens; RemoteEndpoint.TransportProfileUri = selectedEndpoint.TransportProfileUri; RemoteEndpoint.SecurityLevel = selectedEndpoint.SecurityLevel; _logger?.LogTrace($"Success discovering endpoints of '{endpointUrl}'."); } catch (Exception ex) { _logger?.LogError($"Error discovering endpoints of '{endpointUrl}'. {ex.Message}"); throw; } } // Ask for user identity. May show dialog. if (UserIdentityProvider != null) { UserIdentity = await UserIdentityProvider(RemoteEndpoint); } await base.OnOpeningAsync(token); }
public async Task ConnnectToAllEndpoints() { // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = EndpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; logger.LogInformation($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await DiscoveryService.GetEndpointsAsync(getEndpointsRequest); // for each endpoint and user identity type, try creating a session and reading a few nodes. foreach (var selectedEndpoint in getEndpointsResponse.Endpoints .OrderBy(e => e.SecurityLevel)) { foreach (var selectedTokenPolicy in selectedEndpoint.UserIdentityTokens) { IUserIdentity selectedUserIdentity; switch (selectedTokenPolicy.TokenType) { case UserTokenType.Certificate: selectedUserIdentity = x509Identity; break; case UserTokenType.UserName: selectedUserIdentity = new UserNameIdentity("root", "secret"); break; case UserTokenType.Anonymous: selectedUserIdentity = new AnonymousIdentity(); break; default: continue; } var channel = new ClientSessionChannel( localDescription, certificateStore, selectedUserIdentity, selectedEndpoint, loggerFactory: loggerFactory); await channel.OpenAsync(); logger.LogInformation($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'."); logger.LogInformation($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'."); logger.LogInformation($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'."); logger.LogInformation($"UserIdentityToken: '{channel.UserIdentity}'."); logger.LogInformation($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); } } }