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