C · recipe

Publish with OPC UA PubSub in C

open62541 implements Part 14, which makes it a genuine option for deterministic publishing from an embedded target. Build a connection, a PublishedDataSet, a WriterGroup and a DataSetWriter, then enable the group.

Stackopen62541
Version1.5.8

The code

#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include <open62541/server_pubsub.h>
#include <stdio.h>

/* build open62541 with -DUA_ENABLE_PUBSUB=ON */

int main(void) {
    UA_Server *server = UA_Server_new();
    UA_ServerConfig_setDefault(UA_Server_getConfig(server));

    /* 1. connection: where the messages go */
    UA_PubSubConnectionConfig connCfg;
    memset(&connCfg, 0, sizeof(connCfg));
    connCfg.name = UA_STRING("UDP-UADP Connection");
    connCfg.transportProfileUri = UA_STRING(
        "http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp");
    UA_NetworkAddressUrlDataType addr = {
        UA_STRING_NULL, UA_STRING("opc.udp://224.0.2.14:4840/") };
    UA_Variant_setScalar(&connCfg.address, &addr,
        &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]);
    connCfg.publisherId.idType = UA_PUBLISHERIDTYPE_UINT16;
    connCfg.publisherId.id.uint16 = 1;

    UA_NodeId connId;
    UA_Server_addPubSubConnection(server, &connCfg, &connId);

    /* 2. published dataset: what is published */
    UA_PublishedDataSetConfig pdsCfg;
    memset(&pdsCfg, 0, sizeof(pdsCfg));
    pdsCfg.publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDITEMS;
    pdsCfg.name = UA_STRING("Machine State");
    UA_NodeId pdsId;
    UA_Server_addPublishedDataSet(server, &pdsCfg, &pdsId);

    /* 3. writer group: how often */
    UA_WriterGroupConfig wgCfg;
    memset(&wgCfg, 0, sizeof(wgCfg));
    wgCfg.name = UA_STRING("WriterGroup1");
    wgCfg.publishingInterval = 1000;
    wgCfg.writerGroupId = 1;
    wgCfg.encodingMimeType = UA_PUBSUB_ENCODING_UADP;
    UA_NodeId wgId;
    UA_Server_addWriterGroup(server, connId, &wgCfg, &wgId);
    UA_Server_enableWriterGroup(server, wgId);

    printf("publishing UADP to 224.0.2.14:4840\n");
    UA_Server_runUntilInterrupt(server);
    UA_Server_delete(server);
    return 0;
}

What it prints

publishing UADP to 224.0.2.14:4840
# in Wireshark, filter on: opcua  -- you will see UADP NetworkMessages
# 224.0.2.14 is the standard OPC UA PubSub multicast address

Notes

  • PubSub must be compiled in: -DUA_ENABLE_PUBSUB=ON. Without it none of these symbols exist.
  • 224.0.2.14:4840 is the standard multicast address for UDP UADP. Check your switches actually forward multicast before blaming the code.
  • UADP over UDP is for local real-time fan-out. For edge-to-cloud, use the MQTT transport profile instead: same model, different transport URI.
  • A subscriber joining mid-stream sees nothing until the next key frame. Set the key frame count accordingly.
  • PubSub has no session, so security keys come from a Security Key Service rather than a handshake. Plan that before you need it.

What breaks first

Messages are published but no subscriber receives them BadNotConnected
Almost always the network rather than the code: multicast not forwarded, wrong interface bound, or a firewall dropping UDP 4840. Confirm with Wireshark on the publisher first.

Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.

Free download
OPC UA Troubleshooting & Integration Checklist
The field-tested checklist engineers use to diagnose certificates, ports and namespace problems fast, plus a Python (asyncua) client template.
Get the free checklist →
Free, no course, no login