예제 #1
0
        public async Task TryConnectAsync()
        {
            await _mutex.WaitAsync(_cancellationToken).ConfigureAwait(false);

            try
            {
                if (Connected)
                {
                    return;
                }
                try
                {
                    var endpointDescription = await GetEndpointAsync(EndpointUrl, true).ConfigureAwait(false);

                    ConfiguredEndpoint.Update(endpointDescription);
                    ConfiguredEndpoint.Configuration.UseBinaryEncoding = endpointDescription.EncodingSupport == BinaryEncodingSupport.Optional || endpointDescription.EncodingSupport == BinaryEncodingSupport.Required;
                    TransportChannel = SessionChannel.Create(Configuration, ConfiguredEndpoint.Description, ConfiguredEndpoint.Configuration, Configuration.SecurityConfiguration.ApplicationCertificate.Certificate, Configuration.CreateMessageContext());
                    Open(_sessionName, null);
                    NotifyPropertyChanged("Connected");
                    Trace.TraceInformation("Success connecting to endpoint '{0}'. ", ConfiguredEndpoint);
                }
                catch (ServiceResultException ex)
                {
                    Trace.TraceError("Error connecting to endpoint '{0}'. {1}", ConfiguredEndpoint, ex.Message);
                }
            }
            finally
            {
                _mutex.Release();
            }
        }
예제 #2
0
        private async Task <Session> GetSessionAsync(string serverUrl)
        {
            lock (_sessions)
            {
                if (_sessions.ContainsKey(serverUrl))
                {
                    return(_sessions[serverUrl]);
                }
            }

            await CheckAndLoadConfiguration();

            EndpointDescription endpointDescription;

            try
            {
                endpointDescription = CoreClientUtils.SelectEndpoint(serverUrl, true, 15000);
            }
            catch (Exception)
            {
                throw new DataSetNotAvailableException();
            }

            Console.WriteLine("    Selected endpoint uses: {0}",
                              endpointDescription.SecurityPolicyUri.Substring(endpointDescription.SecurityPolicyUri.LastIndexOf('#') + 1));

            var endpointConfiguration = EndpointConfiguration.Create(_appConfiguration);

            var endpoint = new ConfiguredEndpoint(endpointDescription.Server, endpointConfiguration);

            endpoint.Update(endpointDescription);

            var s = await Session.Create(_appConfiguration,
                                         endpoint,
                                         true,
                                         false,
                                         _appConfiguration.ApplicationName + "_session",
                                         (uint)_appConfiguration.ClientConfiguration.DefaultSessionTimeout,
                                         null,
                                         null);

            lock (_sessions)
            {
                if (_sessions.ContainsKey(serverUrl))
                {
                    s = _sessions[serverUrl];
                }
                else
                {
                    _sessions.Add(serverUrl, s);
                }
            }

            return(s);
        }
예제 #3
0
        /// <summary>
        /// Creates a new session
        /// </summary>
        /// <param name="identity"></param>
        /// <returns></returns>
        private async Task <Session> CreateSessionAsync(IUserIdentity identity)
        {
            if (_connection.Endpoint.SecurityMode != SecurityMode.SignAndEncrypt)
            {
                _logger.Warning("Establishing unencrypted connection.");
            }
            if (_urlQueue.TryDequeue(out var next))
            {
                if (_endpointUrl != null && _endpointUrl != next)
                {
                    _urlQueue.Enqueue(_endpointUrl);
                }
                _endpointUrl = next;
                _logger.Information("Creating session via {endpoint}.", _endpointUrl);
            }
            var selectedEndpoint = await DiscoverEndpointsAsync(_config,
                                                                _connection.Endpoint, new Uri(_endpointUrl), (server, endpoints, channel) =>
                                                                SelectServerEndpoint(server, endpoints, channel, true));

            if (selectedEndpoint == null)
            {
                throw new ConnectionException(
                          $"Unable to select secure endpoint on {_connection.Endpoint.Url} via {_endpointUrl}");
            }

            var configuredEndpoint = new ConfiguredEndpoint(selectedEndpoint.Server,
                                                            EndpointConfiguration.Create(_config));

            configuredEndpoint.Update(selectedEndpoint);

            var session = await Session.Create(_config, configuredEndpoint, true, false,
                                               _sessionName, (uint)(_timeout.TotalMilliseconds * 1.2), identity, null);

            if (session == null)
            {
                throw new ExternalDependencyException(
                          $"Cannot establish session to {_connection.Endpoint.Url} via {_endpointUrl}.");
            }
            session.KeepAlive         += (_, e) => e.CancelKeepAlive = true;
            session.KeepAliveInterval  = -1;                    // No keep alives - we handle those ourselves.
            session.RenewUserIdentity += (_, user) => identity; // Reset back to default.

            try {
                var complexTypeSystem = new ComplexTypeSystem(session);
                await complexTypeSystem.Load();
            }
            catch (Exception ex) {
                _logger.Error(ex, "Failed to load complex type system");
            }
            return(session);
        }
