OPC-UA open62541 sdk Динамически добавлять узлы переменных после запуска сервера - PullRequest
1 голос
/ 14 марта 2019

При чтении документации и примеров OPC-UA и OPC-UA open62541 sdk узлы переменных всегда добавляются перед оператором для запуска сервера. Можно ли добавить их после запуска сервера?Если я изменю порядок операторов, которые не работают.

Подумайте о следующей ситуации: мне нужно выполнить несколько http-запросов, как только мы запустим приложение / программное обеспечение (не сервер) асинхронно.Затем сервер запускается, после того как мой http-запрос выполнен, я добавил переменные узлы на основе информации, возвращаемой из Интернета.

Я добавил несколько комментариев к коду, чтобы уточнить, что я пытаюсь сделать.

int main() {
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    UA_ServerConfig *config = UA_ServerConfig_new_default();
    UA_Server *server = UA_Server_new(config);

    // If I put this statement after the other statement:
    // UA_StatusCode retval = UA_Server_run(server, &running);
    // The variables are not added.
    addVariable(server);

    // I would like to add some variables nodes after this statement, 
    // for example, like I said I request some information online 
    // and I will add the nodes after return from this request asynchronous.
    UA_StatusCode retval = UA_Server_run(server, &running);
    UA_Server_delete(server);
    UA_ServerConfig_delete(config);
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Да, возможно использовать UA_Server_addVariableNode, поскольку вы уже используете его (вероятно) в addVariable(). Я думаю, ваш код основан на https://github.com/open62541/open62541/blob/master/examples/tutorial_server_variable.c

Простое изменение порядка кода не работает, так как

UA_StatusCode retval = UA_Server_run(server, &running);

блокируется.

Вам нужно изменить это, чтобы использовать итеративный подход:

UA_StatusCode retval = UA_Server_run_startup(server);
if(retval != UA_STATUSCODE_GOOD)
   return 1;

while(running) {
    UA_UInt16 timeout = UA_Server_run_iterate(server, waitInternal);

    // HERE you can add any node to the server you like.
    // e.g. call addVariable2().
    // Make sure that you only call it once in the loop.

    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = timeout * 1000;
    select(0, NULL, NULL, NULL, &tv);
}
retval = UA_Server_run_shutdown(server);

Обратите внимание, что open62541 в настоящее время не поддерживает многопоточность. Если вы добавляете переменные в другой поток, вам нужно убедиться, что вы мьютексуете доступ к объекту server.

Приведенный выше пример основан на: https://github.com/open62541/open62541/blob/master/examples/server_mainloop.c

Другой подход - просто запустить другой поток, который обрабатывает ваши асинхронные запросы, а затем вызывает UA_Server_addVariableNode в отдельном потоке. Тем не менее убедитесь, что вы используете мьютексы.

0 голосов
/ 15 марта 2019

Возможно, есть решение, но оно должно запускаться клиентом OPC UA.

Спецификация OPC UA определяет некоторые службы, позволяющие клиенту добавлять / удалять узлы или ссылки (AddNodes, * 1004).*, DeleteNodes, DeleteReferences)

И ваш клиент OPC UA, и сервер должны поддерживать эти службы.

...