Message Type Text versus Binary

Options
Robert
Robert Member Posts: 58 ✭✭

The handling of messages and message type is quite confusing as even most examples of code assume to send messages in binary format.

What is solace recommendation for structured text messages ? (like json, xml, csv,...)

Here the facts as i understood them:

  • Default is always sending as binary message type
  • Rest Messanging API maps json, xml to Text Message Solace REST HTTP Message Encoding (see chapter: HTTP Content-Type Mapping to Solace Message Types)
  • Most samples i have seen handle messages as binary

What is the problem with that ?

  • If all would use by default binary we would get different message type depending on how messages gets published to solace ? (via rest api it would turn to text message) and by using the standard libs it would by default turn to binary.
  • The receive and handling of binary and text is different on consumer side (binary: getBinaryAttachment() or dump() everything text: getText())

Clarity and more standardization of examples, defaults would avoid issues like:

what method should I use to return the contents of a solace.message in human readable string — Solace Community

Other open questions:

  • As well unclear what impact setting SDT has on the message type. i can send a text message but in solace any message attribute (header fields) is added by using SDT.
  • What message property i can check to understand which message type was received on consumer side.

Many thanks for your help.

Answers

  • Aaron
    Aaron Member, Administrator, Moderator, Employee Posts: 541 admin
    Options

    Hi @Robert . Apologies for leaving this post so long, just noticing it now.

    Which API(s) are you using? Then I can point to some specific examples.

    I don't know if any API has a "default" of binary payload. I think you need to specify what type of message you're creating when you first create it to publish.

    I'd recommend against using SDTMap and SDTStream as these don't play with with our open protocol support: AMQP, MQTT, REST. It's a proprietary encoding which means you'll need Solace libraries to decode them.

    If sending text data (XML, CSV, JSON, etc.) I'd recommend using TextMessages. (which are actually an SDT with a single text field... you can see some extra bytes at the start of the payload if trying to parse a TextMessage as just plain binary). TextMessages will automagically get converted appropriately when receiving from other protocols.

    To check what type a message is, it depends on the API. I'm familiar with JCSMP mostly, and the common pattern is something like:

    if (msg instanceof TextMessage) {
        String payload = ((TextMessage)msg).getText();
        // blahblhablha
    } else if (msg instanceof BytesMesssage) {
        byte[] payload = ((BytesMessage)msg).getData();
        // blahb lahb
    } else {
        // something else
    }
    

    N.B. I'm typing this out from memory, but I think that's correct. Something like that.

    For JavaScript, check out message.getType() and the MessageType class. https://docs.solace.com/API-Developer-Online-Ref-Documentation/js

    I think there are other ways for other APIs.

    For the REST Messaging API, I think you need to specify that it's text specifically, or it sends it as a plain binary payload. For example:

    curl http://localhost:9000/TOPIC/solace/samples/rest/hello/test -d 'hello world binary'
    

    Sends as binary payload. But:

    curl http://localhost:9000/TOPIC/solace/samples/rest/hello/test -d 'hello world text' -H 'content-type: text'
     -- OR --
    curl http://localhost:9000/TOPIC/solace/samples/rest/hello/test -d '{"hello world": "json"}' -H 'content-type: application/json'
    

    Send as TextMessages. See here: https://docs.solace.com/API/RESTMessagingPrtl/Solace-REST-Message-Encoding.htm#_Ref393980206


    Hope this helps!

  • Aaron
    Aaron Member, Administrator, Moderator, Employee Posts: 541 admin
    edited January 2023 #3
    Options

    Correction: just tested: publishing an MQTT message with text payload, since the broker doesn't look at the payload, it will be sent to SMF clients as a binary message. And yeah, found this section in the docs: https://docs.solace.com/API/MQTT/Using-MQTT.htm#payload-conversion

    When an event broker receives an MQTT publish message from a client, the received message's payload, which is a sequence of bytes, is encapsulated in the resulting egress SMF message as a binary attachment.

    But from SMF→MQTT it works fine, the text payload of a TextMessage is extracted properly. From the same section in the docs:

    If there is binary metadata that describes the format of the binary attachment, the data of the specified type is copied into the payload field of the MQTT publish message.


    And noticed one of your other open questions: User Properties (you called them "message attributes") are sent separately from the payload in their own optional section. So yeah, message type doesn't matter (binary or text), and you set the User Properties using an SDTMap in our SMF APIs. These will attempt to be converted by the broker if using open protocols. SDTMaps support a lot of data types, and not all are compatible with open protocols or standards. For example, you can nest SDTMaps, but JMS doesn't allow this and only supports flat maps. Or, receiving with an MQTT 5.0 client (user properties weren't in the 3.1.1 version), the broker attempts to convert any property to text before setting in the outbound MQTT message.