AMPS Programming: Working with Commands
The AMPS clients provide named convenience methods for core AMPS functionality. These named methods work by creating messages and sending those messages to AMPS. All communication with AMPS occurs through messages.
You can use the Command
object to customize the messages that AMPS
sends. This is useful for more advanced scenarios where you need precise
control over AMPS, in cases where you need to use an earlier version of
the client to communicate with a more recent version of AMPS, or in
cases where a named method is not available.
Understanding AMPS Messages
AMPS messages are represented in the client as AMPS.Message
objects. The
Message
object is generic, and can represent any type of AMPS message,
including both outgoing and incoming messages. This section includes a
brief overview of elements common to AMPS command messages. Full details
of commands to AMPS are provided in the AMPS Command Reference (linked at
the bottom of this page).
All AMPS command messages contain the following elements:
- Command - The command tells AMPS how to interpret the message.
Without a command, AMPS will reject the message. Examples of commands
include
publish
,subscribe
, andsow
. - CommandId - The command ID, together with the name of the client,
uniquely identifies a command to AMPS. The command ID can be used
later on to refer to the command or the results of the command. For
example, the command ID for a
subscribe
message becomes the identifier for the subscription. The AMPS client provides a command ID when the command requires one and no command ID is set.
Most AMPS messages contain the following fields:
- Topic - The topic that the command applies to, or a regular
expression that identifies a set of topics that the command applies
to. For most commands, the topic is required. Commands such as
logon
,start_timer
, andstop_timer
do not apply to a specific topic, and do not need this field. - Ack Type - The ack type tells AMPS how to acknowledge the message to the client. Each command has a default acknowledgment type that AMPS uses if no other type is provided.
- Options - The
options
are a comma-separated list of options that affect how AMPS processes and responds to the message.
Beyond these fields, different commands include fields that are relevant to that particular command. For example, SOW queries, subscriptions, and some forms of SOW deletes accept the Filter field, which specifies the filter to apply to the subscription or query. As another example, publish commands accept the Expiration field, which sets the SOW expiration for the message.
For full details on the options available for each command and the acknowledgment messages returned by AMPS, see the AMPS Command Reference.
Creating and Populating the Command
To create a command, you simply construct a command object of the appropriate type:
AMPS::Command command("sow");
Once created, you set the appropriate fields on the command. For example, the following code creates a SOW query, setting the command, topic and filter for the query:
AMPS::Command command("sow")
.setTopic("messages-sow")
.setFilter("/id > 20");
When sent to AMPS using the execute()
method, AMPS performs a SOW
query from the topic messages-sow
using a filter of /id > 20
.
The results of sending this message to AMPS are no different than using
the form of the sow
method that sets these fields.
Using Execute
Once you've created a command, use the execute
method to send the
command to AMPS. The execute
method returns a MessageStream
that
provides response messages. The executeAsync
method sends the
command to AMPS, waits for a processed
acknowledgment, then
returns. Messages are processed on the client background thread.
For example, the following snippet sends the command created above:
client.execute(command);
You can also provide a message handler to receive acknowledgments,
statistics, or the results of subscriptions and SOW queries. The AMPS
client maintains a background thread that receives and processes
incoming messages. The call to executeAsync
returns on the main
thread as soon as AMPS acknowledges the command as having been
processed, and messages are received and processed on the background
thread:
void handleMessages(const AMPS::Message& m, void* user_data)
{
/* print acknowledgment type and reason for sample purposes.*/
std::cout << m.getAckType() << " : " << m.getReason() << std::endl;
}
...
client.executeAsync(command, AMPS::MessageHandler(handleMessages, NULL));
...
While this message handler simply prints the ack type and reason for sample purposes, message handlers in production applications are typically designed with a specific purpose. For example, your message handler may fill a work queue, or check for success and throw an exception if a command failed.
Using Execute To Publish
Notice that the publish
command does not typically provide return
results other than acknowledgment messages, so there is little need for
a message handler with a publish
command. To send a publish
command, use the executeAsync()
method with a default-constructed
message handler. With a default-constructed message handler, AMPS does
not enter the message handler in the internal routing table, which
improves efficiency for commands that do not expect a response:
client.executeAsync(publishCmd, AMPS::MessageHandler());
A default-constructed message handler has an empty implementation and does
not receive acknowledgments. To detect write failures, set
the FailedWriteHandler
on the client.
AMPS Command Cookbook
The AMPS Command Reference includes information on which fields and options to set on commands to get a specific result. The reference includes both reference information and a Command Cookbook that provides a concise guide for commonly-used commands.