open62541 基于UDP发布订阅(一)

本文详细介绍了如何在OPCUA应用程序中使用open62541库实现Publishers和Subscribers之间的PubSub通信,包括配置、发布、订阅过程,以及解决跨平台地址解析问题的方法。

概述

PubSub在OPC UA应用程序中分为Publishers(发布者)和Subscribers(订阅者)。发布者是数据的来源,订阅者使用这些数据。PubSub中的通信是基于消息的,Publishers将消息发送给面向消息的中间件,PubSub支持两种不同的消息中间件变体,broker-less和broker-based两种形式。broker-less面向消息的中间件是能够路由基于数据报的消息的网络基础设备,Publishers和Subscribers使用数据报协议,如UDP;broker-based面向消息的中间件是一个消息代理,Publishers和Subscribers使用标准的消息传递协议,如AMQP或MQTT代理。

基于UDP的发布订阅

  • 编译open62541
    CMake中勾选对应的UA_ENABLE_ALALGAMATION和UA_ENABLE_PUBSUB选项,如图所示
    在这里插入图片描述
    编译生成的工程后能够得到对应的.h和.c文件
    在这里插入图片描述
    将其添加进我们工程中能正常使用了。本例程用的是没有勾选UA_ENABLE_AMALGAMATION选项,即使用.h和.lib的方式去进行使用的。

  • Publish端

这里以tutorial_pubsub_publish.c中内容来讲述如何进行发布,代码如下,有部分修改。

#include <open62541/plugin/log_stdout.h>
#include <open62541/plugin/pubsub_ethernet.h>
#include <open62541/plugin/pubsub_udp.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>

UA_NodeId connectionIdent, publishedDataSetIdent, writerGroupIdent;
UA_NodeId connectionIdentEx, publishedDataSetIdentEx, writerGroupIdentEx;
UA_NodeId myIntegerNodeId, myIntegerNodeIdEx;

static void
addPubSubConnection(UA_Server *server, UA_String *transportProfile,
                    UA_NetworkAddressUrlDataType *networkAddressUrl){
   
   
    /* Details about the connection configuration and handling are located
     * in the pubsub connection tutorial */
    UA_PubSubConnectionConfig connectionConfig;
    memset(&connectionConfig, 0, sizeof(connectionConfig));
    connectionConfig.name = UA_STRING("UADP Connection 1");
    connectionConfig.transportProfileUri = *transportProfile;
    connectionConfig.enabled = UA_TRUE;
    UA_Variant_setScalar(&connectionConfig.address, networkAddressUrl,
                         &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]);
    /* Changed to static publisherId from random generation to identify
     * the publisher on Subscriber side */
    connectionConfig.publisherId.numeric = 2234;
    UA_Server_addPubSubConnection(server, &connectionConfig, &connectionIdent);
}

static void
addPubSubConnectionEx(UA_Server *server, UA_String *transportProfile,
UA_NetworkAddressUrlDataType *networkAddressUrl){
   
   
	/* Details about the connection configuration and handling are located
	* in the pubsub connection tutorial */
	UA_PubSubConnectionConfig connectionConfig;
	memset(&connectionConfig, 0, sizeof(connectionConfig));
	connectionConfig.name = UA_STRING("UADP Connection 2");
	connectionConfig.transportProfileUri = *transportProfile;
	connectionConfig.enabled = UA_TRUE;
	UA_Variant_setScalar(&connectionConfig.address, networkAddressUrl,
		&UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]);
	/* Changed to static publisherId from random generation to identify
	* the publisher on Subscriber side */
	connectionConfig.publisherId.numeric = 2234;
	UA_Server_addPubSubConnection(server, &connectionConfig, &connectionIdentEx);
}

static void
addPublishedDataSet(UA_Server *server) {
   
   
    /* The PublishedDataSetConfig contains all necessary public
    * information for the creation of a new PublishedDataSet */
    UA_PublishedDataSetConfig publishedDataSetConfig;
    memset(&publishedDataSetConfig, 0, sizeof(UA_PublishedDataSetConfig));
    publishedDataSetConfig.publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDITEMS;
    publishedDataSetConfig.name = UA_STRING("Demo PDS");
    /* Create new PublishedDataSet based on the PublishedDataSetConfig. */
    UA_Server_addPublishedDataSet(server, &publishedDataSetConfig, &publishedDataSetIdent);
}

static void
addPublishedDataSetEx(UA_Server *server) {
   
   
	/* The PublishedDataSetConfig contains all necessary public
	* information for the creation of a new PublishedDataSet */
	UA_PublishedDataSetConfig publishedDataSetConfig;
	memset(&publishedDataSetConfig, 0, sizeof(UA_PublishedDataSetConfig));
	publishedDataSetConfig.publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDITEMS;
	publishedDataSetConfig.name = UA_STRING("Demo PDS Ex");
	/* Create new PublishedDataSet based on the PublishedDataSetConfig. */
	UA_Server_addPublishedDataSet(server, &publishedDataSetConfig, &publishedDataSetIdentEx);
}

static void
addDataSetField(UA_Server *server) {
   
   
    /* Add a field to the previous created PublishedDataSet */
    UA_NodeId dataSetFieldIdent;
    UA_DataSetFieldConfig dataSetFieldConfig;
    memset(&dataSetFieldConfig, 0, sizeof(UA_DataSetFieldConfig));
    dataSetFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
    dataSetFieldConfig.field.variable.fieldNameAlias = UA_STRING("Server localtime");
    dataSetFieldConfig.field.variable.promotedField = UA_FALSE;
    dataSetFieldConfig.field.variable.publishParameters.publishedVariable =
    UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
    dataSetFieldConfig.field.variable.publishParameters.attributeId = UA_ATTRIBUTEID_VALUE;
    UA_Server_addDataSetField(server, publishedDataSetIdent,
                              &dataSetFieldConfig, &dataSetFieldIdent);
}

static void
addDataSetFieldEx(UA_Server *server) {
   
   
	/* Add a field to the previous created PublishedDataSet */
	UA_NodeId dataSetFieldIdent;
	UA_DataSetFieldConfig dataSetFieldConfig;
	memset(&dataSetFieldConfig, 0, sizeof(UA_DataSetFieldConfig));
	dataSetFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
	dataSetFieldConfig.field.variable.fieldNameAlias = UA_STRING("Server localtime");
	dataSetFieldConfig.field.variable.promotedField = UA_FALSE;
	dataSetFieldConfig.field.variable.publishParameters.publishedVariable =
		UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
	dataSetFieldConfig.field.variable.publishParameters.attributeId = UA_ATTRIBUTEID_VALUE;
	UA_Server_addDataSetField(server, publishedDataSetIdentEx,
		&dataSetFieldConfig, &dataSetFieldIdent);
	/***********添加节点****************/
	UA_NodeId myFieldIdent;
	UA_DataSetFieldConfig myFieldConfig;
	memset(&myFieldConfig, 0, sizeof(UA_DataSetFieldConfig));
	myFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
	myFieldConfig.field.variable.fieldNameAlias = UA_STRING("Myself node");
	myFieldConfig.field.variable.promotedField = UA_FALSE;
	myFieldConfig.field.variable.publishParameters.publishedVariable = myIntegerNodeId;
	myFieldConfig.field.variable.publishParameters.attributeId = UA_ATTRIBUTEID_VALUE;
	UA_Server_addDataSetField(server, publishedDataSetIdentEx,
		&myFieldConfig, &
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

复杂的世界311

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值