예제 #1
0
        /// <summary>
        /// Raised when a publish response arrives from the server.
        /// </summary>
        static void Session_Notification(Session session, NotificationEventArgs e)
        {
            NotificationMessage message = e.NotificationMessage;

            // check for keep alive.
            if (message.NotificationData.Count == 0)
            {
                Console.WriteLine(
                    "===>>> Subscription KeepAlive: SubscriptionId={0} MessageId={1} Time={2:HH:mm:ss.fff}",
                    e.Subscription.Id,
                    message.SequenceNumber,
                    message.PublishTime.ToLocalTime());

                return;
            }

            DataChangeNotification dcn = (DataChangeNotification)ExtensionObject.ToEncodeable(message.NotificationData[0]);
            // Console.WriteLine("{0:mm:ss.fff} - SeqNo={1}, Items={2}", message.PublishTime, message.SequenceNumber, dcn.MonitoredItems.Count);

            int count = 0;

            // get the data changes (oldest to newest).
            foreach (MonitoredItemNotification datachange in message.GetDataChanges(false))
            {
                // lookup the monitored item.
                MonitoredItem monitoredItem = e.Subscription.FindItemByClientHandle(datachange.ClientHandle);

                if (monitoredItem == null)
                {
                    Console.WriteLine("MonitoredItem ClientHandle not known: {0}", datachange.ClientHandle);
                    continue;
                }

                // this is called on another thread so we need to synchronize before accessing the node.
                lock (m_lock)
                {
                    NodeOfInterest node = monitoredItem.Handle as NodeOfInterest;

                    //Console.WriteLine(
                    //    "Update for {0}: {1} Status={2} Timestamp={3:HH:mm:ss.fff}",
                    //    node.DisplayName,
                    //    datachange.Value.WrappedValue,
                    //    datachange.Value.StatusCode,
                    //    datachange.Value.SourceTimestamp.ToLocalTime());

                    node.Value = datachange.Value;
                    Save(datachange.ClientHandle, node.Value);
                    count++;
                }
            }

            if (count > NotificationsPerPublish)
            {
                Console.WriteLine("Too many notifications in Publish: {0}/{1}", count, NotificationsPerPublish);
            }

            lock (m_publishes)
            {
                m_notifications++;

                if (m_lastDump.AddSeconds(1) > DateTime.UtcNow)
                {
                    return;
                }

                int sampleCount = 0;
                int itemCount   = 0;

                DateTime timestamp = DateTime.MinValue;

                while (m_publishes.Count > 0)
                {
                    DataValue value1 = m_publishes.Dequeue();

                    if (timestamp < value1.SourceTimestamp)
                    {
                        if (timestamp != DateTime.MinValue)
                        {
                            //Console.WriteLine(
                            //    "Items = {1}, Timestamp = {0:mm:ss.fff}",
                            //    timestamp,
                            //    itemCount);
                        }

                        timestamp = value1.SourceTimestamp;
                        itemCount = 0;
                    }

                    sampleCount++;
                    itemCount++;
                }

                //Console.WriteLine(
                //    "Items = {1}, Timestamp = {0:mm:ss.fff}",
                //    timestamp,
                //    itemCount);

                uint expectedSamples       = 10000; // (uint)((1000.0/SamplingInterval)*ItemsToMonitor);
                uint expectedNotifications = 50;

                Console.WriteLine(
                    "{0:mm:ss.fff}-{1:mm:ss.fff}, Messages = {2}/{3}, Samples = {4}/{5}, MissedSamples = {6}",
                    m_lastDump,
                    m_lastDump.AddSeconds(1),
                    m_notifications,
                    expectedNotifications,
                    sampleCount,
                    expectedSamples,
                    (int)m_expectedSamples - (int)m_actualSamples);

                m_lastDump    = m_lastDump.AddSeconds(1);
                m_lastMessage = message.SequenceNumber;
                m_dumpCount++;
                m_notifications = 0;

                m_actualSamples   += (uint)sampleCount;
                m_expectedSamples += expectedSamples;

                if (m_dumpCount == 10)
                {
                    m_actualSamples   = 0;
                    m_expectedSamples = 0;
                }
            }
        }
