c# - OPC UA 客户端 KeepAlive
问题描述
亲爱的 OPC UA 社区!
我想使用来自OPC Foundation和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.");
}
}
哪个例子是正确的?对于这些选项中的任何一个,服务器是否会丢弃对监视项目的订阅?我可以依靠这些示例来创建可靠的客户端,还是缺少一些东西?
感谢您的任何帮助!
解决方案
这是查看参考客户端和参考服务器实施的最佳方式(例如,通过“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);
}
}
推荐阅读
- uml - 我应该把用例图中包含的用例放在我的类图中吗?
- php - 如何计算年、月和日的年龄
- python - 无法以编程方式下载远程 Maven 存储库中的所有文件
- python-3.x - Python3 网页抓取,csv 输出显示 TypeError: can only concatenate list (not "str") to list
- python - 即使此条件的“IF”部分为真,只有 else 部分正在执行。无论输入是什么,只有 Else 执行
- javascript - 如何在 Greasemonkey 中重定向到我的 youtube 订阅页面?
- javascript - v-img 没有在功能组件中呈现 - Vuetify 2
- node.js - 表单发送空对象
- sql - 从规范化数据库中选择时重复行
- r - 在 optim() 中实现要优化的参数的标准