예제 #4
0
        public async Task <ConnectionStatus> OpcClient(string endpointURL)
        {
            try
            {
                Uri endpointURI      = new Uri(endpointURL);
                var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate, 15000);

                info.LabelText = "Selected endpoint uses: " + selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1);

                var endpointConfiguration = EndpointConfiguration.Create(config);
                var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
                endpoint.Update(selectedEndpoint);

                var platform    = Device.RuntimePlatform;
                var sessionName = "";

                switch (Device.RuntimePlatform)
                {
                case "Android":
                    sessionName = "OPC UA Xamarin Client Android";
                    break;

                case "UWP":
                    sessionName = "OPC UA Xamarin Client UWP";
                    break;

                case "iOS":
                    sessionName = "OPC UA Xamarin Client IOS";
                    break;
                }
                session = await Session.Create(config, endpoint, false, sessionName, 60000, new UserIdentity(new AnonymousIdentityToken()), null);


                if (session != null)
                {
                    connectionStatus = ConnectionStatus.Connected;
                }
                else
                {
                    connectionStatus = ConnectionStatus.NotConnected;
                }
                // register keep alive handler
                session.KeepAlive += Client_KeepAlive;
            }
            catch
            {
                connectionStatus = ConnectionStatus.Error;
            }
            return(connectionStatus);
        }
예제 #5
0
        private static void securelyUpdateEndpointConfiguration(ConfiguredEndpoint ep, ApplicationConfiguration applicationConfiguration)
        {
            // ep.UpdateFromServer(...) looks for matching endpoints on the server.
            // If there is no match with the same securityMode and securityPolicy, it will simply
            // _replace_ ep by one of the server endpoints, possibly lowering the security settings. Therefore:
            // save old settings - update from server - verify security settings -- and throw update from server away if security settings have changed.
            // note that ConfiguredEndpoints need a collection to live in. Note also that some settings of the configured endpoint may be changed nonetheless behind the scenes.
            ConfiguredEndpointCollection cepc = new ConfiguredEndpointCollection();
            EndpointDescription          epd  = (EndpointDescription)ep.Description.Clone();
            ConfiguredEndpoint           cep  = new ConfiguredEndpoint(cepc, epd);

            Opc.Ua.BindingFactory bindingFactory = BindingFactory.Create(applicationConfiguration, applicationConfiguration.CreateMessageContext());
            ep.UpdateFromServer(bindingFactory);

            if (ep.Description.SecurityMode != epd.SecurityMode || ep.Description.SecurityPolicyUri != epd.SecurityPolicyUri)
            {
                ep.Update(cep);
                throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "No endpoint with matching security configuration could be found during updated on connect.");
            }
        }
예제 #6
0
        /// <summary>
        /// Connects to a single OPC UA Server's endpoint
        /// </summary>
        public static async Task EndpointConnect(Uri endpointUrl)
        {
            EndpointDescription selectedEndpoint   = CoreClientUtils.SelectEndpoint(endpointUrl.AbsoluteUri, true);
            ConfiguredEndpoint  configuredEndpoint = new ConfiguredEndpoint(selectedEndpoint.Server, EndpointConfiguration.Create(m_configuration));

            configuredEndpoint.Update(selectedEndpoint);

            Session newSession = await Session.Create(
                m_configuration,
                configuredEndpoint,
                true,
                false,
                m_configuration.ApplicationName,
                60000,
                new UserIdentity(new AnonymousIdentityToken()),
                null);

            if (newSession != null)
            {
                Trace("Created session with updated endpoint " + selectedEndpoint.EndpointUrl + " from server!");
                newSession.KeepAlive += new KeepAliveEventHandler((sender, e) => StandardClient_KeepAlive(sender, e, newSession));
                m_sessions.Add(newSession);
            }
        }
예제 #7
0
        /// <summary>
        /// Connects to a single OPC UA Server's endpoint
        /// </summary>
        public static async Task EndpointConnect(Uri endpointUrl)
        {
            EndpointDescription selectedEndpoint   = SelectUaTcpEndpoint(DiscoverEndpoints(m_configuration, endpointUrl, 10));
            ConfiguredEndpoint  configuredEndpoint = new ConfiguredEndpoint(selectedEndpoint.Server, EndpointConfiguration.Create(m_configuration));

            configuredEndpoint.Update(selectedEndpoint);

            Session newSession = await Session.Create(
                m_configuration,
                configuredEndpoint,
                true,
                false,
                m_configuration.ApplicationName,
                60000,
                new UserIdentity(new AnonymousIdentityToken()),
                null);

            if (newSession != null)
            {
                Trace("Opc.Ua.Publisher.Module: Created session with updated endpoint " + selectedEndpoint.EndpointUrl + " from server!");
                newSession.KeepAlive += new KeepAliveEventHandler((sender, e) => StandardClient_KeepAlive(sender, e, newSession));
                m_sessions.Add(newSession);
            }
        }
