Creating Messages
Messages are explicitly created by client applications when publishing and are implicitly created by the messaging APIs on matching message delivery.
JCSMP
Creates an object of the specified class (see Java Message Classes below) to encapsulate a message.
Java RTO API
Creates an object within the native library and provides a handle to the application.
C API
Allocates a memory buffer from heap storage to store and send and receive messages.
.NET API
Creates an IMessage
object to encapsulate a message.
JavaScript and Node.js APIs
Creates a solace.Message
object to encapsulate a message.
When creating messages, the following factors should be considered:
Message Ownership
When creating messages for publishing, there are two message ownership models:
- Session-independent
In a Session-independent message ownership model, client applications can reuse messages between send operations. Messages are allocated on-demand and are disposed explicitly by client applications when they are done with the messages.
- Session-dependent
The JCSMP also supports a Session-dependent message ownership model. In this model, message instances are pre-allocated into a producer message pool; client applications can ‘take' a message instance from the message pool, populate it, and send it. When the send operation returns, the message instance is automatically reset and ‘put' back into the message pool by the API. This is done through the
Producer
interface on the Session.Session-dependent messages cannot be used in a batch send (refer to Sending Multiple Messages at Once).
The session-dependent message ownership model is primarily maintained for backwards compatibility with existing applications that use the JCSMP. It is recommended that new Java applications use the Session-independent messages. There is no performance penalty for using the Session-independent message ownership model if messages are pre-allocated and reused, whenever possible.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
JCSMPFactory.createMessage(...) Creates an object of the specified class (refer to the table Java Message Classes) to encapsulate a message. |
Java RTO |
Solclient.createMessageForHandle(...) Creates a message and binds it to the given |
C |
solClient_msg_alloc(...) Allocates a memory buffer from heap storage to store and send and receive messages. |
.NET |
|
JavaScript and Node.js |
solace.SolclientFactory.createMessage() Creates a |
Related Samples
For an example of how to create Session-independent messages, refer to the ADPubAck
sample for the JCSMP, the DirectPubSub
samples for the Java RTO, C, and .NET APIs, and the TopicPublisher
sample for the JavaScript and Node.js APIs.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
producer.createBytesXMLMessage() producer.createBytesMessage() producer.createMapMessage() producer.createStreamMessage() producer.createTextMessage() producer.createXMLContentMessage() |
Java RTO |
Not applicable |
C |
Not applicable |
.NET |
Not applicable |
JavaScript and Node.js |
Not applicable |
Message Types
The messaging APIs support different message types as defined by the message payloads.
JCSMP
For developers' convenience, the following type-safe message types/classes are provided.
Message Class | Description |
---|---|
BytesXMLMessage |
An unstructured class that can be used to send a message that contains an XML data payload. |
BytesMessage |
A structured class that can be used to send a message that contains a stream of uninterpreted bytes in a binary attachment. |
MapMessage |
A structured class that can be used to send a message that contains a structured data type (SDT) map. Refer to Using Structured Data. |
StreamMessage |
A structured class that can be used to send a message that contains a SDT stream. Refer to Using Structured Data. |
TextMessage |
A structured class that can be used to send a message that contains text. |
XMLContentMessage |
A structured class that can be used to send a message that contains XML data payload. |
Java RTO API
Java RTO provides the following message types.
Message Class | Description |
---|---|
BytesMessage |
A structured class that can be used to send a message that contains a stream of uninterpreted bytes in a binary attachment. |
C, JavaScript. Node.js, and .NET APIs
These APIs define only a single message type. In these APIs, a message payload can contain any combination of the message types and classes listed above by way of message helper functions.
Resetting Messages
When reusing a message in the Session-independent message ownership model, you can release all memory associated with a message buffer so that the message buffer is reset to its original state (that is, as if it has just been allocated). All fields are reset to their default values.
The Java RTO API does not include a reset method. If a message is destroyed using MessageHandle.destroy()
, you must call createMessageForHandle
again to allocate a new message for the now-unbound handle.
PubSub+ Messaging API | Call |
---|---|
JCSMP |
XMLMessage.reset() |
Java RTO |
Not applicable |
C |
solClient_msg_reset() |
.NET |
IMessage.reset() |
JavaScript and Node.js |
solace.Message.reset() |
Setting Message Properties
A number of important message properties can be set for Guaranteed messages, which will affect how messages are routed when they are published.
For a complete list of message properties that can be set, refer to the PubSub+ Messaging APIs documentation for the appropriate messaging API.
ACK Immediately
If this property is set to false (the default), the event broker should send an acknowledgment for the messages received in the publish window when a threshold of either a third of the Publish Window Size is reached or one second has elapsed. These are non-configurable thresholds on the event broker.
- This property has no effect on an outgoing Direct message or on a message received by a client.
- This property may or may not be removed by the receiving event broker prior to its delivery to a receiving client. Therefore, receiving clients should not rely on this property being present.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
Message.setAckImmediately(...) |
Java RTO |
MessageHandle.setAckImmediately(...) |
C |
solClient_msg_setAckImmediately(...) |
.NET |
IMessage.AckImmediately |
JavaScript and Node.js |
solace.Message.setAcknowledgementImmediately(...) |
Class-of-Service
A COS level of 2 is a reserved Solace value; currently a message with a COS level of 2 is treated as low priority.
You must set the COS value using the data structure provided by each API. Do not set the value directly using an integer.
For information on how to configuring a queue or a topic endpoint to be able to selectively discard low-priority messages, refer to the reject-low-priority-msg
and reject-low-priority-msg-limit
Queue CONFIG and Topic Endpoint CONFIG commands in Guaranteed Messaging Configuration.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
Message.setCos(...) |
Java RTO |
MessageHandle.setUserCos(...) |
C |
solClient_msg_setClassOfService(...) |
.NET |
IMessage.UserCos |
JavaScript and Node.js |
solace.Message.setUserCos(...) |
Correlation ID
A unique correlation ID (in the form of a string) can be set for a message. A correlation ID can be used to correlate a request message and its corresponding reply. A correlation ID can also be used as an identifier in a message selector.
For information on using Request Reply messaging for Guaranteed messages, refer to Request Reply Messaging. For information on selectors, refer to Using Selectors.
PubSub+ Messaging API | Call |
---|---|
JCSMP |
Message.setCorrelationID(...) |
Java RTO |
MessageHandle.setCorrelationId(...) |
C |
solClient_msg_setCorrelationID(...) |
.NET |
IMessage.CorrelationId |
JavaScript and Node.js |
solace.Message.setCorrelationId(...) |
Dead Message Queue Eligibility
Guaranteed messages that have exceeded their TTL or maximum number of redelivery attempts can be moved from a durable Queue or a Topic Endpoint to a DMQ, instead of being discarded if those messages are flagged as being DMQ-eligible. A DMQ is just a durable queue that has been assigned to serve as the DMQ for another durable endpoint. For more information, refer to Configuring Dead Message Queues
DMQ eligibility is a set as a message flag. A value of true
enables a published message to be DMQ-eligible.
Setting DMQ eligibility for a Direct message only has an effect when the message's Topic matches a Topic subscription on an endpoint and the event broker changes the received message's delivery mode to Non-Persistent. For more information on how received messages' delivery modes can be modified for Topic matching, refer to Guaranteed Messages.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
Message.setDMQEligible(...) |
Java RTO |
MessageHandle.setDMQEligible(...) |
C |
solClient_msg_setDMQEligible(...) |
.NET |
IMessage.DMQEligible |
JavaScript and Node.js |
solace.Message.setDMQEligible(...) |
Related Samples
For an example of how to make messages DMQ-eligible, refer to the messageTTLAndDeadMessageQueue
sample for the appropriate messaging API.
Deliver-To-One Subscribers
The Deliver-To-One property can set for Guaranteed Messages when they are published.
The Deliver-To-One flag only affects the delivery of messages with a Direct delivery mode. Therefore, when the Deliver-To-One flag is enabled for a persistent or non-persistent message, it does not affect message delivery behavior, unless the delivery mode of that message is changed to Direct when it matches a Topic subscription assigned to a queue or topic endpoint destination. In this case, the message that is changed to Direct is only be delivered to a single Direct message consumer, rather than all, even though there might be a number of clients with appropriate subscriptions that are capable of receiving the message.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
XMLMessage.setDeliverToOne(...) |
Java RTO |
MessageHandle.setDeliverToOne(...) |
C |
solClient_msg_setDeliverToOne(...) |
.NET |
IMessage.DeliverToOne |
JavaScript and Node.js |
solace.Message.setDeliverToOne(...) |
Delivery Mode
Each published message has a delivery mode. Direct delivery is the default. To use Guaranteed Messaging, set the delivery mode to Persistent in most cases.
A Non-Persistent delivery mode is also available for Guaranteed Messaging; however this mode is supported only for JMS messaging.applications.
For more information, see Message Delivery Modes.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
Message.setDeliveryMode(...) |
Java RTO |
MessageHandle.setMessageDeliveryMode(...) |
C |
solClient_msg_setDeliveryMode(...) |
.NET |
IMessage.DeliveryMode |
JavaScript and Node.js |
solace.Message.setDeliveryMode(...) |
Related Samples
For an example of how to set the delivery mode for a message, refer to the DirectPubSub
sample for the Java, Java RTO, C, and .NET APIs, and the TopicPublisher
sample for JavaScript and Node.js APIs.
Destination
A published Guaranteed message is routed according to its set Queue or Topic destination.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
A destination is set on the send method used to publish the message. Refer to Sending One Message at a Time or Sending Multiple Messages at Once. |
Java RTO |
MessageHandle.setDestination(...) |
C |
solClient_msg_setDestination(...) |
.NET |
IMessage.Destination |
JavaScript and Node.js |
solace.Message.setDestination(...) |
Related Samples
For an example of how to publish a message to a Topic, refer to the DirectPubSub
sample for the Java, Java RTO, C, and .NET APIs, and the TopicPublisher
sample for the JavaScript and Node.js APIs.
For an example of how to publish a message to a Queue, refer to the QueueProvisionAndBrowse
sample for the Java, Java RTO, C, and .NET APIs, and the QueueProducer
sample for the JavaScript and Node.js APIs.
Message Eliding Eligibility
The message eliding capabilities of the event broker enables clients to only receive the most current Direct messages published to Topics that they subscribe to, at a rate that they can manage. Using message eliding can be useful in situations where a slower message rate is required or there are slow subscribers (that is, clients that are not consuming messages quickly enough).
To use message eliding, the following are required:
- Published messages must be flagged as eligible for message eliding.
- A receiving client application must be assigned a client profile through its client username that permits it to use message eliding. The client profile also sets a rate to control the delay interval at which a new eliding-eligible message elides a previous version that is queued for delivery to the client. For information on how to configure client profiles and assign them to clients, refer to Configuring Client Authentication.
The message eliding flag only affects the delivery of messages with a Direct delivery mode. Therefore, when the message eliding flag is enabled for a persistent or non-persistent message, it does not affect message delivery behavior, unless the delivery mode of that message is changed to Direct when it matches a client topic subscription. In this case, the message that is changed to Direct can then be elided.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
Message.setElidingEligible(...) |
Java RTO |
MessageHandle.setElidingEligible(...) |
C |
solClient_msg_setElidingEligible(...) |
.NET |
IMessage.ElidingEligible |
JavaScript and Node.js |
solace.Message.setElidingEligible(...) |
Message Expiration
You can set an expiration time (in milliseconds), from midnight, January 1, 1970 UTC, on a sent message. By default, a published message's expiration value is 0, which means that the message never expires.
The message expiration field is transported from end-to-end through the event broker only when a client explicitly sets an expiration value greater than 0, and TTL is not set or is set to 0.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
Message.setExpiration(...) |
Java RTO |
MessageHandle.setExpiration(...) |
C |
solClient_msg_setExpiration(...) |
.NET |
IMessage.Expiration |
JavaScript and Node.js |
solace.Message.setGMExpiration(...) |
To maintain an accurate message expiration value, it is important to synchronize the system clocks of the clients connecting to the event broker.
Message TTL is the only mechanism in the messaging network for preventing expired messages to be delivered to clients. Setting an expiration value has no effect on the life cycle of a message in the messaging network. That is, a message with an expiration time that has passed is still delivered to consumers. If it is determined that some further action (such as discarding the received message) should occur, it is the responsibility of a receiving application to perform that action.
Enabling Message Expiration Calculation
To calculate a message expiration value that also accounts for a message TTL value, enable message expiration calculation for the Session . By default, to improve system performance, message expiration calculation is not enabled.
When message expiration calculation is enabled, and the message has a TTL value greater than 0, the API updates the message's expiration value with the sum of the message TTL and the UTC value after the message is sent or received.
Setting TTL and expiration values for messages with Direct delivery modes only has an effect if the event broker automatically changes the messages' delivery mode from Direct to non-persistent because the messages' Topics match a Topic subscription assigned to an endpoint. For information on how messages' delivery modes could be changed to fulfill topic matches, refer to Topic Matching and Message Delivery Modes.
PubSub+ Messaging API | Session Property |
JCSMP |
JCSMPProperties.CALCULATE_MESSAGE_EXPIRATION |
Java RTO |
SessionHandle.PROPERTIES.CALCULATE_MESSAGE_EXPIRATION |
C |
SOLCLIENT_SESSION_PROP_CALCULATE_MESSAGE_EXPIRATION |
.NET |
SessionProperties.CalculateMessageExpiration |
JavaScript and Node.js |
Not applicable |
Related Samples
For an example of how to set an expiration time or enable message expiration calculation, refer to the messageTTLAndDeadMessageQueue
sample for the appropriate messaging API.
Message Priority
You can apply a message priority value to messages that are published to an event broker. When Queues or Topic Endpoints are configured to respect message priority, the event broker uses this value to deliver the message in the appropriate order. In other words, messages with a higher priority are sent before messages with a lower priority. A value of 0 is the lowest priority, and a value of 255 is the highest priority (though the event broker treats all values higher than 9 as priority 9). The default value is 4.
When an endpoint is configured to enforce message priority, it increases the chance that duplicate messages will be delivered to a consuming client after it recovers from a connection failure.
PubSub+ Messaging API | Use |
JCSMP |
Message.setPriority(...) |
Java RTO |
MessageHandle.setPriority(...) |
C |
solClient_msg_setPriority(...) |
.NET |
IMessage.Priority |
JavaScript and Node.js |
solace.Message.setPriority(...) |
Partition Key
You can set a partition key in your message to take advantage of partitioned queues. Partitioned queues allow you to easily scale the number of consumer applications in your event mesh, while maintaining the message sequence for all published messages with the same partition key. PubSub+ event brokers ensure that all related events are delivered to the same consumer in the correct sequence and also re-balance the event stream when you add or remove consumers. For more information see Partitioned Queues.
You set the partition key in the API by specifying the user message property listed in the table below. This value is stored in the JMSXGroupID
field in the message and remains unchanged between network hops.
The following table shows how to configure the key in a PubSub+ message property to use partitioned queues.
PubSub+ Messaging API | How to Set the Partition Key |
---|---|
JCSMP |
Use the
The following example sets the partition key TextMessage message = JCSMPFactory.onlyInstance().createMessage(TextMessage.class); SDTMap messageProperties = JCSMPFactory.onlyInstance().createMap(); messageProperties.putString(XMLMessage.MessageUserPropertyConstants.QUEUE_PARTITION_KEY,"Group-0"); message.setProperties(messageProperties); |
Java RTO |
Use the If required, you can also retrieve or remove the partition key using the /* Java RTO uses getters and setters for the partition key */ String firstQueuePartitionKey = "Group-0"; msg.setQueuePartitionKey(queuePartitionKey); assert firstQueuePartitionKey == msg.getQueuePartitionKey(): "The message does not have the expected queue partition key."; msg.deleteQueuePartitionKey(); assert msg.getQueuePartitionKey() == null: "The message should not have had a queue partition key set."; |
C |
Create a user property map to set message properties on a message with the function
The following example sets the partition key value to ... solClient_opaqueContainer_pt userPropContainer = NULL; // message pointer solClient_opaqueMsg_pt msg_p = NULL; ... // Allocate memory for the message to be sent. if ((rc = solClient_msg_alloc(&msg_p)) != SOLCLIENT_OK) { // error handling } if ((rc = solClient_msg_createUserPropertyMap(msg_p, &userPropContainer, 1024)) != SOLCLIENT_OK) { // error handling } if ((rc = solClient_container_addString(userPropContainer, "Group-0","JMSXGroupID")) != SOLCLIENT_OK) { // alternative SOLCLIENT_MESSAGE_USER_PROP_QUEUE_PARTITION_KEY can be used instead of "JMSXGroupID" // error handling } |
.NET |
Use the
The following example sets the partition key IMessage msg = ContextFactory.Instance.CreateMessage(); IMapContainer user_map = msg.CreateUserPropertyMap(); user_map.AddString(MessageUserPropertyConstants.SOLCLIENT_USER_PROP_QUEUE_PARTITION_KEY , "Group-0"); user_map.Close(); |
JavaScript |
Use the
The following example sets the partition key message.getUserPropertyMap ( ).addField(Message.SOLCLIENT_USER_PROP_QUEUE_PARTITION_KEY, solace.SDTFieldType.STRING,'Group-0') // Or using pre-created SDTField: message.getUserPropertyMap ( )addField('Message.SOLCLIENT_USER_PROP_QUEUE_PARTITION_KEY, SDTField.create(solace.SDTFieldType.STRING, 'Group-0')) |
ReplyTo Destinations
When the message is to be published as a request, a ReplyTo destination can be set to indicate where the reply to the request message should be sent. For information on using Request Reply messaging for Guaranteed messages, refer to Request Reply Messaging.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
|
Java RTO |
|
C |
|
.NET |
|
JavaScript and Node.js |
|
Related Samples
For an example of how to create a Guaranteed request message, which includes a ReplyTo destination, refer to the RRGuaranteedRequester
and RRGuaranteedReplier
samples for the Java, Java RTO, C, and .NET APIs. For the JavaScript and Node.js APIs, refer to the Basic Requestor
and BasicReplier
samples.
Time-To-Live
To ensure that old messages are not delivered to consuming clients, you can set a Time-To-Live (TTL) (in milliseconds) for each Guaranteed message to be published. When Queues or Topic Endpoints are configured to respect message TTLs, and a received message's TTL has passed, it can be discarded by the endpoint, or, if the message is eligible for a Dead Message Queue (DMQ), moved to a DMQ provisioned on the event broker.
By default, a published message's TTL value is 0, which means that the message never expires.
For information on how to configure an endpoint to respect message TTLs, refer to Defining Endpoint Properties or to the PubSub+ Messaging APIs documentation for the messaging API used. For information on making messages eligible for DMQs, refer Dead Message Queue Eligibility.
PubSub+ Messaging API | Use |
---|---|
JCSMP |
Message.setTimeToLive(...) |
Java RTO |
MessageHandle.setTimeToLive(...) |
C |
solClient_msg_setTimeToLive(...) |
.NET |
IMessage.TimeToLive |
JavaScript and Node.js |
solace.Message.setTimeToLive(...) |
Related Samples
For an example of how to set a TTL for published messages, refer to the messageTTLAndDeadMessageQueue
sample for the appropriate messaging API.