Represents the event arguments provided when a new notification message arrives.
Inheritance: System.EventArgs
        private void Session_Notification(Session sender, NotificationEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(m_SessionNotification, sender, e);
                return;
            }
            else if (!IsHandleCreated)
            {
                return;
            }
            
            try
            {
                if (m_subscription != null)
                {
                    if (!Object.ReferenceEquals(m_subscription, e.Subscription))
                    {
                        return;
                    }
                }

                // get the current control contents.
                List<ItemData> tags = new List<ItemData>();

                foreach (ListViewItem item in ItemsLV.Items)
                {
                    ItemData tag = item.Tag as ItemData;

                    if (tag != null)
                    {
                        tags.Add(tag);
                    }
                }

                tags.Insert(0, new ItemData(e.Subscription, e.NotificationMessage));

                // update control.
                Update(tags);
            }
            catch (Exception exception)
            {
				GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        /// <summary>
        /// Processes a Publish repsonse from the server.
        /// </summary>
        void Session_Notification(Session session, NotificationEventArgs e)
        {
            try
            {
                // ignore notifications for other subscriptions.
                if (!Object.ReferenceEquals(m_subscription,  e.Subscription))
                {
                    return;
                }
                                
                // notify controls of the change.
                EventsCTRL.NotificationReceived(e);
                DataChangesCTRL.NotificationReceived(e);

                // update subscription status.
                UpdateStatus();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception);
            }
        }
 internal void NotificationReceived(NotificationEventArgs e)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Processes a new notification.
        /// </summary>
        public void NotificationReceived(NotificationEventArgs e)
        {
            // get the events.
            List<EventFieldList> events = new List<EventFieldList>();

            foreach (EventFieldList eventFields in e.NotificationMessage.GetEvents(true))
            {
                if (m_monitoredItem != null)
                {
                    if (m_monitoredItem.ClientHandle != eventFields.ClientHandle)
                    {
                        continue;
                    }
                }
                else
                {
                    if (m_subscription.FindItemByClientHandle(eventFields.ClientHandle) == null)
                    {
                        continue;
                    }
                }   

                events.Add(eventFields);

                if (events.Count >= MaxEventCount)
                {
                    break;
                }
            }

            // check if nothing more to do.
            if (events.Count == 0)
            {
                return;
            }

            int offset = events.Count;

            // fill in earlier events.
            foreach (ListViewItem listItem in ItemsLV.Items)
            {
                EventFieldList eventFields = listItem.Tag as EventFieldList;

                if (eventFields == null)
                {
                    continue;
                }

                if (m_monitoredItem != null)
                {
                    if (m_monitoredItem.ClientHandle != eventFields.ClientHandle)
                    {
                        continue;
                    }
                }
                
                 events.Add(eventFields);

                if (events.Count >= MaxEventCount)
                {
                    break;
                }
            }
            
            UpdateEvents(events, offset);
            AdjustColumns();
        }
Example #5
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;
                }
            }
        }
