我有一个现有应用程序,该应用程序将libev广泛用于其事件循环。我现在想添加OPC UA服务器功能,但是不确定如何最好地将open62541事件循环集成到libev中。
想到以下可能性:
UA_Server_run_iterate
时间为0调用waitInternal
。这要么意味着服务器将永远无法休眠(在ev_idle
中轮询open62541),要么来自OPC UA客户端的请求将经历最多50ms的额外延迟(默认最大等待时间为open62541)。UA_Server_run_iterate
。就复杂性和性能而言,您会选择上述哪个选项中的“最佳”?
您能想到上面未列出的其他选项吗?
答案 0 :(得分:0)
我建议选项1或选项2。(免责声明:我是open62541的核心开发人员之一)
- 从libev事件循环内以waitInternal时间为0调用UA_Server_run_iterate。这要么意味着服务器永不休眠(在ev_idle中轮询open62541),要么来自OPC UA客户端的请求将经历额外的延迟。最长50ms(默认的最大等待时间为open62541)。
目前,这可能是您可以选择的最佳选择。您可以按固定间隔(例如,每10毫秒一次)调用UA_Server_run_iterate,具体取决于应用程序的要求。所有其他选项都需要修补open62541,并且由于目前正在添加许多功能,因此内部API中正在进行很多工作。最后也看看我的笔记!
- 修补open62541,以允许服务器网络层检索当前正在使用的文件描述符(serverSocket和连接)。这将允许为这些文件描述符添加libev事件,然后仅在必要时才轮询UA_Server_run_iterate。
您可能不需要修补open62541,因为如果网络层是TCP层,则可以通过服务器配置的网络层获取套接字的文件描述符:server->config.networkLayers[i].serverSockets[j]
。
由于可能存在不同种类的网络层,因此这也可能会引入很多维护工作。例如。 pubsub使用UDP,套接字存储在config->pubsubTransportLayers
- 实施一个使用libev的自定义服务器网络层。这似乎意味着大量的代码重复...是否有实现自定义网络层的示例/教程?
您可以使用插件接口实现自己的网络层,即编写自己的(https://github.com/open62541/open62541/blob/master/arch/ua_network_tcp.c)。由于这是使用内部API的,因此可以期望进行大量维护工作和修补程序。 ->工作太多
- 在单独的线程中运行open62541事件循环。我真的很想避免这种情况,因为诸如libev之类的事件系统的全部目的是避免与异步操作相关的问题。例如,来自open62541的所有回调都必须与libev主线程同步。
我想说这不是一个好选择,因为您引入了异步回调。
一般说明:
我们目前有一个内部草图和草图来重新设计网络接口,尤其是对所有套接字FD都有一个选择。当前,我们有多个FD的多个选择。
还可以查看以下PR,我们已经开始进行返工: https://github.com/open62541/open62541/pull/2271