예제 #8
0
        static async Task ConsoleSampleClient(string endpointURL, Op op, int count)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration {
                ApplicationName       = "UA Core Sample Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration {
                    ApplicationCertificate = new CertificateIdentifier {
                        StoreType   = "Directory",
                        StorePath   = "OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 120000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 120000
                }
            };

            await config.Validate(ApplicationType.Client);

            var haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                var certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += CertificateValidator_CertificateValidation;
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            var reconnectLoops = op == Op.All ? 1 : count;

            for (var i = 1; i <= reconnectLoops; i++)
            {
                Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
                var endpointURI        = new Uri(endpointURL);
                var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
                var selectedEndpoint   = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);
                Console.WriteLine("    Selected endpoint uses: {0}",
                                  selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

                Console.WriteLine("3 - Create session with OPC UA server.");
                var endpointConfiguration = EndpointConfiguration.Create(config);
                var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
                endpoint.Update(selectedEndpoint);
                var session = await CreateSessionAsync(config, endpoint);

                if (op == Op.All || op == Op.Browse)
                {
                    Console.WriteLine("4 - Browse the OPC UA server namespace.");
                    var j = 0;

                    while (true)
                    {
                        var w = Stopwatch.StartNew();

                        var stack = new Stack <Tuple <string, ReferenceDescription> >();
                        session.Browse(
                            null,
                            null,
                            ObjectIds.ObjectsFolder,
                            0u,
                            BrowseDirection.Forward,
                            ReferenceTypeIds.HierarchicalReferences,
                            true,
                            (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                            out var continuationPoint,
                            out var references);

                        Console.WriteLine(" DisplayName, BrowseName, NodeClass");
                        references.Reverse();
                        foreach (var rd in references)
                        {
                            stack.Push(Tuple.Create("", rd));
                        }

                        while (stack.Count > 0)
                        {
                            var browsed = stack.Pop();
                            session.Browse(
                                null,
                                null,
                                ExpandedNodeId.ToNodeId(browsed.Item2.NodeId, session.NamespaceUris),
                                0u,
                                BrowseDirection.Forward,
                                ReferenceTypeIds.HierarchicalReferences,
                                true,
                                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                                out continuationPoint,
                                out references);

                            references.Reverse();
                            foreach (var rd in references)
                            {
                                stack.Push(Tuple.Create(browsed.Item1 + "   ", rd));
                            }
                            Console.WriteLine($"{browsed.Item1}{(references.Count == 0 ? "-" : "+")} " +
                                              $"{browsed.Item2.DisplayName}, {browsed.Item2.BrowseName}, {browsed.Item2.NodeClass}");
                        }
                        Console.WriteLine($"   ....        took {w.ElapsedMilliseconds} ms...");
                        if (++j <= count)
                        {
                            break;
                        }

                        // Reconnect
                        session.Close();
                        session = await CreateSessionAsync(config, endpoint);
                    }
                }

                if (op == Op.All || op == Op.Subscribe)
                {
                    Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
                    var subscription = new Subscription(session.DefaultSubscription)
                    {
                        PublishingInterval = 1000
                    };

                    Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
                    var list = new List <MonitoredItem> {
                        new MonitoredItem(subscription.DefaultItem)
                        {
                            DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                        }
                    };
                    list.ForEach(m => m.Notification += OnNotification);
                    subscription.AddItems(list);

                    Console.WriteLine("7 - Add the subscription to the session.");
                    session.AddSubscription(subscription);
                    subscription.Create();

                    await Task.Delay(1000 *(count + 1));

                    subscription.Delete(false);
                    subscription.Dispose();
                }

                session.Close();
            }
        }
