예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Subscription"/> class.
        /// </summary>
        /// <param name="session">The session client.</param>
        /// <param name="target">The target model.</param>
        /// <param name="loggerFactory">The logger factory.</param>
        public Subscription(UaTcpSessionClient session, object target, ILoggerFactory loggerFactory = null)
        {
            this.session         = session;
            this.subscriptionRef = new WeakReference(target);
            this.logger          = loggerFactory?.CreateLogger <Subscription>();

            // get values from [Subscription] attribute.
            var typeInfo = target.GetType().GetTypeInfo();
            var sa       = typeInfo.GetCustomAttribute <SubscriptionAttribute>();

            if (sa != null)
            {
                this.PublishingInterval = sa.PublishingInterval;
                this.KeepAliveCount     = sa.KeepAliveCount;
                this.LifetimeCount      = sa.LifetimeCount;
                this.PublishingEnabled  = sa.PublishingEnabled;
                this.MonitoredItems     = new MonitoredItemCollection(target);
            }

            // register for property change.
            var inpc = target as INotifyPropertyChanged;

            if (inpc != null)
            {
                inpc.PropertyChanged += this.OnPropertyChanged;
            }

            // store this in the shared attached subscriptions list
            attachedSubscriptions.Remove(target);
            attachedSubscriptions.Add(target, this);
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SubscriptionAdapter"/> class.
        /// </summary>
        /// <param name="session">The session client.</param>
        /// <param name="subscription">The ISubscription target.</param>
        public SubscriptionAdapter(UaTcpSessionClient session, ISubscription subscription)
        {
            this.session                       = session;
            this.subscription                  = subscription;
            this.subscription.Session          = session;
            this.subscription.PropertyChanged += this.OnPropertyChanged;
            var publishEvent = this.session.GetEvent <PubSubEvent <PublishResponse> >();

            this.token1 = publishEvent.Subscribe(this.OnPublishResponse, publishEvent.SynchronizationContext != null ? ThreadOption.UIThread : ThreadOption.BackgroundThread, false, this.CanExecutePublishResponse);
            var stateChangedEvent = this.session.GetEvent <PubSubEvent <CommunicationState> >();

            this.token2 = stateChangedEvent.Subscribe(this.OnStateChanged, ThreadOption.BackgroundThread, false);
            this.OnStateChanged(this.session.State);
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Subscription"/> class.
        /// </summary>
        /// <param name="session">The session client.</param>
        /// <param name="publishingInterval">The publishing interval in milliseconds.</param>
        /// <param name="keepAliveCount">The number of PublishingIntervals before the server should return an empty Publish response.</param>
        /// <param name="lifetimeCount">The number of PublishingIntervals before the server should delete the subscription. Set '0' to use session's lifetime.</param>
        /// <param name="maxNotificationsPerPublish">The maximum number of notifications per publish request. Set '0' to use no limit.</param>
        /// <param name="priority">The priority assigned to subscription.</param>
        public Subscription(UaTcpSessionClient session = null, double publishingInterval = 1000f, uint keepAliveCount = 10, uint lifetimeCount = 0, uint maxNotificationsPerPublish = 0, byte priority = 0)
        {
            this.Session                    = session;
            this.PublishingInterval         = publishingInterval;
            this.KeepAliveCount             = keepAliveCount;
            this.LifetimeCount              = lifetimeCount;
            this.MaxNotificationsPerPublish = maxNotificationsPerPublish;
            this.MonitoredItems             = new MonitoredItemCollection(this);
            this.PropertyChanged           += this.OnPropertyChanged;

            // subscribe to data change and event notifications.
            if (session != null)
            {
                var publishEvent = session.GetEvent <PubSubEvent <PublishResponse> >();
                this.token1 = publishEvent.Subscribe(this.OnPublishResponse, ThreadOption.PublisherThread, false);
                var stateChangedEvent = session.GetEvent <PubSubEvent <CommunicationState> >();
                this.token2 = stateChangedEvent.Subscribe(this.OnStateChanged, ThreadOption.PublisherThread, false);
                this.OnStateChanged(session.State);
            }
        }
예제 #4
0
        public async Task ConnnectToAllEndpoints()
        {
            // get or add application certificate.
            var localCertificate = this.localDescription.GetCertificate();
            if (localCertificate == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing.");
            }

            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = this.endpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };
            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryClient.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.UserName:
                            selectedUserIdentity = new UserNameIdentity("root", "secret");
                            break;

                        case UserTokenType.Certificate:
                            selectedUserIdentity = new X509Identity(localCertificate);
                            break;

                        default:
                            selectedUserIdentity = new AnonymousIdentity();
                            break;
                    }

                    var client = new UaTcpSessionClient(
                        this.localDescription,
                        localCertificate,
                        selectedUserIdentity,
                        selectedEndpoint);
                    Console.WriteLine($"Creating session with endpoint '{client.RemoteEndpoint.EndpointUrl}'.");
                    Console.WriteLine($"SecurityPolicy: '{client.RemoteEndpoint.SecurityPolicyUri}'.");
                    Console.WriteLine($"SecurityMode: '{client.RemoteEndpoint.SecurityMode}'.");
                    Console.WriteLine($"UserIdentityToken: '{client.UserIdentity}'.");
                    try
                    {
                        await client.OpenAsync();
                        Console.WriteLine($"Closing session '{client.SessionId}'.");
                        await client.CloseAsync();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error opening session '{client.SessionId}'. {ex.Message}");
                    }
                }
            }
        }
