10/12/2015
Hi,
A question.
I am building a OPC UA Client. I am able to create a subscription containing some Monitoreditems.
On the OPC UA server these monitored items change value constantly.
I want to disconnect the client and wait for a while. Then I reconnect having my subscriptions back, but I also want all the monitored Item values queued up during the disconnect.
I am setting a queuesize:
monitoredItem.QueueSize = 100;
How to capture the content of the queue after a disconnect/connection error???
Should the 'lost values' be "new MonitoredItem_Notification" automatically when I reconnect?
Should the SubscriptionId be the same as before the connection was broken?
Should the sessionId be the same or will a new SessionId let med keep the existing subscriptions?
Many questions 🙂
if (node.Displayname == “The node I want to monitor”)
{
MonitoredItem mon = CreateMonitoredItem((NodeId)node.reference.NodeId, node.Displayname);
m_subscription.AddItem(mon);
m_subscription.ApplyChanges();
subscribedClientNodes.Add(node);
}
————
private MonitoredItem CreateMonitoredItem(NodeId nodeId, string displayName)
{
if (m_subscription == null)
{
m_subscription = new Subscription(m_session.DefaultSubscription);
m_subscription.PublishingEnabled = true;
m_subscription.PublishingInterval = 3000;//1000;
m_subscription.KeepAliveCount = 10;
m_subscription.LifetimeCount = 10;
m_subscription.MaxNotificationsPerPublish = 1000;
m_subscription.Priority = 100;
bool cache = m_subscription.DisableMonitoredItemCache;
m_session.AddSubscription(m_subscription);
m_subscription.Create();
}
// add the new monitored item.
MonitoredItem monitoredItem = new MonitoredItem(m_subscription.DefaultItem);
//Each time a monitored item is sampled, the server evaluates the sample using a filter defined for each monitoreditem.
//The server uses the filter to determine if the sample should be reported. The type of filter is dependent on the type of item.
//DataChangeFilter for Variable, Eventfilter when monitoring Events. etc
//MonitoringFilter f = new MonitoringFilter();
//DataChangeFilter f = new DataChangeFilter();
//f.DeadbandValue
monitoredItem.StartNodeId = nodeId;
monitoredItem.AttributeId = Attributes.Value;
monitoredItem.DisplayName = displayName;
//Disabled, Sampling, (Report (includes sampling))
monitoredItem.MonitoringMode = MonitoringMode.Reporting;
//How often the Client wish to check for new values on the server. Must be 0 if item is an event.
//If a negative number the SamplingInterval is set equal to the PublishingInterval (inherited)
//The Subscriptions KeepAliveCount should always be longer than the SamplingInterval/PublishingInterval
monitoredItem.SamplingInterval = 500;
//Number of samples stored on the server between each reporting
monitoredItem.QueueSize = 100;
monitoredItem.DiscardOldest = true;//Discard oldest values when full
monitoredItem.CacheQueueSize = 100;
monitoredItem.Notification += m_MonitoredItem_Notification;
if (ServiceResult.IsBad(monitoredItem.Status.Error))
{
return null;
}
return monitoredItem;
}
——
private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e);
return;
}
try
{
if (m_session == null)
{
return;
}
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
if (notification == null)
{
return;
}
foreach(MonitoredItem mon in monitoredItem.Subscription.MonitoredItems)
{
MonitoredItemNotification v = mon.LastValue as MonitoredItemNotification;
richTextBox1.AppendText(“
Iteration: ” + mon.DisplayName + ” value: ” + v.Value.Value + “sTime: “+v.Value.SourceTimestamp+” status: ” + mon.Status.QueueSize.ToString());
}
string sess = m_session.SessionId.Identifier.ToString();
string s = string.Format(“
MonitoredItem: {0}\t Value: {1}\t Status: {2}\t SourceTimeStamp: {3}”, monitoredItem.DisplayName, (notification.Value.WrappedValue.ToString().Length == 1) ? notification.Value.WrappedValue.ToString() + ” ” : notification.Value.WrappedValue.ToString(), notification.Value.StatusCode.ToString(), notification.Value.SourceTimestamp.ToLocalTime().ToString(“HH:mm:ss.fff”));
richTextBox1.AppendText(s + “
SessionId: ” + sess);
}
catch (Exception exception)
{
ClientUtils.HandleException(this.Text, exception);
}
}
Moderators-Specifications
Moderators-Companion
Moderators-Implementation
Moderators-Certification
Moderators-COM
02/24/2014
So a couple of points
- code question should be posted to GitHub
- A client, if it gets disconnect - say do to an network interrupt - can reconnect to the server (new session) and reclaim the subscription. The limit on this is the subscription timeout period. The new session has to have the same security content as the original session.
-if the goal is to be able to disconnect the client for a period of time and then reconnect, the server really should support DurableSubscription. See the specification for additional details.
Paul
Paul Hunkar - DSInteroperability
1 Guest(s)