예제 #9
0
        /// <summary>
        /// Checks if there is an active OPC UA session for the provided browser session. If the persisted OPC UA session does not exist,
        /// a new OPC UA session to the given endpoint URL is established.
        /// </summary>
        public async Task <Session> GetSessionAsync(string sessionID, string endpointURL)
        {
            if (string.IsNullOrEmpty(sessionID) || string.IsNullOrEmpty(endpointURL))
            {
                return(null);
            }

            OpcSessionCacheData entry;

            if (OpcSessionCache.TryGetValue(sessionID, out entry))
            {
                if (entry.OPCSession != null)
                {
                    if (entry.OPCSession.Connected)
                    {
                        return(entry.OPCSession);
                    }

                    try
                    {
                        entry.OPCSession.Close(500);
                    }
                    catch
                    {
                    }
                    entry.OPCSession = null;
                }
            }
            else
            {
                // create a new entry
                OpcSessionCacheData newEntry = new OpcSessionCacheData {
                    EndpointURL = endpointURL
                };
                OpcSessionCache.TryAdd(sessionID, newEntry);
            }

            Uri endpointURI = new Uri(endpointURL);
            EndpointDescriptionCollection endpointCollection    = DiscoverEndpoints(_configuration, endpointURI, 10);
            EndpointDescription           selectedEndpoint      = SelectUaTcpEndpoint(endpointCollection);
            EndpointConfiguration         endpointConfiguration = EndpointConfiguration.Create(_configuration);
            ConfiguredEndpoint            endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);

            endpoint.Update(selectedEndpoint);

            // Check if we have a cached endpoint with the same URL and use that one instead
            foreach (ConfiguredEndpoint cachedEndpoint in OpcCachedEndpoints)
            {
                if (cachedEndpoint.EndpointUrl.AbsoluteUri.Equals(endpointURL, StringComparison.InvariantCultureIgnoreCase))
                {
                    endpoint = cachedEndpoint;
                    break;
                }
            }

            Session session = await Session.Create(
                _configuration,
                endpoint,
                true,
                false,
                sessionID,
                60000,
                new UserIdentity(new AnonymousIdentityToken()),
                null);

            if (session != null)
            {
                session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);

                // Update our cache data
                if (OpcSessionCache.TryGetValue(sessionID, out entry))
                {
                    if (string.Equals(entry.EndpointURL, endpointURL, StringComparison.InvariantCultureIgnoreCase))
                    {
                        OpcSessionCacheData newValue = new OpcSessionCacheData
                        {
                            CertThumbprint = entry.CertThumbprint,
                            EndpointURL    = entry.EndpointURL,
                            Trusted        = entry.Trusted,
                            OPCSession     = session
                        };
                        OpcSessionCache.TryUpdate(sessionID, newValue, entry);
                    }
                }
            }

            return(session);
        }
예제 #10
0
        /// <summary>
        /// Подключение к OPC-серверу по его адресу. Выполняется асинхронно.
        /// </summary>
        /// <param name="ep">Адрес OPC-сервера</param>
        /// <returns></returns>
        public async Task Connect(string endpointUrl)
        {
            _config = new ApplicationConfiguration()
            {
                ApplicationName       = "Console OPC-Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:localhost:OPCFoundation:SampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = "Directory",
                        StorePath   = "./OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = Utils.Format("CN={0}, DC={1}", "Console OPC-Client", Utils.GetHostName())
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "./OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "./OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "./OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 15000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 60000
                }
            };
            await _config.Validate(ApplicationType.Client);

            _haveAppCertificate = _config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (_haveAppCertificate && _config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
            {
                _config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            }

            Uri endpointURI           = new Uri(endpointUrl);
            var endpointCollection    = DiscoverEndpoints(_config, endpointURI, 10);
            var selectedEndpoint      = SelectUaTcpEndpoint(endpointCollection, _haveAppCertificate);
            var endpointConfiguration = EndpointConfiguration.Create(_config);
            var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);

            endpoint.Update(selectedEndpoint);

            _session = await Session.Create(_config, endpoint, true, "Console OPC Client", 60000, null, null);

            _subscription = new Subscription(_session.DefaultSubscription)
            {
                PublishingInterval = 1000
            };
        }
        public async Task <ConnectionStatus> OpcClient(string endpointURL)
        {
            try
            {
                Uri endpointURI      = new Uri(endpointURL);
                var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, false, 15000);

                info.LabelText = "Selected endpoint uses: " + selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1);

                var endpointConfiguration = EndpointConfiguration.Create(config);
                var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
                endpoint.Update(selectedEndpoint);

                var platform    = Device.RuntimePlatform;
                var sessionName = "";

                switch (Device.RuntimePlatform)
                {
                case "Android":
                    sessionName = "AIS Demonstrator Android Applikation";
                    break;

                // other cases are irrelevant for the Industrie 4.0 Demonstrator as of now
                case "UWP":
                    sessionName = "OPC UA Xamarin Client UWP";
                    break;

                case "iOS":
                    sessionName = "OPC UA Xamarin Client IOS";
                    break;
                }
                #region OPC UA User Authentication handling

                /*
                 * Partially copied from https://github.com/OPCFoundation/UA-.NETStandard/issues/446
                 */
                UserTokenPolicy utp = new UserTokenPolicy();
                utp.TokenType = UserTokenType.UserName;

                UserTokenPolicyCollection utpCollection = new UserTokenPolicyCollection();
                utpCollection.Add(utp);
                selectedEndpoint.UserIdentityTokens = utpCollection;
                selectedEndpoint.SecurityMode       = MessageSecurityMode.SignAndEncrypt;
                UserIdentity SessionUserIdentity = new UserIdentity(MainActivity.UserName, MainActivity.UserPassword);

                #endregion
                session = await Session.Create(config, endpoint, false, sessionName, 30000, SessionUserIdentity, null);


                if (session != null)
                {
                    connectionStatus = ConnectionStatus.Connected;

                    #region Subscription + monitoredItems
                    // Code for Monitored Items based on http://opcfoundation.github.io/UA-.NETStandard/help/index.htm#client_development.htm

                    // Create Subscription
                    Subscription subscription = new Subscription() // new Subscription(OpcClient.session.DefaultSubscription)
                    {
                        PublishingInterval = 1000,
                        PublishingEnabled  = true
                    };
                    // CoffeeLevel
                    MonitoredItem CoffeeLevel = new MonitoredItem(subscription.DefaultItem)
                    {
                        StartNodeId      = "ns=1;s=CoffeeLevel",
                        DisplayName      = "MonitoredCoffeeLevel",
                        AttributeId      = Attributes.Value,
                        MonitoringMode   = MonitoringMode.Reporting,
                        SamplingInterval = 1000, // check the CoffeeLevel every second
                        QueueSize        = 1,    // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one
                        DiscardOldest    = true  // we only need the most recent value for CoffeeLevel
                    };
                    CoffeeLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueCoffeeLevel);

                    // WaterLevel
                    MonitoredItem WaterLevel = new MonitoredItem(subscription.DefaultItem)
                    {
                        StartNodeId      = "ns=1;s=WaterLevel",
                        DisplayName      = "MonitoredWaterLevel",
                        AttributeId      = Attributes.Value,
                        MonitoringMode   = MonitoringMode.Reporting,
                        SamplingInterval = 1000, // check the CoffeeLevel every second
                        QueueSize        = 1,    // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one
                        DiscardOldest    = true  // we only need the most recent value for CoffeeLevel
                    };
                    WaterLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueWaterLevel);

                    // CleanlinessLevel
                    MonitoredItem CleanlinessLevel = new MonitoredItem(subscription.DefaultItem)
                    {
                        StartNodeId      = "ns=1;s=Cleanliness",
                        DisplayName      = "MonitoredCleanlinessLevel",
                        AttributeId      = Attributes.Value,
                        MonitoringMode   = MonitoringMode.Reporting,
                        SamplingInterval = 1000, // check the CoffeeLevel every second
                        QueueSize        = 1,    // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one
                        DiscardOldest    = true  // we only need the most recent value for CoffeeLevel
                    };
                    CleanlinessLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueCleanlinessLevel);

                    // add MonitoredItems to Subscription
                    subscription.AddItem(CoffeeLevel);
                    subscription.AddItem(WaterLevel);
                    subscription.AddItem(CleanlinessLevel);

                    // add Subscription to Session
                    session.AddSubscription(subscription);
                    subscription.Create();

                    #endregion
                }
                else
                {
                    connectionStatus = ConnectionStatus.NotConnected;
                }
                // register keep alive handler
                session.KeepAlive += Client_KeepAlive;
            }
            catch
            {
                connectionStatus = ConnectionStatus.Error;
            }
            return(connectionStatus);
        }
