/// <summary>
        /// This Service returns the Servers known to a Server or Discovery Server.
        /// </summary>
        /// <param name="request">a request.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public static async Task<FindServersResponse> FindServersAsync(FindServersRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            var client = new UaTcpDiscoveryClient(
                new EndpointDescription
                {
                    EndpointUrl = request.EndpointUrl,
                    SecurityMode = MessageSecurityMode.None,
                    SecurityPolicyUri = SecurityPolicyUris.None
                });
            try
            {
                await client.OpenAsync().ConfigureAwait(false);
                var response = await client.innerChannel.RequestAsync(request).ConfigureAwait(false);
                await client.CloseAsync().ConfigureAwait(false);
                return (FindServersResponse)response;
            }
            catch (Exception)
            {
                await client.AbortAsync().ConfigureAwait(false);
                throw;
            }
        }
        /// <summary>
        /// This Service returns the Endpoints supported by a Server and all of the configuration information required to establish a SecureChannel and a Session.
        /// </summary>
        /// <param name="request">a request.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public static async Task <GetEndpointsResponse> GetEndpointsAsync(GetEndpointsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            var client = new UaTcpDiscoveryClient(
                new EndpointDescription
            {
                EndpointUrl       = request.EndpointUrl,
                SecurityMode      = MessageSecurityMode.None,
                SecurityPolicyUri = SecurityPolicyUris.None
            });

            try
            {
                await client.OpenAsync().ConfigureAwait(false);

                var response = await client.innerChannel.RequestAsync(request).ConfigureAwait(false);

                await client.CloseAsync().ConfigureAwait(false);

                return((GetEndpointsResponse)response);
            }
            catch (Exception)
            {
                await client.AbortAsync().ConfigureAwait(false);

                throw;
            }
        }
        /// <summary>
        /// Opens a session with the remote endpoint.
        /// </summary>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task.</returns>
        private async Task OpenAsync(CancellationToken token = default(CancellationToken))
        {
            await this.semaphore.WaitAsync(token).ConfigureAwait(false);

            try
            {
                if (this.RemoteEndpoint == null)
                {
                    // If specific endpoint is not provided, use discovery to select endpoint with highest
                    // security level.
                    try
                    {
                        this.Logger?.LogInformation($"Discovering endpoints of '{this.discoveryUrl}'.");
                        var getEndpointsRequest = new GetEndpointsRequest
                        {
                            EndpointUrl = this.discoveryUrl,
                            ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
                        };
                        var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest).ConfigureAwait(false);

                        if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0)
                        {
                            throw new InvalidOperationException($"'{this.discoveryUrl}' returned no endpoints.");
                        }

                        this.RemoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();
                        this.Logger?.LogTrace($"Success discovering endpoints of '{this.discoveryUrl}'.");
                    }
                    catch (Exception ex)
                    {
                        this.Logger?.LogError($"Error discovering endpoints of '{this.discoveryUrl}'. {ex.Message}");
                        throw;
                    }
                }

                // throw here to exit state machine.
                token.ThrowIfCancellationRequested();

                // evaluate the user identity provider (may show a dialog).
                var userIdentity = await this.UserIdentityProvider(this.RemoteEndpoint);

                try
                {
                    this.linkToken?.Dispose();
                    if (this.innerChannel != null && this.innerChannel.State != CommunicationState.Closed)
                    {
                        await this.innerChannel.AbortAsync();
                    }

                    this.innerChannel = new UaTcpSessionChannel(
                        this.LocalDescription,
                        this.CertificateStore,
                        userIdentity,
                        this.RemoteEndpoint,
                        this.loggerFactory,
                        this.SessionTimeout,
                        this.TimeoutHint,
                        this.DiagnosticsHint,
                        this.LocalReceiveBufferSize,
                        this.LocalSendBufferSize,
                        this.LocalMaxMessageSize,
                        this.LocalMaxChunkCount);

                    await this.innerChannel.OpenAsync(token).ConfigureAwait(false);

                    this.linkToken = this.pendingRequests.LinkTo(this.innerChannel);

                    //// create an internal subscription.
                    //var subscriptionRequest = new CreateSubscriptionRequest
                    //{
                    //    RequestedPublishingInterval = DefaultPublishingInterval,
                    //    RequestedMaxKeepAliveCount = DefaultKeepaliveCount,
                    //    RequestedLifetimeCount = (uint)(this.SessionTimeout / DefaultPublishingInterval),
                    //    PublishingEnabled = true,
                    //    Priority = 0
                    //};
                    //var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);
                    //this.subscriptionId = subscriptionResponse.SubscriptionId;
                }
                catch (Exception ex)
                {
                    this.Logger?.LogError($"Error opening channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'. {ex.Message}");
                    throw;
                }
            }
            finally
            {
                this.semaphore.Release();
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Opens a session with the remote endpoint.
        /// </summary>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task.</returns>
        private async Task OpenAsync(CancellationToken token = default(CancellationToken))
        {
            await this.semaphore.WaitAsync(token).ConfigureAwait(false);

            try
            {
                if (this.RemoteEndpoint == null)
                {
                    // If specific endpoint is not provided, use discovery to select endpoint with highest
                    // security level.
                    try
                    {
                        Trace.TraceInformation($"UaTcpSessionClient discovering endpoints of '{this.discoveryUrl}'.");
                        var getEndpointsRequest = new GetEndpointsRequest
                        {
                            EndpointUrl = this.discoveryUrl,
                            ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
                        };
                        var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest).ConfigureAwait(false);

                        if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0)
                        {
                            throw new InvalidOperationException($"'{this.discoveryUrl}' returned no endpoints.");
                        }

                        this.RemoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceWarning($"UaTcpSessionClient error discovering endpoints of '{this.discoveryUrl}'. {ex.Message}");
                        throw;
                    }
                }

                // throw here to exit state machine.
                token.ThrowIfCancellationRequested();
                try
                {
                    this.linkToken?.Dispose();
                    Trace.TraceInformation($"UaTcpSessionClient opening channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'.");
                    this.innerChannel = new UaTcpSessionChannel(
                        this.LocalDescription,
                        this.LocalCertificate,
                        this.UserIdentity,
                        this.RemoteEndpoint,
                        this.SessionTimeout,
                        this.TimeoutHint,
                        this.DiagnosticsHint,
                        this.LocalReceiveBufferSize,
                        this.LocalSendBufferSize,
                        this.LocalMaxMessageSize,
                        this.LocalMaxChunkCount);
                    await this.innerChannel.OpenAsync(token).ConfigureAwait(false);

                    this.linkToken = this.pendingRequests.LinkTo(this.innerChannel);

                    // create an internal subscription.
                    this.publishEvent.Subscribe(this.OnPublishResponse, ThreadOption.PublisherThread, false);
                    var subscriptionRequest = new CreateSubscriptionRequest
                    {
                        RequestedPublishingInterval = DefaultPublishingInterval,
                        RequestedMaxKeepAliveCount  = DefaultKeepaliveCount,
                        RequestedLifetimeCount      = (uint)(this.SessionTimeout / DefaultPublishingInterval),
                        PublishingEnabled           = true,
                        Priority = 0
                    };
                    var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

                    this.subscriptionId = subscriptionResponse.SubscriptionId;
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning($"UaTcpSessionClient error opening channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'. {ex.Message}");
                    throw;
                }
            }
            finally
            {
                this.semaphore.Release();
            }
        }