Example #6
0
        /// <summary>
        /// Processes the response from a publish request.
        /// </summary>
        private void ProcessPublishResponse(
            ResponseHeader      responseHeader,
            uint                subscriptionId,
            UInt32Collection    availableSequenceNumbers,
            bool                moreNotifications,
            NotificationMessage notificationMessage)
        {
            Subscription subscription = null;
            
            // send notification that the server is alive.
            OnKeepAlive(m_serverState, responseHeader.Timestamp);

            // collect the current set if acknowledgements.
            lock (SyncRoot)
            {
                // clear out acknowledgements for messages that the server does not have any more.
                SubscriptionAcknowledgementCollection acknowledgementsToSend = new SubscriptionAcknowledgementCollection();

                for (int ii = 0; ii < m_acknowledgementsToSend.Count; ii++)
                {
                    SubscriptionAcknowledgement acknowledgement = m_acknowledgementsToSend[ii];

                    if (acknowledgement.SubscriptionId != subscriptionId)
                    {
                        acknowledgementsToSend.Add(acknowledgement);
                    }
                    else
                    {
                        if (availableSequenceNumbers == null || availableSequenceNumbers.Contains(acknowledgement.SequenceNumber))
                        {
                            acknowledgementsToSend.Add(acknowledgement);
                        }
                    }
                }

                // create an acknowledgement to be sent back to the server.
                if (notificationMessage.NotificationData.Count > 0)
                {
                    SubscriptionAcknowledgement acknowledgement = new SubscriptionAcknowledgement();

                    acknowledgement.SubscriptionId = subscriptionId;
                    acknowledgement.SequenceNumber = notificationMessage.SequenceNumber;

                    acknowledgementsToSend.Add(acknowledgement);
                }

                uint lastSentSequenceNumber = 0;
                if (availableSequenceNumbers != null)
                {
                    foreach (uint availableSequenceNumber in availableSequenceNumbers)
                    {
                        if (m_latestAcknowledgementsSent.ContainsKey(subscriptionId))
                        {
                            lastSentSequenceNumber = m_latestAcknowledgementsSent[subscriptionId];

                            // If the last sent sequence number is uint.Max do not display the warning; the counter rolled over
                            // If the last sent sequence number is greater or equal to the available sequence number (returned by the publish), a warning must be logged.
                            if (((lastSentSequenceNumber >= availableSequenceNumber) && (lastSentSequenceNumber != uint.MaxValue)) || (lastSentSequenceNumber == availableSequenceNumber) && (lastSentSequenceNumber == uint.MaxValue))
                            {
                                Utils.Trace("Received sequence number which was already acknowledged={0}", availableSequenceNumber);
                            }
                        }
                    }
                }

                if (m_latestAcknowledgementsSent.ContainsKey(subscriptionId))
                {
                    lastSentSequenceNumber = m_latestAcknowledgementsSent[subscriptionId];

                    // If the last sent sequence number is uint.Max do not display the warning; the counter rolled over
                    // If the last sent sequence number is greater or equal to the notificationMessage's sequence number (returned by the publish), a warning must be logged.
                    if (((lastSentSequenceNumber >= notificationMessage.SequenceNumber) && (lastSentSequenceNumber != uint.MaxValue)) || (lastSentSequenceNumber == notificationMessage.SequenceNumber) && (lastSentSequenceNumber == uint.MaxValue))
                    {
                        Utils.Trace("Received sequence number which was already acknowledged={0}", notificationMessage.SequenceNumber);
                    }
                }

                if (availableSequenceNumbers != null)
                {
                    foreach (var acknowledgement in acknowledgementsToSend)
                    {
                        if (acknowledgement.SubscriptionId == subscriptionId && !availableSequenceNumbers.Contains(acknowledgement.SequenceNumber))
                        {
                            Utils.Trace("Sequence number={0} was not received in the available sequence numbers.", acknowledgement.SequenceNumber);
                        }
                    }
                }

                m_acknowledgementsToSend = acknowledgementsToSend;

                if (notificationMessage.IsEmpty)
                {
                    Utils.Trace("Empty notification message received for SessionId {0} with PublishTime {1}", SessionId, notificationMessage.PublishTime.ToLocalTime());
                }

                // find the subscription.
                foreach (Subscription current in m_subscriptions)
                {
                    if (current.Id == subscriptionId)
                    {
                        subscription = current;                            
                        break;
                    }
                }                    
            }

            // ignore messages with a subscription that has been deleted.
            if (subscription != null)
            {
                // Validate publish time and reject old values.
                if (notificationMessage.PublishTime.AddMilliseconds(subscription.CurrentPublishingInterval * subscription.CurrentLifetimeCount) < DateTime.UtcNow)
                {
                    Utils.Trace("PublishTime {0} in publish response is too old for SubscriptionId {1}.", notificationMessage.PublishTime.ToLocalTime(), subscription.Id);
                }

                // Validate publish time and reject old values.
                if (notificationMessage.PublishTime > DateTime.UtcNow.AddMilliseconds(subscription.CurrentPublishingInterval * subscription.CurrentLifetimeCount))
                {
                    Utils.Trace("PublishTime {0} in publish response is newer than actual time for SubscriptionId {1}.", notificationMessage.PublishTime.ToLocalTime(), subscription.Id);
                }

                // update subscription cache.                                 
                subscription.SaveMessageInCache(
                    availableSequenceNumbers, 
                    notificationMessage, 
                    responseHeader.StringTable);

                // raise the notification.
                lock (m_eventLock)
                {
                    NotificationEventArgs args = new NotificationEventArgs(subscription, notificationMessage, responseHeader.StringTable);

                    if (m_Publish != null)
                    {
                        ThreadPool.QueueUserWorkItem(OnRaisePublishNotification, args);
                    }
                }
            }
            else
            {
                Utils.Trace("Received Publish Response for Unknown SubscriptionId={0}", subscriptionId);
            }
        }
