コード例 #1
0
ファイル: Subscription.cs プロジェクト: OPCFoundation/UA-.NET
        /// <summary>
        /// Initializes the object.
        /// </summary>
        public Subscription(
            IServerInternal  server,
            Session          session,
            uint             subscriptionId,
			double           publishingInterval,
            uint             maxLifetimeCount,
			uint             maxKeepAliveCount,
            uint             maxNotificationsPerPublish,
            byte             priority,
			bool             publishingEnabled,
            uint             maxMessageCount)
        {       
            if (server == null)  throw new ArgumentNullException("server");
            if (session == null) throw new ArgumentNullException("session");

            m_server                      = server;
            m_session                     = session;
            m_id                          = subscriptionId;
            m_publishingInterval          = publishingInterval;
            m_maxLifetimeCount            = maxLifetimeCount;
            m_maxKeepAliveCount           = maxKeepAliveCount;
            m_maxNotificationsPerPublish  = maxNotificationsPerPublish;
            m_publishingEnabled           = publishingEnabled;
            m_priority                    = priority;
            m_publishTimerExpiry          = HiResClock.UtcNow.Ticks/TimeSpan.TicksPerMillisecond + (long)publishingInterval;
            m_keepAliveCounter            = maxKeepAliveCount;
            m_lifetimeCounter             = 0;
            m_waitingForPublish           = false;
            m_maxMessageCount             = maxMessageCount;
            m_sentMessages                = new List<NotificationMessage>();
            
            m_monitoredItems              = new Dictionary<uint,LinkedListNode<IMonitoredItem>>();
            m_itemsToCheck                = new LinkedList<IMonitoredItem>();
            m_itemsToPublish              = new LinkedList<IMonitoredItem>();
            m_itemsToTrigger              = new Dictionary<uint,List<ITriggeredMonitoredItem>>();

            // m_itemsReadyToPublish         = new Queue<IMonitoredItem>();
            // m_itemsNotificationsAvailable = new LinkedList<IMonitoredItem>();
            m_sequenceNumber              = 1;
            
            // initialize diagnostics.
            m_diagnostics = new SubscriptionDiagnosticsDataType();

            m_diagnostics.SessionId = m_session.Id;
            m_diagnostics.SubscriptionId = m_id;
            m_diagnostics.Priority = priority;
            m_diagnostics.PublishingInterval = publishingInterval;
            m_diagnostics.MaxKeepAliveCount = maxKeepAliveCount;
            m_diagnostics.MaxLifetimeCount = maxLifetimeCount;
            m_diagnostics.MaxNotificationsPerPublish = maxNotificationsPerPublish;
            m_diagnostics.PublishingEnabled = publishingEnabled;
            m_diagnostics.ModifyCount = 0;
            m_diagnostics.EnableCount = 0;
            m_diagnostics.DisableCount = 0;
            m_diagnostics.RepublishMessageRequestCount = 0;
            m_diagnostics.RepublishMessageCount = 0;
            m_diagnostics.TransferRequestCount = 0;
            m_diagnostics.TransferredToSameClientCount = 0;
            m_diagnostics.TransferredToAltClientCount = 0;
            m_diagnostics.PublishRequestCount = 0;
            m_diagnostics.DataChangeNotificationsCount = 0;
            m_diagnostics.EventNotificationsCount = 0;
            m_diagnostics.NotificationsCount = 0;
            m_diagnostics.LatePublishRequestCount = 0;
            m_diagnostics.CurrentKeepAliveCount = 0;
            m_diagnostics.CurrentLifetimeCount = 0;
            m_diagnostics.UnacknowledgedMessageCount = 0;
            m_diagnostics.DiscardedMessageCount = 0;
            m_diagnostics.MonitoredItemCount = 0;
            m_diagnostics.DisabledMonitoredItemCount = 0;
            m_diagnostics.MonitoringQueueOverflowCount = 0;
            m_diagnostics.NextSequenceNumber = (uint)m_sequenceNumber;

            ServerSystemContext systemContext = m_server.DefaultSystemContext.Copy(session);

            m_diagnosticsId = server.DiagnosticsNodeManager.CreateSubscriptionDiagnostics(
                systemContext,
                m_diagnostics,
                OnUpdateDiagnostics);
            
            // TraceState("CREATED");
        }
