1

我有一个现有的应用程序,它广泛使用 libev 的事件循环。我现在想添加 OPC UA 服务器功能,但不确定如何最好地将 open62541 事件循环集成到 libev 中。

想到以下可能性:

  1. UA_Server_run_iterate从时间为 0 的 libev 事件循环中调用。waitInternal这意味着服务器永远不会休眠(在 中轮询 open62541 ev_idle),或者来自 OPC UA 客户端的请求将经历高达 50 毫秒的额外延迟(默认open62541 的最大等待时间)。
  2. 修补 open62541 以允许服务器网络层检索当前正在使用的文件描述符(serverSockets 和连接)。这将允许为这些文件描述符添加 libev 事件,而这些事件又可以UA_Server_run_iterate仅在必要时轮询。
  3. 实现一个使用 libev 的自定义服务器网络层。这似乎意味着相当多的代码重复......是否有任何示例/教程用于实现自定义网络层?
  4. 在单独的线程中运行 open62541 事件循环。我真的真的很想避免这种情况,因为像 libev 这样的事件系统的全部目的是避免与异步操作相关的问题。例如,来自 open62541 的所有回调都必须与主 libev 线程同步。

就复杂性和性能而言,您认为上述哪个选项“最好”?

您能想到上面未列出的任何其他选项吗?


也张贴在 open62541 邮件列表上。

4

1 回答 1

0

我推荐选项 1 或选项 2。(免责声明:我是 open62541 的核心开发人员之一)

  1. 从 libev 事件循环中调用 UA_Server_run_iterate,waitInternal 时间为 0。这意味着服务器永远不会休眠(在 ev_idle 中轮询 open62541),或者来自 OPC UA 客户端的请求将经历高达 50 毫秒的额外延迟(open62541 的默认最大等待时间)。

目前,这可能是您可以选择的最佳选择。您可以根据应用程序的要求以固定间隔(例如,每 10 毫秒)调用 UA_Server_run_iterate。所有其他选项都需要修补 open62541 并且当前内部 API 中发生了很多事情,因为当前正在添加许多功能。也可以看看我最后的笔记!

  1. 修补 open62541 以允许服务器网络层检索当前正在使用的文件描述符(serverSockets 和连接)。这将允许为这些文件描述符添加 libev 事件,这反过来又可以仅在必要时轮询 UA_Server_run_iterate。

您可能不需要修补 open62541,因为如果网络层是 TCP 层,您可以通过服务器配置的网络层获取套接字的文件描述符:server->config.networkLayers[i].serverSockets[j]. 这也可能会引入大量维护工作,因为可能存在不同类型的网络层。例如,pubsub 使用 UDP,其中套接字存储在config->pubsubTransportLayers

  1. 实现一个使用 libev 的自定义服务器网络层。这似乎意味着相当多的代码重复......是否有任何示例/教程用于实现自定义网络层?

您可以使用插件接口实现自己的网络层,即编写自己的(https://github.com/open62541/open62541/blob/master/arch/ua_network_tcp.c)。由于这是使用内部 API,因此您可以期待大量的维护工作和补丁修复。-> 工作量太大

  1. 在单独的线程中运行 open62541 事件循环。我真的真的很想避免这种情况,因为像 libev 这样的事件系统的全部目的是避免与异步操作相关的问题。例如,来自 open62541 的所有回调都必须与主 libev 线程同步。

我会说这不是一个好选择,因为您引入了异步回调。


一般说明:

我们目前有一个内部草案和草图来重新设计网络接口,特别是为所有套接字 FD 选择一个。目前,我们有多个 FD 的多个选择。

还可以查看我们已经开始返工的以下 PR: https ://github.com/open62541/open62541/pull/2271

于 2019-01-16T13:29:46.500 回答