예제 #5
0
        public async Task TransferSubscriptions()
        {
            // get or add application certificate.
            var localCertificate = this.localDescription.GetCertificate();
            if (localCertificate == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing.");
            }

            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = this.endpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };
            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest);
            var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();

            IUserIdentity selectedUserIdentity = new UserNameIdentity("root", "secret");

            var client = new UaTcpSessionClient(
                this.localDescription,
                localCertificate,
                selectedUserIdentity,
                selectedEndpoint);
            Console.WriteLine($"Creating session with endpoint '{client.RemoteEndpoint.EndpointUrl}'.");
            Console.WriteLine($"SecurityPolicy: '{client.RemoteEndpoint.SecurityPolicyUri}'.");
            Console.WriteLine($"SecurityMode: '{client.RemoteEndpoint.SecurityMode}'.");
            await client.OpenAsync();
            Console.WriteLine($"Activated session '{client.SessionId}'.");
            var req = new CreateSubscriptionRequest
            {
                RequestedPublishingInterval = 1000,
                RequestedMaxKeepAliveCount = 20,
                PublishingEnabled = true
            };
            var res = await client.CreateSubscriptionAsync(req);
            Console.WriteLine($"Created subscription '{res.SubscriptionId}'.");

            Console.WriteLine($"Aborting session '{client.SessionId}'.");
            await client.AbortAsync();

            var client2 = new UaTcpSessionClient(
                this.localDescription,
                localCertificate,
                selectedUserIdentity,
                selectedEndpoint);
            await client2.OpenAsync();
            Console.WriteLine($"Activated session '{client2.SessionId}'.");

            var req2 = new TransferSubscriptionsRequest
            {
                SubscriptionIds = new[] { res.SubscriptionId }
            };
            var res2 = await client2.TransferSubscriptionsAsync(req2);
            Console.WriteLine($"Transferred subscription result '{res2.Results[0].StatusCode}'.");

            Assert.IsTrue(StatusCode.IsGood(res2.Results[0].StatusCode));

            Console.WriteLine($"Closing session '{client2.SessionId}'.");
            await client2.CloseAsync();
        }
예제 #6
0
        public async Task SessionTimeoutCausesFault()
        {
            // get or add application certificate.
            var localCertificate = this.localDescription.GetCertificate();
            if (localCertificate == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing.");
            }

            // discover available endpoints of server.
            var getEndpointsRequest = new GetEndpointsRequest
            {
                EndpointUrl = this.endpointUrl,
                ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
            };
            Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'.");
            var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest);
            var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last();

            var selectedTokenType = selectedEndpoint.UserIdentityTokens[0].TokenType;
            IUserIdentity selectedUserIdentity;
            switch (selectedTokenType)
            {
                case UserTokenType.UserName:
                    selectedUserIdentity = new UserNameIdentity("root", "secret");
                    break;

                case UserTokenType.Certificate:
                    selectedUserIdentity = new X509Identity(localCertificate);
                    break;

                default:
                    selectedUserIdentity = new AnonymousIdentity();
                    break;
            }

            var client = new UaTcpSessionClient(
                this.localDescription,
                localCertificate,
                selectedUserIdentity,
                selectedEndpoint)
            {
                SessionTimeout = 10000
            };
            Console.WriteLine($"Creating session with endpoint '{client.RemoteEndpoint.EndpointUrl}'.");
            Console.WriteLine($"SecurityPolicy: '{client.RemoteEndpoint.SecurityPolicyUri}'.");
            Console.WriteLine($"SecurityMode: '{client.RemoteEndpoint.SecurityMode}'.");
            await client.OpenAsync();
            Console.WriteLine($"Activated session '{client.SessionId}'.");

            // server should close session due to inactivity
            await Task.Delay(20000);

            // should throw exception
            var readRequest = new ReadRequest { NodesToRead = new[] { new ReadValueId { NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime), AttributeId = AttributeIds.Value } } };
            await client.ReadAsync(readRequest);

            Console.WriteLine($"Closing session '{client.SessionId}'.");
            await client.CloseAsync();
        }