예제 #12
0
        public async Task ConnectAndMonitor()
        {
            _opcSessionSemaphore.Wait();
            Trace($"Connect and monitor session and nodes on endpoint '{EndpointUri.AbsoluteUri}'.");
            try
            {
                // if the session is disconnected, create it.
                if (State == SessionState.Disconnected)
                {
                    EndpointDescription selectedEndpoint   = CoreClientUtils.SelectEndpoint(EndpointUri.AbsoluteUri, true);
                    ConfiguredEndpoint  configuredEndpoint = new ConfiguredEndpoint(selectedEndpoint.Server, EndpointConfiguration.Create(OpcConfiguration));
                    configuredEndpoint.Update(selectedEndpoint);

                    try
                    {
                        uint timeout = SessionTimeout * ((UnsuccessfulConnectionCount >= OpcSessionCreationBackoffMax) ? OpcSessionCreationBackoffMax : UnsuccessfulConnectionCount + 1);
                        Trace($"Create session for endpoint URI '{EndpointUri.AbsoluteUri}' with timeout of {timeout} ms.");
                        Session = await Session.Create(
                            OpcConfiguration,
                            configuredEndpoint,
                            true,
                            false,
                            OpcConfiguration.ApplicationName,
                            timeout,
                            new UserIdentity(new AnonymousIdentityToken()),
                            null);

                        if (Session != null)
                        {
                            Trace($"Session successfully created with Id {Session.SessionId}.");
                            if (!selectedEndpoint.EndpointUrl.Equals(configuredEndpoint.EndpointUrl))
                            {
                                Trace($"the Server has updated the EndpointUrl to '{selectedEndpoint.EndpointUrl}'");
                            }

                            // init object state and install keep alive
                            UnsuccessfulConnectionCount = 0;
                            State = SessionState.Connected;
                            Session.KeepAliveInterval = OpcKeepAliveIntervalInSec * 1000;
                            Session.KeepAlive        += new KeepAliveEventHandler((sender, e) => StandardClient_KeepAlive(sender, e, Session));

                            // fetch the namespace array and cache it. it will not change as long the session exists.
                            NodeId    namespaceArrayNodeId    = new NodeId(Variables.Server_NamespaceArray, 0);
                            DataValue namespaceArrayNodeValue = Session.ReadValue(namespaceArrayNodeId);
                            _namespaceTable.Update(namespaceArrayNodeValue.GetValue <string[]>(null));

                            // show the available namespaces
                            Trace($"The session to endpoint '{selectedEndpoint.EndpointUrl}' has {_namespaceTable.Count} entries in its namespace array:");
                            int i = 0;
                            foreach (var ns in _namespaceTable.ToArray())
                            {
                                Trace($"Namespace index {i++}: {ns}");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Trace(e, $"Session creation to endpoint '{EndpointUri.AbsoluteUri}' failed {++UnsuccessfulConnectionCount} time(s). Please verify if server is up and Publisher configuration is correct.");
                        State   = SessionState.Disconnected;
                        Session = null;
                        return;
                    }
                }

                // stop monitoring of nodes if requested and remove them from the monitored items list.
                var itemsToRemove = MonitoredItemsInfo.Where(i => i.State == MonitoredItemInfo.MonitoredItemState.StopMonitoring);
                if (itemsToRemove.GetEnumerator().MoveNext())
                {
                    itemsToRemove.GetEnumerator().Reset();
                    Trace($"Remove nodes on endpoint '{EndpointUri.AbsoluteUri}'");
                    Session.DefaultSubscription.RemoveItems(itemsToRemove.Select(i => i.MonitoredItem));
                }

                // ensure all nodes on this session are monitored.
                Trace($"Start monitoring nodes on endpoint '{EndpointUri.AbsoluteUri}'");
                var unmonitoredItems = MonitoredItemsInfo.Where(i => i.State == MonitoredItemInfo.MonitoredItemState.Unmonitored);
                foreach (var item in unmonitoredItems)
                {
                    // if the session is disconnected, we stop trying and wait for the next cycle
                    if (State == SessionState.Disconnected)
                    {
                        break;
                    }

                    NodeId currentNodeId;
                    try
                    {
                        Subscription subscription = Session.DefaultSubscription;
                        if (Session.AddSubscription(subscription))
                        {
                            Trace("Create default subscription.");
                            subscription.Create();
                        }

                        // lookup namespace index if ExpandedNodeId format has been used and build NodeId identifier.
                        if (!string.IsNullOrEmpty(item.StartNodeId.NamespaceUri))
                        {
                            currentNodeId = NodeId.Create(item.StartNodeId.Identifier, item.StartNodeId.NamespaceUri, _namespaceTable);
                        }
                        else
                        {
                            currentNodeId = new NodeId((NodeId)item.StartNodeId);
                        }

                        // get the DisplayName for the node, otherwise use the nodeId
                        Node node = Session.ReadNode(currentNodeId);
                        item.DisplayName = node.DisplayName.Text ?? currentNodeId.ToString();

                        // add the new monitored item.
                        MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem)
                        {
                            StartNodeId      = currentNodeId,
                            AttributeId      = item.AttributeId,
                            DisplayName      = node.DisplayName.Text,
                            MonitoringMode   = item.MonitoringMode,
                            SamplingInterval = item.SamplingInterval,
                            QueueSize        = item.QueueSize,
                            DiscardOldest    = item.DiscardOldest
                        };
                        monitoredItem.Notification += item.Notification;
                        subscription.AddItem(monitoredItem);
                        subscription.ApplyChanges();
                        item.MonitoredItem = monitoredItem;
                        item.State         = MonitoredItemInfo.MonitoredItemState.Monitoreded;
                        item.EndpointUri   = EndpointUri;
                        Trace($"Created monitored item for node '{currentNodeId}' on endpoint '{EndpointUri.AbsoluteUri}'");
                    }
                    catch (Exception e) when(e.GetType() == typeof(ServiceResultException))
                    {
                        ServiceResultException sre = (ServiceResultException)e;

                        switch ((uint)sre.Result.StatusCode)
                        {
                        case StatusCodes.BadSessionIdInvalid:
                        {
                            Trace($"Session with Id {Session.SessionId} is no longer available on endpoint '{EndpointUri}'. Cleaning up.");
                            // clean up the session
                            _opcSessionSemaphore.Release();
                            Disconnect();
                            break;
                        }

                        case StatusCodes.BadNodeIdInvalid:
                        case StatusCodes.BadNodeIdUnknown:
                        {
                            Trace($"Failed to monitor node '{item.StartNodeId.Identifier}' on endpoint '{EndpointUri}'.");
                            Trace($"OPC UA ServiceResultException is '{sre.Result}'. Please check your publisher configuration for this node.");
                            break;
                        }

                        default:
                        {
                            Trace($"Unhandled OPC UA ServiceResultException '{sre.Result}' when monitoring node '{item.StartNodeId.Identifier}' on endpoint '{EndpointUri}'. Continue.");
                            break;
                        }
                        }
                    }
                    catch (Exception e)
                    {
                        Trace(e, $"Failed to monitor node '{item.StartNodeId.Identifier}' on endpoint '{EndpointUri}'");
                    }
                }

                // shutdown unused sessions.
                var unusedSessions = OpcSessions.Where(s => s.MonitoredItemsInfo.Count == 0);
                foreach (var unusedSession in unusedSessions)
                {
                    await unusedSession.Shutdown();

                    OpcSessions.Remove(unusedSession);
                }
            }
            finally
            {
                _opcSessionSemaphore.Release();
            }
        }
예제 #13
0
        public async Task EndpointConnect()
        {
            var endpointCollection = DiscoverEndpoints(Module.Configuration, ServerUrl, 60);
            var selectedEndpoints  = new List <EndpointDescription>();

            // Select endpoints
            foreach (EndpointDescription endpoint in endpointCollection)
            {
                if (endpoint.TransportProfileUri == Profiles.UaTcpTransport &&
                    endpoint.SecurityLevel >= MinimumSecurityLevel &&
                    endpoint.SecurityMode >= MinimumSecurityMode)
                {
                    // patch endpoint to set the original host name we want to connect to.
                    var url = new UriBuilder(endpoint.EndpointUrl);
                    url.Host             = ServerUrl.Host;
                    endpoint.EndpointUrl = url.ToString();
                    selectedEndpoints.Add(endpoint);
                }
            }

            //
            // Sort, but descending with highest level first i.e. return
            // < 0 if x is less than y
            // > 0 if x is greater than y
            //   0 if x and y are equal
            //
            selectedEndpoints.Sort((y, x) => x.SecurityLevel - y.SecurityLevel);

            // Do not emit all exceptions as they occur, only throw them all when no connection can be made.
            var exceptions = new List <Exception>(selectedEndpoints.Count);

            foreach (EndpointDescription endpoint in selectedEndpoints)
            {
                ConfiguredEndpoint configuredEndpoint = new ConfiguredEndpoint(
                    endpoint.Server, EndpointConfiguration.Create(Module.Configuration));
                configuredEndpoint.Update(endpoint);
                try
                {
                    Console.WriteLine($"Opc.Ua.Client.SampleModule: Trying to create session with mode: {endpoint.SecurityMode}, level:{endpoint.SecurityLevel} to {configuredEndpoint.EndpointUrl}...");
                    _session = await Session.Create(
                        Module.Configuration,
                        configuredEndpoint,
                        true,
                        false,
                        Module.Configuration.ApplicationName,
                        60000,
                        // TODO: Make user identity configurable, plus add dedicated security policy
                        new UserIdentity(new AnonymousIdentityToken()),
                        null);

                    if (_session != null)
                    {
                        var subscription = new Subscription(_session.DefaultSubscription);
                        subscription.PublishingInterval = PublishingInterval;

                        // TODO: Make other subscription settings configurable...
                        subscription.AddItems(MonitoredItems);
                        _session.AddSubscription(subscription);
                        subscription.Create();

                        Console.WriteLine($"Opc.Ua.Client.SampleModule: Session with mode: {endpoint.SecurityMode}, level:{endpoint.SecurityLevel} to {configuredEndpoint.EndpointUrl} established!");
                        _session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);

                        // Done
                        return;
                    }
                    exceptions.Add(new Exception($"ERROR: Create session to endpoint {endpoint.ToString()} returned null."));
                }
                catch (AggregateException ae)
                {
                    exceptions.AddRange(ae.InnerExceptions);
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                }

                //  ... try another endpoint until we do not have any more...
                Console.WriteLine($"Opc.Ua.Client.SampleModule: WARNING Could not create session to endpoint {endpoint.ToString()}...");
            }
            throw new AggregateException("Failed to find acceptable endpoint to connect to.", exceptions);
        }