Example #7
0
        void Session_Notification(Session session, NotificationEventArgs e)
        {            
            lock (m_messages)
            {
                List<uint> messages = null;

                if (!m_messages.TryGetValue(e.Subscription.Id, out messages))
                {
                    m_messages[e.Subscription.Id] = messages = new List<uint>();
                }

                messages.Add(e.NotificationMessage.SequenceNumber);
            }
        }
Example #8
0
        void Session_Notification(Session session, NotificationEventArgs e)
        {
            try
            {  
                lock (m_variables)
                {
                    NotificationMessage message = e.NotificationMessage;

                    // check for keep alive.
                    if (message.NotificationData.Count == 0)
                    {
                        return;
                    }
                
                    int count = 0;

                    foreach (ExtensionObject extension in message.NotificationData)
                    {
                        if (ExtensionObject.IsNull(extension))
                        {
                            continue;
                        }

                        DataChangeNotification datachange = extension.Body as DataChangeNotification;
                                        
                        if (datachange == null)
                        {
                            continue;
                        }

                        /*
                        Log(
                            "NOTIFICATION: [{0}]\t{1:HH:mm:ss.fff}\t{2:HH:mm:ss.fff}\t{3}", 
                            message.SequenceNumber, 
                            message.PublishTime, 
                            DateTime.UtcNow, 
                            datachange.MonitoredItems.Count);
                        */

                        for (int ii = 0; ii < datachange.MonitoredItems.Count; ii++)
                        {
                            count++;

                            MonitoredItemNotification notification = datachange.MonitoredItems[ii];
                            TestVariable variable = null;

                            if (m_monitoredItems.TryGetValue(notification.ClientHandle, out variable))
                            {
                                List<Notification> notifications = variable.Notifications[notification.ClientHandle];

                                Notification record = new Notification();
                         
                                record.Value = notification.Value;
                                record.SequenceNumber = message.SequenceNumber;
                                record.Timestamp = DateTime.UtcNow;

                                for (int jj = notifications.Count-1; jj >= 0 ; jj--)
                                {
                                    if (notifications[jj].SequenceNumber == record.SequenceNumber)
                                    {
                                        if (notifications[jj].Value.SourceTimestamp == record.Value.SourceTimestamp)
                                        {
                                            notifications[jj] = record;
                                            record = null;
                                            break;
                                        }
                                    }
                                    
                                    if (notifications[jj].SequenceNumber <= record.SequenceNumber)
                                    {
                                        if (jj < notifications.Count-1)
                                        {
                                            notifications.Insert(jj+1, record);
                                        }
                                        else
                                        {
                                            notifications.Add(record);
                                        }

                                        record = null;
                                        break;
                                    }
                                    
                                    if (jj == 0 && notifications[jj].SequenceNumber > record.SequenceNumber)
                                    {
                                        notifications.Insert(0, record);
                                        record = null;
                                        break;
                                    }
                                }

                                if (record != null)
                                {
                                    notifications.Add(record);
                                }
                            }
                        }
                    }
                    
                    // Utils.Trace("NotificationMessage #{0} DataCount={1} NotificationCount={2}", message.SequenceNumber, message.NotificationData.Count, count);
                }
            }
            catch (Exception exception)
            {
                HaltTestOnError(exception, "Fatal while processing a notification.", null);
            }
        }
