Интеграция open62541 в существующий цикл событий libev - PullRequest
0 голосов
/ 16 января 2019

У меня есть приложение, которое широко использует libev для цикла обработки событий. Теперь я хотел бы добавить функциональность сервера OPC UA, но не уверен, как лучше интегрировать цикл событий open62541 в libev.

На ум приходят следующие возможности:

  1. Вызовите UA_Server_run_iterate из цикла событий libev с временем waitInternal, равным 0. Это может означать, что сервер никогда не будет спать (опрос open62541 в ev_idle), или запрос от клиента OPC UA будет иметь дополнительную задержку до 50 мс (максимальное время ожидания по умолчанию open62541).
  2. Патч open62541, чтобы разрешить поиск файловых дескрипторов, используемых в настоящее время (serverSockets и соединения) сетевым уровнем сервера. Это позволило бы добавить события libev для этих файловых дескрипторов, которые, в свою очередь, могли бы опрашивать UA_Server_run_iterate только при необходимости.
  3. Реализация пользовательского сетевого уровня сервера, который использует libev. Кажется, это подразумевает некоторое дублирование кода ... Есть ли примеры / учебные пособия для реализации пользовательского сетевого уровня?
  4. Запустить цикл событий open62541 в отдельном потоке. Я действительно очень хочу этого избежать, поскольку вся цель системы событий, такой как libev, состоит в том, чтобы избежать проблем, связанных с асинхронной работой. Например, все обратные вызовы из open62541 должны были бы синхронизироваться с основным потоком libev.

Какой из вышеперечисленных вариантов вы бы назвали «лучшим» с точки зрения сложности и производительности?

Можете ли вы назвать какие-либо другие варианты, не перечисленные выше?


Также опубликовано в списке рассылки open62541.

1 Ответ

0 голосов
/ 16 января 2019

Я бы порекомендовал либо вариант 1, либо вариант 2. (Отказ от ответственности: я один из разработчиков ядра open62541)

  1. Вызов UA_Server_run_iterate из цикла событий libev с временем ожиданияInInternal, равным 0. Это может означать, что сервер никогда не сможет спать (опрос open62541 в ev_idle), или что запросы от клиента OPC UA будут испытывать дополнительную задержку до 50 мс (максимальное время ожидания по умолчанию open62541).

На данный момент это, вероятно, лучший вариант, который вы могли бы выбрать. Вы можете вызывать UA_Server_run_iterate через фиксированный интервал, например каждые 10 мс, в зависимости от требований приложения. Все остальные опции требуют исправления 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

...