diff --git a/Libraries/Opc.Ua.Client/ISession.cs b/Libraries/Opc.Ua.Client/ISession.cs index 91bf571a70..bf26be5a83 100644 --- a/Libraries/Opc.Ua.Client/ISession.cs +++ b/Libraries/Opc.Ua.Client/ISession.cs @@ -296,15 +296,17 @@ namespace Opc.Ua.Client /// Load the list of subscriptions saved in a file. /// /// The stream. + /// Load the subscriptions for transfer after load. /// The list of loaded subscriptions - IEnumerable Load(Stream stream); + IEnumerable Load(Stream stream, bool transferSubscriptions = false); /// /// Load the list of subscriptions saved in a file. /// /// The file path. + /// Load the subscriptions for transfer after load. /// The list of loaded subscriptions - IEnumerable Load(string filePath); + IEnumerable Load(string filePath, bool transferSubscriptions = false); /// /// Updates the local copy of the server's namespace uri and server uri tables. diff --git a/Libraries/Opc.Ua.Client/Session.cs b/Libraries/Opc.Ua.Client/Session.cs index e8eb1b40d1..39fc333e11 100644 --- a/Libraries/Opc.Ua.Client/Session.cs +++ b/Libraries/Opc.Ua.Client/Session.cs @@ -1412,8 +1412,9 @@ namespace Opc.Ua.Client /// Load the list of subscriptions saved in a stream. /// /// The stream. + /// Load the subscriptions for transfer after load. /// The list of loaded subscriptions - public IEnumerable Load(Stream stream) + public IEnumerable Load(Stream stream, bool transferSubscriptions = false) { // secure settings XmlReaderSettings settings = Utils.DefaultXmlReaderSettings(); @@ -1425,6 +1426,15 @@ namespace Opc.Ua.Client SubscriptionCollection subscriptions = (SubscriptionCollection)serializer.ReadObject(reader); foreach (Subscription subscription in subscriptions) { + if (!transferSubscriptions) + { + // ServerId must be reset if the saved list of subscriptions + // is not used to transfer a subscription + foreach (var monitoredItem in subscription.MonitoredItems) + { + monitoredItem.ServerId = 0; + } + } AddSubscription(subscription); } return subscriptions; @@ -1435,12 +1445,13 @@ namespace Opc.Ua.Client /// Load the list of subscriptions saved in a file. /// /// The file path. + /// Load the subscriptions for transfer after load. /// The list of loaded subscriptions - public IEnumerable Load(string filePath) + public IEnumerable Load(string filePath, bool transferSubscriptions = false) { using (FileStream stream = File.OpenRead(filePath)) { - return Load(stream); + return Load(stream, transferSubscriptions); } } diff --git a/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs b/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs index b353b03cac..5ccb9f8677 100644 --- a/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs +++ b/Tests/Opc.Ua.Client.Tests/SubscriptionTest.cs @@ -35,7 +35,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using NUnit.Framework; -using Opc.Ua.Server.Tests; namespace Opc.Ua.Client.Tests { @@ -131,15 +130,18 @@ namespace Opc.Ua.Client.Tests new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusState", StartNodeId = VariableIds.Server_ServerStatus_State - } + }, }; + + var simulatedNodes = GetTestSetSimulation(Session.NamespaceUris); + list2.AddRange(CreateMonitoredItemTestSet(subscription, simulatedNodes)); list2.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => { foreach (var value in item.DequeueValues()) { TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode); } }); - subscription.AddItems(list); + subscription.AddItems(list2); subscription.ApplyChanges(); subscription.SetPublishingMode(false); Assert.False(subscription.PublishingEnabled); @@ -221,15 +223,18 @@ namespace Opc.Ua.Client.Tests new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusState", StartNodeId = VariableIds.Server_ServerStatus_State - } + }, }; + + var simulatedNodes = GetTestSetSimulation(Session.NamespaceUris); + list2.AddRange(CreateMonitoredItemTestSet(subscription, simulatedNodes)); list2.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => { foreach (var value in item.DequeueValues()) { TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode); } }); - subscription.AddItems(list); + subscription.AddItems(list2); await subscription.ApplyChangesAsync().ConfigureAwait(false); await subscription.SetPublishingModeAsync(false).ConfigureAwait(false); Assert.False(subscription.PublishingEnabled); @@ -261,7 +266,7 @@ namespace Opc.Ua.Client.Tests [Test, Order(200)] - public void LoadSubscription() + public async Task LoadSubscriptionAsync() { if (!File.Exists(m_subscriptionTestXml)) Assert.Ignore("Save file {0} does not exist yet", m_subscriptionTestXml); @@ -270,22 +275,36 @@ namespace Opc.Ua.Client.Tests Assert.NotNull(subscriptions); Assert.IsNotEmpty(subscriptions); + int valueChanges = 0; + foreach (var subscription in subscriptions) { + var list = subscription.MonitoredItems.ToList(); + list.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => { + foreach (var value in item.DequeueValues()) + { + valueChanges++; + TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode); + } + }); + Session.AddSubscription(subscription); - subscription.Create(); + await subscription.CreateAsync().ConfigureAwait(false); } - Thread.Sleep(5000); + await Task.Delay(5000); - foreach (var subscription in subscriptions) + TestContext.Out.WriteLine("{0} value changes.", valueChanges); + + Assert.GreaterOrEqual(valueChanges, 10); + + foreach (var subscription in Session.Subscriptions) { OutputSubscriptionInfo(TestContext.Out, subscription); } - var result = Session.RemoveSubscriptions(subscriptions); + var result = await Session.RemoveSubscriptionsAsync(subscriptions).ConfigureAwait(false); Assert.True(result); - } [Theory, Order(300)] @@ -477,7 +496,7 @@ namespace Opc.Ua.Client.Tests /// /// The origin session gets network disconnected, /// after transfer available sequence numbers are - /// just ackoledged. + /// just acknoledged. /// DisconnectedAck, /// @@ -586,8 +605,8 @@ namespace Opc.Ua.Client.Tests var transferSubscriptions = new SubscriptionCollection(); if (transferType != TransferType.KeepOpen) { - // load - transferSubscriptions.AddRange(targetSession.Load(filePath)); + // load subscriptions for transfer + transferSubscriptions.AddRange(targetSession.Load(filePath, true)); // hook notifications for log output int ii = 0;