예제 #14
0
        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration
            {
                ApplicationName = "UA Core Sample Client",
                ApplicationType = ApplicationType.Client,
                ApplicationUri = "urn:"+Utils.GetHostName()+":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas = new TransportQuotas { OperationTimeout = 120000 },
                ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 120000 }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            Uri endpointURI = new Uri(endpointURL);
            var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
            var selectedEndpoint = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);
            Console.WriteLine("    Selected endpoint uses: {0}",
                selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

#if PERF
        for (int i = 1; ; i++)
        {
#endif
            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
            endpoint.Update(selectedEndpoint);
            var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, null,
                null);

            // Access underlying proxy socket
            var channel = session.TransportChannel as IMessageSocketChannel;
            var socket = channel.Socket as ProxyMessageSocket;
            var proxySocket = socket.ProxySocket;
            Console.WriteLine("    Connected through proxy {0}.", proxySocket.LocalEndPoint.ToString());

            ReferenceDescriptionCollection references;
            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);
            Stopwatch w = Stopwatch.StartNew();

            Console.WriteLine($"4 - Browse the OPC UA server namespace.");

            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint) NodeClass.Variable | (uint) NodeClass.Object | (uint) NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            BrowseChildren("", references, session);
            Console.WriteLine($" ....        took {w.ElapsedMilliseconds} ms...");
