Я бы порекомендовал либо вариант 1, либо вариант 2. (Отказ от ответственности: я один из разработчиков ядра open62541)
- Вызов UA_Server_run_iterate из цикла событий libev с временем ожиданияInInternal, равным 0. Это может означать, что сервер никогда не сможет спать (опрос open62541 в ev_idle), или что запросы от клиента OPC UA будут испытывать дополнительную задержку до 50 мс (максимальное время ожидания по умолчанию open62541).
На данный момент это, вероятно, лучший вариант, который вы могли бы выбрать. Вы можете вызывать UA_Server_run_iterate через фиксированный интервал, например каждые 10 мс, в зависимости от требований приложения. Все остальные опции требуют исправления open62541, и в настоящее время во внутреннем API многое происходит, так как многие функции добавляются в настоящее время. Также посмотрите мою заметку в конце!
- Патч open62541, чтобы разрешить поиск файловых дескрипторов, используемых в настоящее время (serverSockets и соединения) сетевым уровнем сервера. Это позволит добавить события 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