コード例 #2
0
        /// <summary>
        /// Reports notifications for any monitored diagnostic nodes.
        /// </summary>
        private void DoScan(object alwaysUpdateArrays)
        {
            try
            {
                lock (Lock)
                {
                    if (!m_diagnosticsEnabled)
                    {
                        return;
                    }

                    m_lastDiagnosticsScanTime = DateTime.UtcNow;
                
                    // update server diagnostics.
                    UpdateServerDiagnosticsSummary();
                   
                    // update session diagnostics.
                    bool sessionsChanged = alwaysUpdateArrays != null;
                    SessionDiagnosticsDataType[] sessionArray = new SessionDiagnosticsDataType[m_sessions.Count];

                    for (int ii = 0; ii < m_sessions.Count; ii++)
                    {
                        SessionDiagnosticsData diagnostics = m_sessions[ii];

                        if (UpdateSessionDiagnostics(diagnostics, sessionArray, ii))
                        {
                            sessionsChanged = true;
                        }
                    }

                    // check of the session diagnostics array node needs to be updated.
                    SessionDiagnosticsArrayState sessionsNode = (SessionDiagnosticsArrayState)FindPredefinedNode(
                        VariableIds.Server_ServerDiagnostics_SessionsDiagnosticsSummary_SessionDiagnosticsArray,
                        typeof(SessionDiagnosticsArrayState));
                                                
                    if (sessionsNode != null && (sessionsNode.Value == null || StatusCode.IsBad(sessionsNode.StatusCode) || sessionsChanged))
                    {
                        sessionsNode.Value = sessionArray;
                        sessionsNode.ClearChangeMasks(SystemContext, false);
                    }
                      
                    bool sessionsSecurityChanged = alwaysUpdateArrays != null;
                    SessionSecurityDiagnosticsDataType[] sessionSecurityArray = new SessionSecurityDiagnosticsDataType[m_sessions.Count];

                    for (int ii = 0; ii < m_sessions.Count; ii++)
                    {                        
                        SessionDiagnosticsData diagnostics = m_sessions[ii];

                        if (UpdateSessionSecurityDiagnostics(diagnostics, sessionSecurityArray, ii))
                        {
                            sessionsChanged = true;
                        }
                    }

                    // check of the array node needs to be updated.
                    SessionSecurityDiagnosticsArrayState sessionsSecurityNode = (SessionSecurityDiagnosticsArrayState)FindPredefinedNode(
                        VariableIds.Server_ServerDiagnostics_SessionsDiagnosticsSummary_SessionSecurityDiagnosticsArray,
                        typeof(SessionSecurityDiagnosticsArrayState));
                                                
                    if (sessionsSecurityNode != null && (sessionsSecurityNode.Value == null || StatusCode.IsBad(sessionsSecurityNode.StatusCode) || sessionsSecurityChanged))
                    {
                        sessionsSecurityNode.Value = sessionSecurityArray;
                        sessionsSecurityNode.ClearChangeMasks(SystemContext, false);
                    }

                    bool subscriptionsChanged = alwaysUpdateArrays != null;
                    SubscriptionDiagnosticsDataType[] subscriptionArray = new SubscriptionDiagnosticsDataType[m_subscriptions.Count];

                    for (int ii = 0; ii < m_subscriptions.Count; ii++)
                    {
                        SubscriptionDiagnosticsData diagnostics = m_subscriptions[ii];
                        
                        if (UpdateSubscriptionDiagnostics(diagnostics, subscriptionArray, ii))
                        {
                            sessionsChanged = true;
                        }
                    }

                    // check of the subscription node needs to be updated.
                    SubscriptionDiagnosticsArrayState subscriptionsNode = (SubscriptionDiagnosticsArrayState)FindPredefinedNode(
                        VariableIds.Server_ServerDiagnostics_SubscriptionDiagnosticsArray,
                        typeof(SubscriptionDiagnosticsArrayState));
                                                   
                    if (subscriptionsNode != null && (subscriptionsNode.Value == null || StatusCode.IsBad(subscriptionsNode.StatusCode) || subscriptionsChanged)) 
                    {
                        subscriptionsNode.Value = subscriptionArray;
                        subscriptionsNode.ClearChangeMasks(SystemContext, false);
                    }

                    for (int ii = 0; ii < m_sessions.Count; ii++)
                    {
                        SessionDiagnosticsData diagnostics = m_sessions[ii];
                        List<SubscriptionDiagnosticsDataType> subscriptionDiagnosticsArray = new List<SubscriptionDiagnosticsDataType>();

                        NodeId sessionId = diagnostics.Summary.NodeId;

                        for (int jj = 0; jj < m_subscriptions.Count; jj++)
                        {
                            SubscriptionDiagnosticsData subscriptionDiagnostics = m_subscriptions[jj];

                            if (subscriptionDiagnostics.Value.Value == null)
                            {
                                continue;
                            }

                            if (subscriptionDiagnostics.Value.Value.SessionId != sessionId)
                            {
                                continue;
                            }

                            subscriptionDiagnosticsArray.Add(subscriptionDiagnostics.Value.Value);
                        }

                        // update session subscription array.
                        subscriptionsNode = (SubscriptionDiagnosticsArrayState)diagnostics.Summary.CreateChild(
                            SystemContext,
                            BrowseNames.SubscriptionDiagnosticsArray);
                                    
                        if (subscriptionsNode != null && (subscriptionsNode.Value == null || StatusCode.IsBad(subscriptionsNode.StatusCode) || subscriptionsChanged))
                        {
                            subscriptionsNode.Value = subscriptionDiagnosticsArray.ToArray();
                            subscriptionsNode.ClearChangeMasks(SystemContext, false);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error during diagnostics scan.");
            }
        }
コード例 #3
0
        /// <summary>
        /// Creates the diagnostics node for a subscription.
        /// </summary>
        public NodeId CreateSubscriptionDiagnostics(
            ServerSystemContext systemContext, 
            SubscriptionDiagnosticsDataType diagnostics,
            NodeValueSimpleEventHandler updateCallback)
        {
            NodeId nodeId = null;

            lock (Lock)
            {
                // check if diagnostics have been enabled.
                if (!m_diagnosticsEnabled)
                {
                    return null;
                }

                SubscriptionDiagnosticsState diagnosticsNode = new SubscriptionDiagnosticsState(null);

                // create a new instance and assign ids.
                nodeId = CreateNode(
                    systemContext,
                    null,
                    ReferenceTypeIds.HasComponent,
                    new QualifiedName(diagnostics.SubscriptionId.ToString()),
                    diagnosticsNode);

                // add reference to subscription array.
                diagnosticsNode.AddReference(
                    ReferenceTypeIds.HasComponent,
                    true,
                    VariableIds.Server_ServerDiagnostics_SubscriptionDiagnosticsArray);

                // wrap diagnostics in a thread safe object.
                SubscriptionDiagnosticsValue diagnosticsValue = new SubscriptionDiagnosticsValue(diagnosticsNode, diagnostics, Lock);
                diagnosticsValue.CopyPolicy = Opc.Ua.VariableCopyPolicy.Never;
                diagnosticsValue.OnBeforeRead = OnBeforeReadDiagnostics;
                
                // must ensure the first update gets sent.
                diagnosticsValue.Value = null;
                diagnosticsValue.Error = StatusCodes.BadWaitingForInitialData;

                m_subscriptions.Add(new SubscriptionDiagnosticsData(diagnosticsValue, updateCallback));

                // add reference from subscription array.
                SubscriptionDiagnosticsArrayState array = (SubscriptionDiagnosticsArrayState)FindPredefinedNode(
                    VariableIds.Server_ServerDiagnostics_SubscriptionDiagnosticsArray,
                    typeof(SubscriptionDiagnosticsArrayState));
                                            
                if (array != null)
                {
                    array.AddReference(ReferenceTypeIds.HasComponent, false, diagnosticsNode.NodeId);
                }
                
                // add reference to session subscription array.
                diagnosticsNode.AddReference(
                    ReferenceTypeIds.HasComponent,
                    true,
                    diagnostics.SessionId);

                // add reference from session subscription array.
                SessionDiagnosticsObjectState sessionNode = (SessionDiagnosticsObjectState)FindPredefinedNode(
                    diagnostics.SessionId,
                    typeof(SessionDiagnosticsObjectState));
                                            
                if (sessionNode != null)
                {
                    // add reference from subscription array.
                    array = (SubscriptionDiagnosticsArrayState)sessionNode.CreateChild(
                        systemContext,
                        BrowseNames.SubscriptionDiagnosticsArray);
                                                
                    if (array != null)
                    {
                        array.AddReference(ReferenceTypeIds.HasComponent, false, diagnosticsNode.NodeId);
                    }
                }

                // send initial update.
                DoScan(true);
            }

            return nodeId;
        }
コード例 #4
0
        /// <summary>
        /// Updates the subscription diagnostics summary structure.
        /// </summary>
        private bool UpdateSubscriptionDiagnostics(
            SubscriptionDiagnosticsData diagnostics, 
            SubscriptionDiagnosticsDataType[] subscriptionArray, 
            int index)
        {  
            // get the latest snapshot.
            object value = null;
            
            ServiceResult result = diagnostics.UpdateCallback(
                SystemContext, 
                diagnostics.Value.Variable, 
                ref value);

            SubscriptionDiagnosticsDataType newValue = value as SubscriptionDiagnosticsDataType;
            subscriptionArray[index] = newValue;

            // check for changes.
            if (Utils.IsEqual(newValue, diagnostics.Value.Value))
            {
                return false;
            }
            
            diagnostics.Value.Error = null;
            
            // check for bad value.
            if (ServiceResult.IsNotBad(result) && newValue == null)
            {
                result = StatusCodes.BadOutOfService;
            }

            // check for bad result.
            if (ServiceResult.IsBad(result))
            {
                diagnostics.Value.Error = result;
                newValue = null;
            }
            
            // update the value.
            diagnostics.Value.Value = newValue;
            diagnostics.Value.Timestamp = DateTime.UtcNow;

            // notify any monitored items.
            diagnostics.Value.ChangesComplete(SystemContext);

            return true;
        }