private bool DoKeepAliveTest()
{
bool success = true;
double increment = MaxProgress/3;
double position = 0;
m_keepAliveCount = 0;
int currentKeepAlive = Session.KeepAliveInterval;
List<Subscription> subscriptions = new List<Subscription>();
KeepAliveEventHandler handler = new KeepAliveEventHandler(Session_KeepAlive);
try
{
Session.KeepAlive += handler;
// add several subscriptions with long publish intervals.
for (int publishingInterval = 10000; publishingInterval <= 20000; publishingInterval += 1000)
{
Subscription subscription = new Subscription();
subscription.MaxMessageCount = 100;
subscription.LifetimeCount = 100;
subscription.KeepAliveCount = 10;
subscription.PublishingEnabled = true;
subscription.PublishingInterval = publishingInterval;
MonitoredItem monitoredItem = new MonitoredItem();
monitoredItem.StartNodeId = VariableIds.Server_ServerStatus_CurrentTime;
monitoredItem.AttributeId = Attributes.Value;
monitoredItem.SamplingInterval = -1;
monitoredItem.QueueSize = 0;
monitoredItem.DiscardOldest = true;
subscription.AddItem(monitoredItem);
Session.AddSubscription(subscription);
subscription.Create();
subscriptions.Add(subscription);
}
// get a value to read.
ReadValueId nodeToRead = new ReadValueId();
nodeToRead.NodeId = VariableIds.Server_ServerStatus;
nodeToRead.AttributeId = Attributes.Value;
ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
nodesToRead.Add(nodeToRead);
int testDuration = 5000;
// make sure the keep alives come at the expected rate.
for (int keepAliveInterval = 500; keepAliveInterval < 2000; keepAliveInterval += 500)
{
m_keepAliveCount = 0;
DateTime start = DateTime.UtcNow;
DataValueCollection results = null;
DiagnosticInfoCollection diagnosticsInfos = null;
Session.Read(
null,
0,
TimestampsToReturn.Neither,
nodesToRead,
out results,
out diagnosticsInfos);
ClientBase.ValidateResponse(results, nodesToRead);
ClientBase.ValidateDiagnosticInfos(diagnosticsInfos, nodesToRead);
ServerStatusDataType status = ExtensionObject.ToEncodeable(results[0].Value as ExtensionObject) as ServerStatusDataType;
if (status == null)
{
Log("Server did not return a valid ServerStatusDataType structure. Value={0}, Status={1}", results[0].WrappedValue, results[0].StatusCode);
return false;
}
if ((DateTime.UtcNow - start).TotalSeconds > 1)
{
Log("Unexpected delay reading the ServerStatus structure. Delay={0}s", (DateTime.UtcNow - start).TotalSeconds);
return false;
}
Log("Setting keep alive interval to {0}ms.", keepAliveInterval);
Session.KeepAliveInterval = keepAliveInterval;
if (m_errorEvent.WaitOne(testDuration, false))
{
Log("Unexpected error waiting for session keep alives. {0}", m_error.ToLongString());
return false;
}
if (m_keepAliveCount < testDuration / keepAliveInterval)
{
Log("Missing session keep alives. Expected={0}, Actual={1}", testDuration / keepAliveInterval, m_keepAliveCount);
return false;
}
Log("{0} keep alives received in {1}ms.", m_keepAliveCount, testDuration);
position += increment;
ReportProgress(position);
}
ReportProgress(MaxProgress);
}
finally
{
Session.RemoveSubscriptions(subscriptions);
Session.KeepAliveInterval = currentKeepAlive;
Session.KeepAlive -= handler;
}
return success;
}