advanced-messaging
Understanding Message Objects
So far, we have seen that subscribing to a topic involves working with
objects of AMPS::Message
type. A Message
represents a single
message to or from an AMPS server. Messages are received or sent for
every client/server operation in AMPS.
Header properties
There are two parts of each message in AMPS: a set of headers that
provide metadata for the message, and the data that the message
contains. Every AMPS message has one or more header fields defined. The
precise headers present depend on the type and context of the message.
There are many possible fields in any given message, but only a few are
used for any given message. For each header field, the Message
class
contains a distinct property that allows for retrieval and setting of
that field. For example, the Message.get_command_id()
function
corresponds to the commandId
header field, the
Message.get_batch_size()
function corresponds to the BatchSize
header field, and so on. For more information on these header fields,
consult the AMPS User Guide and AMPS Command Reference.
To work with header fields, a Message
contains
getXxx()
/setXxx()
methods corresponding to the header fields.
60East does not recommend attempting to parse header fields from the raw
data of the message.
In AMPS, fields sometimes need to be set to a unique identifier value.
For example, when creating a new subscription, or sending a manually
constructed message, you’ll need to assign a new unique identifier to
multiple fields such as CommandId
and SubscriptionId
. For this
purpose, Message provides newXxx()
methods for each field that generates
a new unique identifier and sets the field to that new value.
getData() method
Access to the data section of a message is provided via the
getData()
method. The data
contains the unparsed data in the
message, returned as a series of bytes (a string
or
const char *
). Your application code parses and works with the data.
The AMPS C++ client contains a collection of helper classes for working with message types that are specific to AMPS (for example, FIX, NVFIX, and AMPS composite message types). For message types that are widely used, such as JSON or XML, you can use whichever library you typically use in your environment.
Advanced Messaging Support
The client.subscribe()
function provides options for subscribing to
topics even when you do not know their exact names, and for providing a
filter that works on the server to limit the messages your application
must process.
Multiple Topics with One Subscription
AMPS allows a regular expression to be supplied in the place of a topic name. When you supply a regular expression, AMPS treats this as a request for topic that matches your expression, including topics that do not yet exist at the time of creating the subscription.
To use a regular expression, simply supply the regular expression in
place of the topic name in the subscribe()
call. For example:
for (auto message : client.subscribe("client.*"))
{
/* receive messages for any topic that begins with 'client' */
std::cout << "Received a message on topic '" << message.getTopic() << "' "
<< "with the data: " << message.getData() << std::endl;
}
Example (CHAPTER_NUMBER).(REGEX_TOPIC_SUBSCRIPTION): Regex topic subscription
In this example, messages on topics client
and client1
would
match the regular expression, and those messages will be returned by the
MessageStream
. As in the example, you can use the getTopic()
method to determine the actual topic of the message sent to the lambda
function.
Content filtering
One of the most powerful features of AMPS is content filtering. With content filtering, filters based on message content are applied at the server, so that your application and the network are not utilized by messages that are uninteresting for your application. For example, if your application is only displaying messages from a particular user, you can send a content filter to the server so that only messages from that particular user are sent to the client. The AMPS User Guide provides full details on content filtering.
To apply a content filter to a subscription, simply pass it into the
client.subscribe()
call:
for (auto message : ampsClient.subscribe("messages", 0, "/sender = 'mom'"))
{
// process messages from mom
}
Next steps
At this point, you are able to build AMPS programs in C/C++ that publish and subscribe to AMPS topics. For an AMPS application to be truly robust, it needs to be able to handle the errors and disconnections that occur in any distributed system. In the next chapter, we will take a closer look at error handling and recovery, and how you can use it to make your application ready for the real world.