学习open62541 --- [46] 集成到现有工程的办法

有时候需要把OPCUA Server集成到已有工程中来,对于open62541,我们一般使用UA_Server_run()去运行server,但是这个函数是个循环执行,会阻塞当前工程,那么就会有2种办法。


方法1 使用线程

单独开启一个线程去运行OPCUA Server,这个比较简单,不再细说


方法2 拆开运行

假设现有工程是使用定时器运行,例如reactor模式,那么就需要把UA_Server_run()拆开运行,下面是个简单的定时运行代码,

#include <signal.h>
#include <sys/timerfd.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

#include "open62541.h"

UA_Boolean running = true;

static void stopHandler(int sign) 
{
    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");
    running = false;
}

#define handle_error(msg) \
       do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(void) 
{
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);
    
    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));
    UA_Server_run_startup(server);
    
    int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
    if (timerfd == -1)
    {
        handle_error("timerfd_create");
    }

    struct itimerspec new_value = {};
    new_value.it_value.tv_sec  = 0;
    new_value.it_value.tv_nsec = 30000000; // 30ms

    new_value.it_interval.tv_sec  = 0;
    new_value.it_interval.tv_nsec = 30000000; // 30ms

    if (timerfd_settime(timerfd, 0, &new_value, NULL) == -1)
    {
        handle_error("timerfd_settime");
    }
    
    printf("timer started\n");
    
    uint64_t exp = 0;
    while (running)
    {
        int ret = read(timerfd, &exp, sizeof(uint64_t));
        if (ret == sizeof(uint64_t)) // 每30ms条件为真
        {
            // do other things
            
            UA_Server_run_iterate(server, false);
        }
    }
    
    UA_StatusCode retval = UA_Server_run_shutdown(server);
    
    UA_Server_delete(server);
    
    return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

拆开运行,可以更好的与现有工程融合在一起。

编译运行后,使用UaExpert连接,连接OK
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值