View Issue Details

IDProjectCategoryView StatusLast Update
000911010000-014: PubSubSpecpublic2023-12-13 10:57
ReporterThilo Bellinger Assigned ToMatthias Damm  
PrioritynormalSeverityminorReproducibilityhave not tried
Status assignedResolutionopen 
Product Version1.05.02 
Summary0009110: treatment for null DataSetMessages
Description

For JSON encoding it is theoretically possible that an entire DataSetMessage is null.

  • A DataSetMessage can be configured to send no DataSetMessageHeader (JsonNetworkMessageContentMask_DataSetMessageHeader).
  • A keep-alive DataSetMessage has no payload

Should a NetworkMessage omit all null DataSetMessages or should it send a null element?

This may even cause the entire Messages array of the NetworkMessage to be empty (or filled with nulls).
Note: Sending nulls in the Messages array would fit to the common array encoding rules but it is quite useless without any information.

For a NetworkMessage without header (JsonNetworkMessageContentMask_NetworkMessageHeader) the single DataSetMessage is encoded flat.
Here the entire NetworkMessage can be null.

My proposal:
Drop keep-alive messages completely when they have no DataSetMessage header and treat them like a normal delta frame interval without data.
The DataSetMessage can be omitted when there is no data to publish.
The NetworkMessage can be omitted when there is no DataSetMessage to publish.
Thus all sent DataSetMessages and NetworkMessages will always have some data.

TagsNo tags attached.
Commit Version
Fix Due Date

Activities

Peter Wehrfritz

2023-11-30 14:35

reporter   ~0020464

First of all, you cannot omit messages, else the reader might observe a MessageReceiveTimeout. There is a difference between a null value and an empty object (I know UA treats it in some cases the same). A KeepAlive message is not null but, empty. In my opinion a KeepAlive DataSetMessage in a SingleDataSetNetworkMessage with all header off, should be simply encoded as '{}'. You cannot encode it as 'null' because 'null' is not a valid JSON document.

Thilo Bellinger

2023-11-30 16:25

reporter   ~0020466

I agree, a NetworkMessage cannot be null but has to be at least an empt JSON document when something shall be sent.
I also agree that such an empty NetworkMessage can be interpreted by the subscriber when it clearly belongs to a single DataSetMessage.
Actually this will match to the publisher configuration without the need of special exceptions:

  • Something is sent at the keep alive interval to indicate that the publisher is alive.
  • The NetworkMessage contains everything which was configured to be published: Nothing.

A null KeepAlive DataSetMessage message is still ambiguous if the related group has multiple writers (using delta frame messages) and I assume different subscriber implementations will handle this differently.
I recommend to describe such completely ambiguous configurations as invalid.
When a publisher sends such an ambiguous message then there is no surprise if a subscriber behaves unexpected.
Then the fault is clearly on the publisher configuration and neither on the subscriber nor on the specification to allow such ambiguity.
Especially as there are multiple ways to solve the ambiguity:

  • Publish the WriterIds
  • Publish only KeyFrameMessages (number of messages equals the number of Writers) with a defined DataSetMessage ordering
  • Publish the single DataSetMessages to individual queues.

Peter Wehrfritz

2023-12-13 10:57

reporter   ~0020528

There are many configuration combinations that lead to ambiguous messages. And a large proportion of these are in fact not tragic and even wanted, as the recipient is a client with no knowledge of OPC UA (the whole cloud use case). Therefore, I think it would be better not to define which combinations are not useful for an OPC UA reader, but to create one or two profiles that are explicitly optimized for the two-way OPC UA communication case. If you then configure a writer/writer group that is intend to be used by a OPC UA reader, you would simply choose that profile, and you know that there are no problems for the subscriber to understand the content of the messages.

While we're at it, this is what such a profile could look like:

JsonNetworkMessageContentMask

Bit 0: NetworkMessageHeader disabled
Bit 1: DataSetMessageHeader enabled
Bit 2: SingleDataSetMessage enabled
Bit 3: PublisherId disabled
Bit 4: DataSetClassId disabled
Bit 5: ReplyTo disabled
Bit 6: WriterGroupName disabled

JsonDataSetMessageContentMask

Bit 0: DataSetWriterId disabled
Bit 1: MetaDataVersion enabled
Bit 2: SequenceNumber enabled
Bit 3: Timestamp optional
Bit 4: Status optional
Bit 5: MessageType enabled
Bit 6: DataSetWriterName disabled
Bit 7: ReversibleFieldEncoding enabled
Bit 8: PublisherId optional
Bit 9: WriterGroupName disabled
Bit 10: MinorVersion disabled

DataSetFieldContentMask configurable
KeyFrameCount configurable

The DataSetWriter's QueueName is following the recommandation of 1.05.03

I intentionally disabled the DataSetWriterId because the DataSetWriter is sending its messages to a distinct queue. I think it is better to let the broker filter instead of the reader/reader group, because this will reduce the used bandwidth. Without using the topic feature it cannot work anyway, because there is no way to decide the right recipent reader from the network message alone, due to the missing WriterGroupId. While there is a WriterGroupName you cannot configure the WriterGroupName on the Reader, only the WriterGroupId is available.

Issue History

Date Modified Username Field Change
2023-08-17 14:43 Thilo Bellinger New Issue
2023-11-30 14:35 Peter Wehrfritz Note Added: 0020464
2023-11-30 16:25 Thilo Bellinger Note Added: 0020466
2023-12-05 20:42 Jim Luth Assigned To => Matthias Damm
2023-12-05 20:42 Jim Luth Status new => assigned
2023-12-13 10:57 Peter Wehrfritz Note Added: 0020528