OPC UA 客户端 KeepAlive
OPC UA client KeepAlive
尊敬的 OPC UA 社区!
我想使用 OPC Foundation and MS Azure 中的示例为我们的软件开发 OPC UA 客户端。我担心这些例子之间的区别。在第一个示例中,使用 ReconnectHandler:
在 KeepAlive 失败后重新连接
private void Client_KeepAlive(Session sender, KeepAliveEventArgs e)
{
if (e.Status != null && ServiceResult.IsNotGood(e.Status))
{
Console.WriteLine("{0} {1}/{2}", e.Status, sender.OutstandingRequestCount, sender.DefunctRequestCount);
if (reconnectHandler == null)
{
Console.WriteLine("--- RECONNECTING ---");
reconnectHandler = new SessionReconnectHandler();
reconnectHandler.BeginReconnect(sender, ReconnectPeriod * 1000, Client_ReconnectComplete);
}
}
}
private void Client_ReconnectComplete(object sender, EventArgs e)
{
// ignore callbacks from discarded objects.
if (!Object.ReferenceEquals(sender, reconnectHandler))
{
return;
}
session = reconnectHandler.Session;
reconnectHandler.Dispose();
reconnectHandler = null;
Console.WriteLine("--- RECONNECTED ---");
}
第二个,会话断开并重新创建:
private void StandardClient_KeepAlive(Session session, KeepAliveEventArgs e)
{
// ignore if we are shutting down
if (ShutdownTokenSource.IsCancellationRequested == true)
{
return;
}
if (e != null && session != null && session.ConfiguredEndpoint != null && OpcUaClientSession != null)
{
try
{
if (!ServiceResult.IsGood(e.Status))
{
Logger.Warning($"Session endpoint: {session.ConfiguredEndpoint.EndpointUrl} has Status: {e.Status}");
Logger.Information($"Outstanding requests: {session.OutstandingRequestCount}, Defunct requests: {session.DefunctRequestCount}");
Logger.Information($"Good publish requests: {session.GoodPublishRequestCount}, KeepAlive interval: {session.KeepAliveInterval}");
Logger.Information($"SessionId: {session.SessionId}");
if (State == SessionState.Connected)
{
MissedKeepAlives++;
Logger.Information($"Missed KeepAlives: {MissedKeepAlives}");
if (MissedKeepAlives >= OpcKeepAliveDisconnectThreshold)
{
Logger.Warning($"Hit configured missed keep alive threshold of {OpcKeepAliveDisconnectThreshold}. Disconnecting the session to endpoint {session.ConfiguredEndpoint.EndpointUrl}.");
session.KeepAlive -= StandardClient_KeepAlive;
Task t = Task.Run(async () => await DisconnectAsync());
}
}
}
else
{
if (MissedKeepAlives != 0)
{
// reset missed keep alive count
Logger.Information($"Session endpoint: {session.ConfiguredEndpoint.EndpointUrl} got a keep alive after {MissedKeepAlives} {(MissedKeepAlives == 1 ? "was" : "were")} missed.");
MissedKeepAlives = 0;
}
}
}
catch (Exception ex)
{
Logger.Error(ex, $"Error in keep alive handling for endpoint '{session.ConfiguredEndpoint.EndpointUrl}'. (message: '{ex.Message}'");
}
}
else
{
Logger.Warning("Keep alive arguments seems to be wrong.");
}
}
哪个例子是正确的?对于这些选项中的任何一个,服务器是否会丢弃对监控项的订阅?我能否依靠这些示例来创建可靠的客户端,还是缺少某些内容?
感谢您的帮助!
这是查看 Reference Client and Reference Server 实施的最佳方式(例如通过“UA 快速启动应用程序”解决方案),因为它们已通过认证。如有疑问,请参考:
private void Session_KeepAlive(Session session, KeepAliveEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new KeepAliveEventHandler(Session_KeepAlive), session, e);
return;
}
try
{
// check for events from discarded sessions.
if (!Object.ReferenceEquals(session, m_session))
{
return;
}
// start reconnect sequence on communication error.
if (ServiceResult.IsBad(e.Status))
{
if (m_reconnectPeriod <= 0)
{
UpdateStatus(true, e.CurrentTime, "Communication Error ({0})", e.Status);
return;
}
UpdateStatus(true, e.CurrentTime, "Reconnecting in {0}s", m_reconnectPeriod);
if (m_reconnectHandler == null)
{
if (m_ReconnectStarting != null)
{
m_ReconnectStarting(this, e);
}
m_reconnectHandler = new SessionReconnectHandler();
m_reconnectHandler.BeginReconnect(m_session, m_reconnectPeriod * 1000, Server_ReconnectComplete);
}
return;
}
// update status.
UpdateStatus(false, e.CurrentTime, "Connected [{0}]", session.Endpoint.EndpointUrl);
// raise any additional notifications.
if (m_KeepAliveComplete != null)
{
m_KeepAliveComplete(this, e);
}
}
catch (Exception exception)
{
ClientUtils.HandleException(this.Text, exception);
}
}
尊敬的 OPC UA 社区!
我想使用 OPC Foundation and MS Azure 中的示例为我们的软件开发 OPC UA 客户端。我担心这些例子之间的区别。在第一个示例中,使用 ReconnectHandler:
在 KeepAlive 失败后重新连接 private void Client_KeepAlive(Session sender, KeepAliveEventArgs e)
{
if (e.Status != null && ServiceResult.IsNotGood(e.Status))
{
Console.WriteLine("{0} {1}/{2}", e.Status, sender.OutstandingRequestCount, sender.DefunctRequestCount);
if (reconnectHandler == null)
{
Console.WriteLine("--- RECONNECTING ---");
reconnectHandler = new SessionReconnectHandler();
reconnectHandler.BeginReconnect(sender, ReconnectPeriod * 1000, Client_ReconnectComplete);
}
}
}
private void Client_ReconnectComplete(object sender, EventArgs e)
{
// ignore callbacks from discarded objects.
if (!Object.ReferenceEquals(sender, reconnectHandler))
{
return;
}
session = reconnectHandler.Session;
reconnectHandler.Dispose();
reconnectHandler = null;
Console.WriteLine("--- RECONNECTED ---");
}
第二个,会话断开并重新创建:
private void StandardClient_KeepAlive(Session session, KeepAliveEventArgs e)
{
// ignore if we are shutting down
if (ShutdownTokenSource.IsCancellationRequested == true)
{
return;
}
if (e != null && session != null && session.ConfiguredEndpoint != null && OpcUaClientSession != null)
{
try
{
if (!ServiceResult.IsGood(e.Status))
{
Logger.Warning($"Session endpoint: {session.ConfiguredEndpoint.EndpointUrl} has Status: {e.Status}");
Logger.Information($"Outstanding requests: {session.OutstandingRequestCount}, Defunct requests: {session.DefunctRequestCount}");
Logger.Information($"Good publish requests: {session.GoodPublishRequestCount}, KeepAlive interval: {session.KeepAliveInterval}");
Logger.Information($"SessionId: {session.SessionId}");
if (State == SessionState.Connected)
{
MissedKeepAlives++;
Logger.Information($"Missed KeepAlives: {MissedKeepAlives}");
if (MissedKeepAlives >= OpcKeepAliveDisconnectThreshold)
{
Logger.Warning($"Hit configured missed keep alive threshold of {OpcKeepAliveDisconnectThreshold}. Disconnecting the session to endpoint {session.ConfiguredEndpoint.EndpointUrl}.");
session.KeepAlive -= StandardClient_KeepAlive;
Task t = Task.Run(async () => await DisconnectAsync());
}
}
}
else
{
if (MissedKeepAlives != 0)
{
// reset missed keep alive count
Logger.Information($"Session endpoint: {session.ConfiguredEndpoint.EndpointUrl} got a keep alive after {MissedKeepAlives} {(MissedKeepAlives == 1 ? "was" : "were")} missed.");
MissedKeepAlives = 0;
}
}
}
catch (Exception ex)
{
Logger.Error(ex, $"Error in keep alive handling for endpoint '{session.ConfiguredEndpoint.EndpointUrl}'. (message: '{ex.Message}'");
}
}
else
{
Logger.Warning("Keep alive arguments seems to be wrong.");
}
}
哪个例子是正确的?对于这些选项中的任何一个,服务器是否会丢弃对监控项的订阅?我能否依靠这些示例来创建可靠的客户端,还是缺少某些内容?
感谢您的帮助!
这是查看 Reference Client and Reference Server 实施的最佳方式(例如通过“UA 快速启动应用程序”解决方案),因为它们已通过认证。如有疑问,请参考:
private void Session_KeepAlive(Session session, KeepAliveEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new KeepAliveEventHandler(Session_KeepAlive), session, e);
return;
}
try
{
// check for events from discarded sessions.
if (!Object.ReferenceEquals(session, m_session))
{
return;
}
// start reconnect sequence on communication error.
if (ServiceResult.IsBad(e.Status))
{
if (m_reconnectPeriod <= 0)
{
UpdateStatus(true, e.CurrentTime, "Communication Error ({0})", e.Status);
return;
}
UpdateStatus(true, e.CurrentTime, "Reconnecting in {0}s", m_reconnectPeriod);
if (m_reconnectHandler == null)
{
if (m_ReconnectStarting != null)
{
m_ReconnectStarting(this, e);
}
m_reconnectHandler = new SessionReconnectHandler();
m_reconnectHandler.BeginReconnect(m_session, m_reconnectPeriod * 1000, Server_ReconnectComplete);
}
return;
}
// update status.
UpdateStatus(false, e.CurrentTime, "Connected [{0}]", session.Endpoint.EndpointUrl);
// raise any additional notifications.
if (m_KeepAliveComplete != null)
{
m_KeepAliveComplete(this, e);
}
}
catch (Exception exception)
{
ClientUtils.HandleException(this.Text, exception);
}
}