Example #9
0
        /// <summary>
        /// Processes a Publish repsonse from the server.
        /// </summary>
        void Session_Notification(Session session, NotificationEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(m_SessionNotification, session, e);
                return;
            }
            else if (!IsHandleCreated)
            {
                return;
            }

            try
            {
                // ignore notifications for other subscriptions.
                if (!Object.ReferenceEquals(m_subscription,  e.Subscription))
                {
                    return;
                }
                                
                // notify controls of the change.
                EventsCTRL.NotificationReceived(e);
                DataChangesCTRL.NotificationReceived(e);

                // update subscription status.
                UpdateStatus();
            }
            catch (Exception exception)
            {
				GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        /// <summary>
        /// Processes a new notification.
        /// </summary>
        public void NotificationReceived(NotificationEventArgs e)
        {
            // get the changes.
            List<MonitoredItemNotification> changes = new List<MonitoredItemNotification>();

            foreach (MonitoredItemNotification change in e.NotificationMessage.GetDataChanges(false))
            {
                if (m_monitoredItem != null)
                {
                    if (m_monitoredItem.ClientHandle != change.ClientHandle)
                    {
                        continue;
                    }
                }
                else
                {
                    if (m_subscription.FindItemByClientHandle(change.ClientHandle) == null)
                    {
                        continue;
                    }
                }

                changes.Add(change);
            }

            // check if nothing more to do.
            if (changes.Count == 0)
            {
                return;
            }

            int offset = changes.Count;

            if (m_showHistory)
            {
                // fill in earlier changes.
                foreach (ListViewItem listItem in ItemsLV.Items)
                {
                    MonitoredItemNotification change = listItem.Tag as MonitoredItemNotification;
                
                    if (change == null)
                    {
                        continue;
                    }

                    if (m_monitoredItem != null)
                    {
                        if (m_monitoredItem.ClientHandle != change.ClientHandle)
                        {
                            continue;
                        }
                    }

                    changes.Add(change);

                    if (changes.Count >= MaxChangeCount)
                    {
                        break;
                    }
                }

                // ensure the newest changes appear first.
                changes.Reverse();
            }

            UpdateChanges(changes, offset);
            AdjustColumns();
        }
Example #11
0
        void Session_Notification(Session session, NotificationEventArgs e)
        {
            lock (m_lock)
            {
		        if (m_messageCount == 0)
		        {
			        m_firstMessageTime = DateTime.UtcNow;
			        m_totalItemUpdateCount = 0;
                    m_itemUpdateCounts = new int[m_itemCount];
		        }

		        m_messageCount++;
                m_lastMessageTime = DateTime.UtcNow;

                int count = 0;

                for (int ii = 0; ii < e.NotificationMessage.NotificationData.Count; ii++)
                {
                    DataChangeNotification notification = e.NotificationMessage.NotificationData[ii].Body as DataChangeNotification;

                    if (notification == null)
                    {
                        continue;
                    }

                    for (int jj = 0; jj < notification.MonitoredItems.Count; jj++)
                    {
                        count++;
                        int clientHandle = (int)notification.MonitoredItems[jj].ClientHandle;

                        m_totalItemUpdateCount++;

                        if (clientHandle >= 0 && clientHandle < m_itemUpdateCounts.Length)
                        {
                            m_itemUpdateCounts[clientHandle]++;
                        }
                    }
                }

                // ReportMessage("OnDataChange. Time={0} ({3}), Count={1}/{2}", DateTime.UtcNow.ToString("mm:ss.fff"), count, m_totalItemUpdateCount, (m_lastMessageTime - m_firstMessageTime).TotalMilliseconds);
            }
        }
        private void Session_Notification(Session sender, NotificationEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(m_SessionNotification, sender, e);
                return;
            }
            else if (!IsHandleCreated)
            {
                return;
            }
            
            try
            {
                if (m_subscription != null)
                {
                    if (!Object.ReferenceEquals(m_subscription, e.Subscription))
                    {
                        return;
                    }
                }

                AddItem(new ItemData(e.Subscription, e.NotificationMessage));

                if (ItemsLV.Items.Count > MaxMessageCount)
                {
                    for (int i = 0; i < (ItemsLV.Items.Count - MaxMessageCount); i++)
                    {
                        ItemsLV.Items.RemoveAt(i);
                    }
                }
            }
            catch (Exception exception)
            {
				GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        /// <summary>
        /// Processes the response from a publish request.
        /// </summary>
        private void ProcessPublishResponse(
            ResponseHeader responseHeader,
            uint subscriptionId,
            UInt32Collection availableSequenceNumbers,
            bool moreNotifications,
            NotificationMessage notificationMessage)
        {
            Subscription subscription = null;

            // send notification that the server is alive.
            OnKeepAlive(m_serverState, responseHeader.Timestamp);

            // collect the current set if acknowledgements.
            lock (SyncRoot)
            {
                // clear out acknowledgements for messages that the server does not have any more.
                SubscriptionAcknowledgementCollection acknowledgementsToSend = new SubscriptionAcknowledgementCollection();

                for (int ii = 0; ii < m_acknowledgementsToSend.Count; ii++)
                {
                    SubscriptionAcknowledgement acknowledgement = m_acknowledgementsToSend[ii];

                    if (acknowledgement.SubscriptionId != subscriptionId)
                    {
                        acknowledgementsToSend.Add(acknowledgement);
                    }
                    else
                    {
                        if (availableSequenceNumbers == null || availableSequenceNumbers.Contains(acknowledgement.SequenceNumber))
                        {
                            acknowledgementsToSend.Add(acknowledgement);
                        }
                    }
                }

                // create an acknowledgement to be sent back to the server.
                if (notificationMessage.NotificationData.Count > 0)
                {
                    SubscriptionAcknowledgement acknowledgement = new SubscriptionAcknowledgement();

                    acknowledgement.SubscriptionId = subscriptionId;
                    acknowledgement.SequenceNumber = notificationMessage.SequenceNumber;

                    acknowledgementsToSend.Add(acknowledgement);
                }

                m_acknowledgementsToSend = acknowledgementsToSend;

                // find the subscription.
                foreach (Subscription current in m_subscriptions)
                {
                    if (current.Id == subscriptionId)
                    {
                        subscription = current;
                        break;
                    }
                }
            }

            // ignore messages with a subscription that has been deleted.
            if (subscription != null)
            {
                // update subscription cache.                                 
                subscription.SaveMessageInCache(
                    availableSequenceNumbers,
                    notificationMessage,
                    responseHeader.StringTable);

                // raise the notification.
                lock (m_eventLock)
                {
                    NotificationEventArgs args = new NotificationEventArgs(subscription, notificationMessage, responseHeader.StringTable);

                    if (m_Publish != null)
                    {
                        Task.Run(() =>
                        {
                            OnRaisePublishNotification(args);
                        });
                    }
                }
            }
        }
        private void Session_Notification(Session sender, NotificationEventArgs e)
        {
            try
            {
                if (m_subscription != null)
                {
                    if (!Object.ReferenceEquals(m_subscription, e.Subscription))
                    {
                        return;
                    }
                }

                // get the current control contents.
                List<ItemData> tags = new List<ItemData>();

                foreach (ListViewItem item in ItemsLV.Items)
                {
                    ItemData tag = item.Tag as ItemData;

                    if (tag != null)
                    {
                        tags.Add(tag);
                    }
                }

                tags.Insert(0, new ItemData(e.Subscription, e.NotificationMessage));

                // update control.
                Update(tags);
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception);
            }
        }