#if PERF
            session.Close();
        }
#else

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            var list = new List<MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                }
            };
            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press any key to exit...");
#endif
        }
예제 #15
0
        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration()
            {
                ApplicationName       = "UA Core Sample Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = "X509Store",
                        StorePath   = "CurrentUser\\UA_MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 15000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 60000
                }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            Uri endpointURI        = new Uri(endpointURL);
            var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
            var selectedEndpoint   = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);

            Console.WriteLine("    Selected endpoint uses: {0}",
                              selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);

            endpoint.Update(selectedEndpoint);
            var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null);

            Console.WriteLine("4 - Browse the OPC UA server namespace.");
            ReferenceDescriptionCollection references;

            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);

            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            foreach (var rd in references)
            {
                Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                ReferenceDescriptionCollection nextRefs;
                byte[] nextCp;
                session.Browse(
                    null,
                    null,
                    ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris),
                    0u,
                    BrowseDirection.Forward,
                    ReferenceTypeIds.HierarchicalReferences,
                    true,
                    (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                    out nextCp,
                    out nextRefs);

                foreach (var nextRd in nextRefs)
                {
                    Console.WriteLine("   + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
                }
            }

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            var subscription = new Subscription(session.DefaultSubscription)
            {
                PublishingInterval = 1000
            };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            var list = new List <MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                }
            };

            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press any key to exit...");
            Console.ReadKey(true);
        }
