AMI Client¶
The AMI Client is a flexible tool enabling bi-directional communication with external applications via AMI Relay. It works by sending Realtime Messages, AMI’s internal messaging protocol, which enables external commands to be processed by AMI.
Overview¶
The AMI Client is a built-in mechanism within the 3forge platform enabling external applications to interact and communicate with AMI. Its primary use is to respond automatically to different events while the communication is active.
It can be fully and freely configured, allowing users to define custom actions in response to specified events. This includes:
- Handling incoming messages
- Notifying when a message is sent
- Alerting on connection status, like when the client connects, disconnects, or successfully logs in
- Processing and responding to command callbacks
The Client is designed for bi-directional communication and can also be used to publish messages back to AMI. This allows for commands to be sent to AMI from an external application using Realtime Messages.
AMI Client Library¶
The AMI Client is supported in the following three languages:
All three client versions use the AmiClientListener interface to allow developers to define what behavior should be executed when each event occurs.
The AMI Client is not thread-safe. Multiple threads should not access the same client.
AMI Client Structure¶
AMI Client is primarily backed by three Java classes, using a Subject-Observer approach:
-
AmiClient(Subject)AmiClientis the lowest level class and establishes and manages communication from AMI to an external application over the Relay.- It contains the functionality for sending and receiving Realtime Messages to AMI.
-
AmiClientListener(Observer)- The
AmiClientListeneris an interface responsible for all the event handling for an AmiClient connection. - It contains a reference to an
AmiClientobject, allowing the listener to both send and receive messages to AMI.
- The
-
AmiClientCommandDefAmiClientCommandDefis a configuration class allowing users to define their own executable commands in AMI, e.g: a “send order” command, which can then be sent to AMI.- The actual functionality and logic of the command callback is then defined in the
AmiClientListenerinstance.
To create an instance of an AMI Client, you will need to implement an AmiClientListener in your language of choice from the list above.
Implementation¶
Details will vary depending on the language, but the core implementation for an AMI Client is the same across each library.
In general, creating and using an instance of an AMI Client should follow these steps:
- Create an AMI Client application using the
AmiClientListenerinterface. - Within the application implementing the listener, initialize an
AmiClientobject which enables connection to and from AMI. - (Optionally) Create command definitions using
AmiClientCommandDefobjects and send those to AMI via the Client. - Implement any logic and other handling needed in the
AmiClientListenermethods. This includes using theAmiClientobject to send and receive Realtime Messages to AMI.
AmiClientListener Methods¶
Logic for handling events should be implemented by the user in the AmiClientListener. This includes:
- Starting and establishing the connection to AMI
- Sending and receiving messages (see the
AmiClientmethods for details) - Events that occur on connect or disconnect
When implementing the interface, there are 6 methods that can be overridden which are listed below. Use these methods to handle any logic for those specific events.
Note
Calls to each method may be slightly different across different libraries. The information is provided for the base Java classes.
Please use this as reference only and refer to the specific library pages for examples in the corresponding language.
void onMessageReceived(...)¶
| Parameter | Description |
|---|---|
rawClient |
Represents the AmiClient's internal connection to the AMI server |
now |
Time in ms that the message was received |
seqnum |
Sequence number, or (Q) param, of the received message |
status |
Status, or (S) param, of the received message |
message |
Message, or (M) param, contents of the received message |
- If the
ENABLE_QUIEToption is not set, then each message sent to AMI will be followed be a status (M) message that is sent back to the Client -
- Use this method to determine what if any actions should be performed by the Client, e.g:
void onMessageSent(...)¶
| Parameter | Description |
|---|---|
rawClient |
Represents the AmiClient's internal connection to the AMI server |
message |
The buffer of the message that was just sent |
- Fired after each message is sent using any
AmiClientsend message method -
- Use this method to determine what if any actions should be performed by the Client when a message is sent to AMI, e.g:
void onConnect(...)¶
| Parameter | Description |
|---|---|
rawClient |
Represents the AmiClient's internal connection to the AMI server |
- Called after a successful connection, but before a login attempt
-
- Use this method to determine what if any actions should be performed by the Client on connection, e.g:
void onDisconnect(...)¶
| Parameter | Description |
|---|---|
rawClient |
Represents the AmiClient's internal connection to the AMI server |
- Called after a client/server connection has been disconnected
-
- Use this method to determine what if any actions should be performed by the Client on disconnect, e.g:
void onCommand(...)¶
| Parameter | Description |
|---|---|
rawClient |
Represents the AmiClient's internal connection to the AMI server |
requestId |
Unique identifier for this execute command (E). Should be included in the response |
cmd |
ID of the command (C) |
userName |
Username of the command caller (U) |
objectType |
Type of object the command was called on |
objectId |
The ID of the object (O) |
params |
Any additional parameters of the received object in key-value pairs |
- Called when an execute (E) command is received from the server
- These can be user-defined commands specified with
AmiClientCommandDefobjects -
- Use this method to configure what behavior the Client should perform when a command has been executed in AMI, e.g:
void onLoggedIn(...)¶
| Parameter | Description |
|---|---|
rawClient |
Represents the AmiClient's internal connection to the AMI server |
- Called after a successful login (L) has processed by the AMI Relay server
-
- Use this method to determine what if any actions should be performed by the Client on login, e.g:
AmiClient Methods¶
There are several methods in the AmiClient class that are used to send messages to and from AMI. You will need to call these methods from within your AMI Client application (AmiClientListener) to interface with AMI.
Listed below are the available AmiClient methods that can be called from an AMI Client instance.
Note
Calls to each method may be slightly different across different libraries. The information is provided for the base Java classes.
Please use this as reference only and refer to the specific library pages for examples in the corresponding language.
Options¶
These are optional flags that can be set to configure the Client. These are passed in when the Client is started as the parameter int options.
| Option | Value | Description |
|---|---|---|
ENABLE_QUIET |
4 | Same as setting O="QUIET" in the login message. Tells AMI Relay not to send message ack back to the Client |
ENABLE_AUTO_PROCESS_INCOMING |
2 | By default, this Client will automatically read inbound messages and process them in a separate thread. If disabled, you must manually call pumpIncomingEvent() |
DISABLE_AUTO_RECONNECT |
8 | By default, this Client will keep trying to reconnect to the AMI server |
ENABLE_SEND_TIMESTAMPS |
32 | Whether this Client should send timestamps. Useful for enabling delayed message detection |
ENABLE_SEND_SEQNUM |
64 | Whether this Client should send sequence numbers. Useful for linking a Client message to a message in AMI |
LOG_CONNECTION_RETRY_ERRORS |
128 | Whether this Client should log errors each time a connection retry fails. If not set, then just on the first connection failure |
LOG_MESSAGES |
256 | If set, all messages will be logged using standard java.util.logging.Logger framework |
ENABLE_AUTO_FLUSH_OUTGOING |
512 | If set, a separate thread is started which will automatically flush messages as they are written |
Connection Handling¶
| Method Name | Alternative Overloads | Description | Return Value |
|---|---|---|---|
void start(String host, int port, String loginId, int options) |
|
Starts the connection with the supplied parameters. Overloaded methods can be used to optionally supply SSL connection details | |
int getOptions() |
Options passed into start() |
Summed value of supplied options | |
void close() |
Close the connection and stop trying to reconnect | ||
boolean connect() |
Try and reconnect, will also send login (L) instructions | true if connected |
|
boolean isConnected() |
Check if there is a live connection to AMI | true if connected |
|
void addListener(AmiClientListener listener) |
Add a new listener for receiving callbacks on important events that occur during connection with AMI | ||
void removeListener(AmiClientListener listener) |
Remove an existing listener | ||
#java long getAutoReconnectFrequencyMs() |
Get how many ms to wait before trying to reconnect when in a disconnected state | value of autoReconnectFrequencyMs |
|
#java long setAutoReconnectFrequencyMs() |
Set the value in ms to wait before trying to reconnect when in a disconnected state | value of autoReconnectFrequencyMs |
|
boolean getDebugMessages() |
Get whether debug messages have been enabled | true if enabled |
|
void setDebugMessages() |
Set whether debug messages are enabled | ||
boolean waitForLogin(long i) |
Check whether AMI is waiting for a login | true if waiting |
Message Handling¶
| Method Name | Alternative Overloads | Description | Return Value |
|---|---|---|---|
boolean sendMessageAndFlush() |
Send the pending message to AMI and block until the message is fully read by AMI | ||
void sendMessageAndFlush(CharSequence cs) |
Send the input message to AMI and block until the message is fully read by AMI | false if there was an io error |
|
void flush() |
Send pending message buffer to AMI. Can be called anytime | ||
boolean pumpIncomingEvent() |
Check for an incoming message and fire appropriate callback if found. Available only if ENABLE_AUTO_PROCESS_INCOMING is disabled |
true if a message was processed, false if there were no queued messages for processing |
|
AmiClient startStatusMessage() |
Starts a status (S) message. Note, this is deprecated | This instance | |
AmiClient startObjectMessage(String type, CharSequence id) |
AmiClient startObjectMessage(String type, CharSequence id, long expiresOn) |
Starts an object (O) message.
|
This instance |
AmiClient startResponseMessage(String origRequestId) |
AmiClient startResponseMessage(String origRequestId, int status, String message) |
Starts a response (R) message.
|
This instance |
AmiClient startCommandDefinition(String id) |
Start a command definition (C) message. Give the command an id, or (I) field |
This instance | |
AmiClient startDeleteMessage(String type, String id) |
Start a delete (D) message.
|
This instance | |
void sendPause(int delayMs) |
Start a pause (P) message. delayMs = the number of ms to pause by, or (D) param |
||
AmiClient addMessageParamNull(CharSequence key) |
Add a parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamString(CharSequence key, CharSequence value) |
|
Add a String parameter to the current message being built corresponding to some key in an AMI target object | This instance |
AmiClient addMessageParamEnum(CharSequence key, CharSequence value) |
AmiClient addMessageParamEnum(CharSequence key, CharSequence value, int start, int end) |
Add an Enum parameter to the current message being built corresponding to some key in an AMI target object | This instance |
AmiClient addMessageParamJson(CharSequence key, Object value) |
Add an JSON parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamBinary(CharSequence key, byte[] value) |
AmiClient addMessageParamBinary(CharSequence key, byte[] value), int start, int end |
Add a Binary parameter to the current message being built corresponding to some key in an AMI target object | This instance |
AmiClient addMessageParamLong(CharSequence key, long value) |
Add a Long parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamInt(CharSequence key, int value) |
Add an Int parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamDouble(CharSequence key, double value) |
Add a Double parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamDoubleEncoded(CharSequence key, double value) |
Add an encoded Double parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamFloat(CharSequence key, float value) |
Add a Float parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamFloatEncoded(CharSequence key, float value) |
Add an encoded Float parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addMessageParamBoolean(CharSequence key, boolean value) |
Add a Boolean parameter to the current message being built corresponding to some key in an AMI target object | This instance | |
AmiClient addRawText(CharSequence text, int start, int end) |
Bypass this API and send the raw chars directly to AMI. The user is responsible for properly escaping, quoting, etc. | This instance | |
boolean sendMessage() |
Finalize and send the message currently being built | false if there was an io issue |
|
void resetMessage() |
Reset the pending message, a new message will need to be restarted | ||
AmiClient addMessageParams(Map<String,Object> params) |
Convenience message for quickly sending all the params from the supplied map where the key corresponds to some key in AMI and the object is the supplied value | This instance | |
void addMessageParamObject(String key, Object value) |
Convenience message for sending a boxed value. Value types are considered by the method such that "123" is sent as a String, 123 as an int, 123d as a double, etc. | ||
void flushAndWaitForReplys(int timeoutMs) |
Flush existing messages and wait for a response | ||
void sendCommandDefinition(AmiClientCommandDef def) |
Send a command (C) declaration to AMI by passing it a pre-defined AmiClientCommandDef object |
||
CharSequence getOutputBuffer() |
Get the current output message buffer | The output message buffer | |
AmiClient startMessage(char type) |
Start a message of the supplied type (O, I, E, etc) | This instance | |
long resetSeqNum(long seqnum) |
The sequence number to include on the next startMessage(...) when ENABLE_SEND_SEQNUM is enabled |
The old seqnum | |
long getAutoFlushBufferMillis() |
Get the value of the autoflush delay. Default is 2ms | The autoflush delay in ms | |
void setAutoFlushBufferMillis() |
Set the value of the autoflush delay. A higher number increases throughput at the cost of latency | ||
int getBufferSizeOut() |
Get the buffer size in Bytes for the outbound buffer (will force flush when buffer is filled). Default is 8192 | Buffer size of outbound buffer | |
void setBufferSizeOut(int bufferSizeOut) |
Set the buffer size in Bytes for the outbound buffer (will force flush when buffer is filled). Default is 8192 | ||
int int getBufferSizeIn() |
Get the buffer size in Bytes for the inbound buffer (number of Bytes attempted to be read off the socket in a single call). Default is 8192 | Buffer size of inbound buffer | |
void setBufferSizeIn(int bufferSizeIn) |
Set the buffer size in Bytes for the inbound buffer (number of Bytes attempted to be read off the socket in a single call). Default is 8192 |
AmiClientCommandDef Methods¶
Users can define their own executable commands from the Client that can be called within AMI which will trigger a callback that then gets sent back to the Client.
This is equivalent to calling a user sending a (C) message to AMI, then AMI sending an (E) message, followed by some optional event handling done in the Client which can include a (R) message. This handling is done in the onCommand(...) method.
Listed below are the available methods for defining an AmiClientCommandDef object.
Note
Calls to each method may be slightly different across different libraries. The information is provided for the base Java classes.
Please use this as reference only and refer to the specific library pages for examples in the corresponding language.
Settable Parameters¶
| Method Name | Description |
|---|---|
AmiClientCommandDef setCommandId(String commandId) |
Set the unique ID attributed to that command. Equivalent to the (I) param |
AmiClientCommandDef setLevel(Integer level) |
Set the permissions level of the command. 0 means remove the command, any other number is used for entitlements. Equivalent to (L) param |
AmiClientCommandDef setWhereClause(String whereClause) |
Set which rows the command will be available at. Equivalent to (W) param |
AmiClientCommandDef setHelp(String help) |
Set a help text that will be displayed in AMI. Equivalent to (H) param |
AmiClientCommandDef setName(String name) |
Set the name of the command. This is what is displayed in AMI. Equivalent to (H) param |
AmiClientCommandDef setPriority(Integer priority) |
Set the priority for display. Commands with higher priority are listed above lower priority in context menu where 0 is highest. Equivalent to (P) param |
AmiClientCommandDef setEnabledExpression(String enabledExpression) |
Set the command to be enabled only where the expression holds. Equivalent to (E) param |
AmiClientCommandDef setStyle(String style) |
Set style of the menu item in a JSON format. Equivalent to (S) param |
AmiClientCommandDef setSelectMode(Integer min, Integer max) |
Constrains number of rows that can be selected. Equivalent to (M) param |
AmiClientCommandDef setFields(String fields) |
Set the parameter the returned execute command should include. Equivalent to (F) param |
AmiClientCommandDef setFilterClause(String filterClause) |
Set a filter on what target objects the command should be available on. Equivalent to (T) param |
AmiClientCommandDef setConditions(String... conditions) |
Set the conditions in AMI on which the command should execute. The accepted conditions are listed below. Equivalent to (C) param |
Conditions¶
| Condition | Value | Description |
|---|---|---|
CONDITION_NOW |
"now" |
Fires when sent |
CONDITION_USER_CLICK |
"user_click" |
Fires on user-click |
CONDITION_USER_LOGIN |
"user_open_layout" |
Fires when user opens layout |
CONDITION_USER_LOGOUT |
"user_close_layout" |
Fires when user logs out |