/// <summary> /// create monitored items for each notifier node identified by the area string(s) added using SetFilter. /// </summary> /// <param name="AreaNames">The List of Area names</param> public void AddMonitoredItems(List<String> AreaNames) { try { List<string> szAreas = new List<string>(); foreach (string areaName in AreaNames) { int wildCardLocation = 0; if ((wildCardLocation = areaName.IndexOfAny(new char[] { '*', '?', '#', '[', ']', '!', '-' })) != -1) { // The string contains wildcards List<string> items = ProcessWildCardAreaName(areaName, wildCardLocation); if (items.Count == 0) { throw ComUtils.CreateComException("AddMonitoredItems", ResultIds.E_INVALIDARG); } foreach (string item in items) { AreaNode areaNode; // Check to see if this area was already added to the subscription as a monitored item if (!m_AreaNodes.TryGetValue(item, out areaNode)) szAreas.Add(item); else // increment reference count for this area ++areaNode.RefCount; } } else { // Check to see if this area was already added to the subscription as a monitored item AreaNode areaNode; if (!m_AreaNodes.TryGetValue(areaName, out areaNode)) szAreas.Add(areaName); else // increment reference count for this area ++areaNode.RefCount; } } if (szAreas.Count == 0) return; // Translate the fully qualified area names to NodeIds BrowsePathResultCollection results = GetBrowseTargets(szAreas); for (int ii = 0; ii < results.Count; ii++) { if (StatusCode.IsBad(results[ii].StatusCode)) { throw ComUtils.CreateComException("AddMonitoredItems", ResultIds.E_INVALIDARG); } // Add monitored item to the subscription BrowsePathTarget target = results[ii].Targets[0]; NodeId node; node = ExpandedNodeId.ToNodeId(target.TargetId, m_session.NamespaceUris); MonitoredItem monitoredItem = CreateMonitoredItemForEvents(node); m_Subscription.AddItem(monitoredItem); m_Subscription.ApplyChanges(); // Add this area to the AreaNode and then add the AreaNode to the two dictionary elements AreaNode areaNode = new AreaNode(); areaNode.AreaName = szAreas[ii]; ++areaNode.RefCount; areaNode.MonitoredItem = monitoredItem; m_notifiers.Add(monitoredItem.ClientHandle, areaNode); m_AreaNodes.Add(szAreas[ii], areaNode); } } catch (COMException ex) { throw ComUtils.CreateComException(ex); } catch (Exception ex) { Utils.Trace(ex, "Unexpected error in AddMonitoredItems"); throw ComUtils.CreateComException(ex); } }
/// <summary> /// Called when a session is created with a server. /// </summary> private void OnSessionCreated(Session session) { string commonAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); string configFileName = Utils.Format(@"{0}\OPC Foundation\ComPseudoServers\{1}.internal.xml", commonAppDataPath, m_clsid); lock (m_lock) { try { m_session = null; m_Subscription = null; m_AreaNodes.Clear(); m_session = session; // load the config file. if (File.Exists(configFileName)) { XmlSerializer ser = new XmlSerializer(typeof(Configuration)); TextReader reader = new StreamReader(configFileName); m_configFile = (Configuration)ser.Deserialize(reader); reader.Close(); // set the ActualDataType property for (int ii = 0; ii < m_configFile.Attributes.Length - 1; ii++) { NodeId nodeid = new NodeId(m_configFile.Attributes[ii].strDataTypeNodeId); m_configFile.Attributes[ii].ActualDataType = DataTypes.GetSystemType(nodeid, EncodeableFactory.GlobalFactory); } } else { InitConfigInfo(configFileName); } // Obtain the current server table, generate index mapping tables (client->server, server->client) // and update the client side namespace table if necessary due to server changes GenerateNamespaceIndexMappings(m_clsid); // The client side namespace table may have been updated if the server namespace table // has changed therefore save the updated client table. SaveConfigInfo(configFileName); // fetch type tree. m_session.FetchTypeTree(Opc.Ua.ObjectTypeIds.BaseEventType); m_session.FetchTypeTree(Opc.Ua.ReferenceTypeIds.References); //Create UA Event Subscription if none configured in the registry m_Subscription = new Opc.Ua.Client.Subscription(m_session.DefaultSubscription); m_Subscription.PublishingEnabled = true; m_Subscription.PublishingInterval = m_configFile.ProxySubscriptionSettings.PublishingInterval; m_Subscription.KeepAliveCount = m_configFile.ProxySubscriptionSettings.KeepAliveCount; m_Subscription.LifetimeCount = m_configFile.ProxySubscriptionSettings.LifetimeCount; m_Subscription.Priority = m_configFile.ProxySubscriptionSettings.Priority; m_Subscription.MaxNotificationsPerPublish = m_configFile.ProxySubscriptionSettings.MaxNotificationsPerPublish; m_session.AddSubscription(m_Subscription); m_Subscription.Create(); m_KeepAliveInterval = (int)(m_Subscription.CurrentPublishingInterval * m_Subscription.CurrentKeepAliveCount); // Add Server object as the only monitored item to this subscription NodeId nodeId_Server = new NodeId(Opc.Ua.Objects.Server); MonitoredItem monitoredItem = CreateMonitoredItemForEvents(nodeId_Server); m_Subscription.AddItem(monitoredItem); m_Subscription.ApplyChanges(); AreaNode areaNode = new AreaNode(); areaNode.AreaName = "/"; ++areaNode.RefCount; areaNode.MonitoredItem = monitoredItem; m_notifiers.Add(monitoredItem.ClientHandle, areaNode); m_AreaNodes.Add("/", areaNode); m_Subscription.Session.Call( Opc.Ua.ObjectTypes.ConditionType, Methods.ConditionType_ConditionRefresh, m_Subscription.Id); } catch (Exception e) { Utils.Trace(e, "Initializing server after create."); throw ComUtils.CreateComException(e); } } }