OPC UA Client захватывает значения потерянных элементов с сервера UA после ошибки отключения / подключения? - PullRequest
0 голосов
/ 15 октября 2018

Я создаю OPC UA Client, используя OPC Foundation SDK.Я могу создать подписку, содержащую несколько отслеживаемых элементов.

На сервере OPC UA эти отслеживаемые элементы постоянно меняют значение (каждую секунду или около того).

Я хочу отключить клиента (смоделироватьсоединение разорвано), поддержите подписку и подождите некоторое время.Затем я снова подключаюсь, возвращая свои подписки, но я также хочу, чтобы все отслеживаемые значения элементов были поставлены в очередь во время разъединения.Прямо сейчас я получаю только последнее значение сервера при переподключении.

Я устанавливаю размер очереди:

monitoredItem.QueueSize = 100;

Чтобы имитировать ошибку соединения, яустановили «удалить подписку» в false на ClosesSession: m_session.CloseSession (new RequestHeader (), false);

Мой вопрос заключается в том, как захватить содержимое очереди после ошибки отключения / подключения ???

Должны ли «потерянные значения» автоматически быть «новыми MonitoredItem_Notification» при повторном подключении клиента?

Должен ли SubscriptionId быть таким же, как до разрыва соединения?

Должен лиsessionId будет таким же или новый SessionId позволит med сохранить существующие подписки?Как лучше всего симулировать ошибку соединения?

Многие вопросы: -)

Пример кода, в котором я создаю подписку, содержащую некоторые MonitoredItems и метод события MonitoredItem_Notification.

Любой OPC UA Гуру там ??

if (node.Displayname == "node to monitor")
{
   MonitoredItem mon = CreateMonitoredItem((NodeId)node.reference.NodeId, node.Displayname);
   m_subscription.AddItem(mon);
   m_subscription.ApplyChanges();
}
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;
        }


            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);
        }
    }e here

1 Ответ

0 голосов
/ 15 октября 2018

Я не знаю, сколько из этого, если таковой имеется, SDK, который вы используете, делает для вас, но подход при переподключении, как правило:

  1. попытаться возобновить (повторно активировать) ваш старый сеанс.Если это успешно, ваши подписки уже будут существовать, и все, что вам нужно сделать, это отправить дополнительные запросы PublishRequest.Поскольку вы пытаетесь протестировать, закрыв сеанс, это, вероятно, не сработает.

  2. создайте новый сеанс, а затем вызовите службу TransferSubscription, чтобы перенести предыдущие подписки в новый сеанс.Затем вы можете начать отправку PublishRequests, и вы получите уведомления в очереди.

Опять же, в зависимости от того, какой стек / SDK / инструментарий вы используете, некоторые из них или ничего из этого не могут быть обработаны для вас.

...