예제 #2
0
파일: Program.cs 프로젝트: yuriik83/UA-.NET
        /// <summary>
        /// Returns the node ids for a set of relative paths.
        /// </summary>
        /// <param name="session">An open session with the server to use.</param>
        /// <param name="startNodeId">The starting node for the relative paths.</param>
        /// <param name="relativePaths">The relative paths.</param>
        /// <returns>A collection of local nodes.</returns>
        static List<NodeOfInterest> GetNodeIds(
            Session session,
            NodeId startNodeId,
            params string[] relativePaths)
        {
            // build the list of browse paths to follow by parsing the relative paths.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            if (relativePaths != null)
            {
                for (int ii = 0; ii < relativePaths.Length; ii++)
                {
                    BrowsePath browsePath = new BrowsePath();

                    // The relative paths used indexes in the namespacesUris table. These must be 
                    // converted to indexes used by the server. An error occurs if the relative path
                    // refers to a namespaceUri that the server does not recognize.

                    // The relative paths may refer to ReferenceType by their BrowseName. The TypeTree object
                    // allows the parser to look up the server's NodeId for the ReferenceType.

                    browsePath.RelativePath = RelativePath.Parse(
                        relativePaths[ii],
                        session.TypeTree,
                        session.NamespaceUris,
                        session.NamespaceUris);

                    browsePath.StartingNode = startNodeId;

                    browsePaths.Add(browsePath);
                }
            }

            // make the call to the server.
            BrowsePathResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;

            ResponseHeader responseHeader = session.TranslateBrowsePathsToNodeIds(
                null,
                browsePaths,
                out results,
                out diagnosticInfos);

            // ensure that the server returned valid results.
            Session.ValidateResponse(results, browsePaths);
            Session.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);

            Console.WriteLine("Translated {0} browse paths.", relativePaths.Length);

            // collect the list of node ids found.
            List<NodeOfInterest> nodes = new List<NodeOfInterest>();

            for (int ii = 0; ii < results.Count; ii++)
            {
                // check if the start node actually exists.
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ServiceResult error = new ServiceResult(
                        results[ii].StatusCode,
                        diagnosticInfos[ii],
                        responseHeader.StringTable);

                    Console.WriteLine("Path '{0}' is not valid. Error = {1}", relativePaths[ii], error);
                    continue;
                }

                // an empty list is returned if no node was found.
                if (results[ii].Targets.Count == 0)
                {
                    Console.WriteLine("Path '{0}' does not exist.", relativePaths[ii]);
                    continue;
                }

                // Multiple matches are possible, however, the node that matches the type model is the
                // one we are interested in here. The rest can be ignored.
                BrowsePathTarget target = results[ii].Targets[0];

                if (target.RemainingPathIndex != UInt32.MaxValue)
                {
                    Console.WriteLine("Path '{0}' refers to a node in another server.", relativePaths[ii]);
                    continue;
                }

                // The targetId is an ExpandedNodeId because it could be node in another server. 
                // The ToNodeId function is used to convert a local NodeId stored in a ExpandedNodeId to a NodeId.

                NodeOfInterest node = new NodeOfInterest();
                node.NodeId = ExpandedNodeId.ToNodeId(target.TargetId, session.NamespaceUris);
                nodes.Add(node);
            }

            Console.WriteLine("Translate found {0} local nodes.", nodes.Count);

            // return whatever was found.
            return nodes;
        }
예제 #3
0
        /// <summary>
        /// Returns the node ids for a set of relative paths.
        /// </summary>
        /// <param name="session">An open session with the server to use.</param>
        /// <param name="startNodeId">The starting node for the relative paths.</param>
        /// <param name="relativePaths">The relative paths.</param>
        /// <returns>A collection of local nodes.</returns>
        static List <NodeOfInterest> GetNodeIds(
            Session session,
            NodeId startNodeId,
            params string[] relativePaths)
        {
            // build the list of browse paths to follow by parsing the relative paths.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            if (relativePaths != null)
            {
                for (int ii = 0; ii < relativePaths.Length; ii++)
                {
                    BrowsePath browsePath = new BrowsePath();

                    // The relative paths used indexes in the namespacesUris table. These must be
                    // converted to indexes used by the server. An error occurs if the relative path
                    // refers to a namespaceUri that the server does not recognize.

                    // The relative paths may refer to ReferenceType by their BrowseName. The TypeTree object
                    // allows the parser to look up the server's NodeId for the ReferenceType.

                    browsePath.RelativePath = RelativePath.Parse(
                        relativePaths[ii],
                        session.TypeTree,
                        session.NamespaceUris,
                        session.NamespaceUris);

                    browsePath.StartingNode = startNodeId;

                    browsePaths.Add(browsePath);
                }
            }

            // make the call to the server.
            BrowsePathResultCollection results;
            DiagnosticInfoCollection   diagnosticInfos;

            ResponseHeader responseHeader = session.TranslateBrowsePathsToNodeIds(
                null,
                browsePaths,
                out results,
                out diagnosticInfos);

            // ensure that the server returned valid results.
            Session.ValidateResponse(results, browsePaths);
            Session.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);

            Console.WriteLine("Translated {0} browse paths.", relativePaths.Length);

            // collect the list of node ids found.
            List <NodeOfInterest> nodes = new List <NodeOfInterest>();

            for (int ii = 0; ii < results.Count; ii++)
            {
                // check if the start node actually exists.
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ServiceResult error = new ServiceResult(
                        results[ii].StatusCode,
                        diagnosticInfos[ii],
                        responseHeader.StringTable);

                    Console.WriteLine("Path '{0}' is not valid. Error = {1}", relativePaths[ii], error);
                    continue;
                }

                // an empty list is returned if no node was found.
                if (results[ii].Targets.Count == 0)
                {
                    Console.WriteLine("Path '{0}' does not exist.", relativePaths[ii]);
                    continue;
                }

                // Multiple matches are possible, however, the node that matches the type model is the
                // one we are interested in here. The rest can be ignored.
                BrowsePathTarget target = results[ii].Targets[0];

                if (target.RemainingPathIndex != UInt32.MaxValue)
                {
                    Console.WriteLine("Path '{0}' refers to a node in another server.", relativePaths[ii]);
                    continue;
                }

                // The targetId is an ExpandedNodeId because it could be node in another server.
                // The ToNodeId function is used to convert a local NodeId stored in a ExpandedNodeId to a NodeId.

                NodeOfInterest node = new NodeOfInterest();
                node.NodeId = ExpandedNodeId.ToNodeId(target.TargetId, session.NamespaceUris);
                nodes.Add(node);
            }

            Console.WriteLine("Translate found {0} local nodes.", nodes.Count);

            // return whatever was found.
            return(nodes);
        }