예제 #16
0
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                // check that discover has completed.
                if (!m_discoverySucceeded)
                {
                    DialogResult result = MessageBox.Show(
                        "Endpoint information may be out of date because the discovery process has not completed. Continue anyways?",
                        this.Text,
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Warning);

                    if (result != DialogResult.Yes)
                    {
                        return;
                    }
                }

                EndpointConfiguration configuration = m_endpointConfiguration;

                if (configuration == null)
                {
                    configuration = EndpointConfiguration.Create(m_configuration);
                }

                if (m_currentDescription == null)
                {
                    m_currentDescription = CreateDescriptionFromSelections();
                }

                // the discovery endpoint should always be on the same machine as the server.
                // if there is a mismatch it is likely because the server has multiple addresses
                // and was not configured to return the current address to the client.
                // The code automatically updates the domain in the url.
                Uri endpointUrl = Utils.ParseUri(m_currentDescription.EndpointUrl);

                if (m_discoverySucceeded)
                {
                    if (!Utils.AreDomainsEqual(endpointUrl, m_discoveryUrl))
                    {
                        UriBuilder url = new UriBuilder(endpointUrl);

                        url.Host = m_discoveryUrl.DnsSafeHost;

                        if (url.Scheme == m_discoveryUrl.Scheme)
                        {
                            url.Port = m_discoveryUrl.Port;
                        }

                        endpointUrl = url.Uri;

                        m_currentDescription.EndpointUrl = endpointUrl.ToString();
                    }
                }

                // set the encoding.
                Encoding encoding = (Encoding)EncodingCB.SelectedItem;
                configuration.UseBinaryEncoding = encoding != Encoding.Xml;

                if (m_endpoint == null)
                {
                    m_endpoint = new ConfiguredEndpoint(null, m_currentDescription, configuration);
                }
                else
                {
                    m_endpoint.Update(m_currentDescription);
                    m_endpoint.Update(configuration);
                }

                // set the user token policy.
                m_endpoint.SelectedUserTokenPolicyIndex = FindBestUserTokenPolicy(m_currentDescription);

                // update the user identity.
                UserTokenType userTokenType = (UserTokenType)UserTokenTypeCB.SelectedItem;

                UserIdentityToken userIdentity = null;

                if (!m_userIdentities.TryGetValue(userTokenType, out userIdentity))
                {
                    userIdentity = null;
                }

                m_endpoint.UserIdentity = userIdentity;

                DialogResult = DialogResult.OK;
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration()
            {
                ApplicationName = "UA Core Sample Client",
                ApplicationType = ApplicationType.Client,
                ApplicationUri = "urn:"+Utils.GetHostName()+":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
                ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    config.ApplicationUri,
                    config.ApplicationName
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;

            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            Uri endpointURI = new Uri(endpointURL);
            var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
            var selectedEndpoint = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);
            Console.WriteLine("    Selected endpoint uses: {0}", 
                selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
            endpoint.Update(selectedEndpoint);
            var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, null, null);

            Console.WriteLine("4 - Browse the OPC UA server namespace.");
            ReferenceDescriptionCollection references;
            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);

            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            foreach (var rd in references)
            {
                Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                ReferenceDescriptionCollection nextRefs;
                byte[] nextCp;
                session.Browse(
                    null,
                    null,
                    ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris),
                    0u,
                    BrowseDirection.Forward,
                    ReferenceTypeIds.HierarchicalReferences,
                    true,
                    (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                    out nextCp,
                    out nextRefs);

                foreach (var nextRd in nextRefs)
                {
                    Console.WriteLine("   + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
                }
            }

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            var list = new List<MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                }
            };
            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press any key to exit...");
            Console.ReadKey(true);
        }