Skip to content
Start free evaluation

PubSub over UDP

  • Run publishing and subscribing in one process and watch UADP messages go through.
  • Split publisher and subscriber into two processes that talk over UDP.
  • Choose the fields to publish and read the identifiers of received messages.
  • The apps package and the OPCUA_APPS variable from the lab setup.
  • Two terminals.

PubSub needs no OPC UA server or session, so this tutorial doesn’t use server_start or connect.

Start the headless simulator:

터미널 창
"$OPCUA_APPS/bin/pdcomm-opcua-headless"

The default configuration uses UDP with the both role, publisher and subscriber at once: the subscriber listens on a free port of 127.0.0.1 and the publisher sends to that address.

{"action":"pubsub_start"}
{"ok":true,"result":{"acknowledged":0,"destination":"127.0.0.1:64578","dropped":0,"error":null,"listen":"127.0.0.1:64578","queued":0,"received":0,"rejected":0,"role":"both","running":true,"sent":0,"transport":"udp"}}

Publish one DataSet with the default fields:

{"action":"pubsub_publish"}
{"ok":true,"result":{"bytes":60,"fields":4,"sequence":1}}

One 60-byte UADP NetworkMessage went out. Take the received messages:

{"action":"pubsub_received"}
{"ok":true,"result":{"messages":[{"bytes":60,"datasets":[{"fields":[{"type":"Boolean","value":true},{"type":"Int32","value":42},{"type":"Double","value":3.5},{"type":"String","value":"pdcomm"}],"major":1,"minor":1,"sequence":1}],"publisher_id":77,"source":"127.0.0.1:54425","writer_group":1,"writer_ids":[17]}]}}
Field Meaning
publisher_id The PublisherId in the NetworkMessage header (UInt16 77)
writer_group The WriterGroupId (1)
writer_ids The DataSetWriterIds in the message ([17])
datasets[].sequence The DataSetMessage sequence number
datasets[].major, minor The configuration version
datasets[].fields The field values of the key frame
source The UDP address the message came from

Put 1 to 64 typed values in fields:

{"action":"pubsub_publish","fields":[{"type":"Double","value":21.5},{"type":"String","value":"line-1"}]}
{"ok":true,"result":{"bytes":53,"fields":2,"sequence":2}}

Check the status:

{"action":"pubsub_status"}
{"ok":true,"result":{"acknowledged":0,"destination":"127.0.0.1:64578","dropped":0,"error":null,"listen":"127.0.0.1:64578","queued":1,"received":2,"rejected":0,"role":"both","running":true,"sent":2,"transport":"udp"}}

sent and received are running totals, queued counts messages you haven’t taken yet and rejected counts messages that couldn’t be decoded.

{"action":"pubsub_received"}
{"ok":true,"result":{"messages":[{"bytes":53,"datasets":[{"fields":[{"type":"Double","value":21.5},{"type":"String","value":"line-1"}],"major":1,"minor":1,"sequence":2}],"publisher_id":77,"source":"127.0.0.1:54425","writer_group":1,"writer_ids":[17]}]}}

Stop PubSub and end the program:

{"action":"pubsub_stop"}
{"action":"shutdown"}

Now split publisher and subscriber. In the first terminal, start the simulator again:

터미널 창
"$OPCUA_APPS/bin/pdcomm-opcua-headless"

Set the role to subscriber and the listen address to 127.0.0.1:4840, the default opc.udp port defined by Part 14. When you pass only part of the configuration, the rest keeps its defaults.

{"action":"configure","config":{"pubsub":{"role":"subscriber","listen":"127.0.0.1:4840"}}}
{"action":"pubsub_start"}
{"ok":true,"result":{"acknowledged":0,"destination":null,"dropped":0,"error":null,"listen":"127.0.0.1:4840","queued":0,"received":0,"rejected":0,"role":"subscriber","running":true,"sent":0,"transport":"udp"}}

In the second terminal, start another simulator:

터미널 창
"$OPCUA_APPS/bin/pdcomm-opcua-headless"

Set the role to publisher and the destination to the subscriber’s address:

{"action":"configure","config":{"pubsub":{"role":"publisher","destination":"127.0.0.1:4840"}}}
{"action":"pubsub_start"}
{"ok":true,"result":{"acknowledged":0,"destination":"127.0.0.1:4840","dropped":0,"error":null,"listen":null,"queued":0,"received":0,"rejected":0,"role":"publisher","running":true,"sent":0,"transport":"udp"}}
{"action":"pubsub_publish","fields":[{"type":"Int32","value":5},{"type":"Boolean","value":false}]}
{"ok":true,"result":{"bytes":40,"fields":2,"sequence":1}}

In the first terminal, take the received messages:

{"action":"pubsub_received"}
{"ok":true,"result":{"messages":[{"bytes":40,"datasets":[{"fields":[{"type":"Int32","value":5},{"type":"Boolean","value":false}],"major":1,"minor":1,"sequence":1}],"publisher_id":77,"source":"127.0.0.1:53076","writer_group":1,"writer_ids":[17]}]}}

Type this in both terminals:

{"action":"shutdown"}
{"ok":true,"result":{"client_closed":null,"pubsub_stopped":true,"server_stopped":false}}
error in the reply Cause and fix
PubSub is already running PubSub is already started. To change its configuration, send pubsub_stop first, then configure.
PubSub is not running You sent pubsub_publish or pubsub_received before pubsub_start.
UDP transport I/O: address in use (os error 48) Another program uses the listen address. Use another port or stop that program; the error number differs by operating system.
This PubSub connection has no publisher You sent pubsub_publish with the subscriber role.
fields must be an array of 1 to 64 typed values fields is empty or has more than 64 entries.

The simulator doesn’t sign or encrypt UADP messages, so use it only on networks you trust. In the GUI, the PubSub tab does the same.