/// <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); }
/// <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); }
/// <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); } }
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}"); } } } }
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(); }
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(); }