Every distributed system will experience occasional disconnections between one or more nodes. The reliability of the overall system depends on an application's ability to efficiently detect and recover from these disconnections. Using the AMPS JavaScript client's disconnect handling, you can build powerful applications that are resilient in the face of connection failures and spurious disconnects. For additional reliability, you can also use the high availability functionality (discussed in the following sections), which provides both disconnect handling and features to help ensure that messages are reliably delivered.
In every distributed system, the robustness of your application depends on its ability to recover gracefully from unexpected events. The AMPS client provides the building blocks necessary to ensure your application can recover from the kinds of errors and special events that may occur when using AMPS.
The AMPS client includes a heartbeat feature to help applications detect disconnection from the server within a predictable amount of time. Without using a heartbeat, an application must rely on the environment to notify it when a disconnect occurs. For applications that are simply receiving messages, it can be impossible to tell whether a socket is disconnected or whether there are simply no incoming messages for the client.
When you set a heartbeat, the AMPS client sends a heartbeat message to the AMPS server at a regular interval, and waits a specified amount of time for the response. If the operating system reports an error on send, or if the server does not respond within the specified amount of time, the AMPS client considers the server to be disconnected.
The AMPS client processes heartbeat messages asynchronously. If your application publishes messages in a loop (a synchronous operation), or the message handler is receiving significant amount of messages at the moment, the client may fail to respond to heartbeat messages in a timely manner and may be disconnected by the server.
The Client
class, included with the AMPS JavaScript client, contains a disconnect handler and other features for building highly-available applications. The Client
includes features for managing a list of failover servers, resuming subscriptions, republishing in-flight messages, and other functionality that is commonly needed for high availability. This section covers the use of a custom disconnect handler in the event that the behavior of the Client
does not suit the needs of your application. 60East recommends using the provided disconnect handler unless there is specific behavior that does not meet your needs (for example, if your application does not want to reconnect to AMPS in the event of a disconnection).
The Client
class in the JavaScript library combines functionality of both Client
and HAClient
classes of other AMPS client libraries.
The Client
class contains a disconnect handler and other features for building highly-available applications. The Client
includes features for managing a list of failover servers, resuming subscriptions, republishing in-flight messages, and other functionality that is commonly needed for high availability. 60East recommends using the Client
for automatic reconnection wherever possible, as the disconnect handler has been carefully crafted to handle a wide variety of edge cases and potential failures.
If an application needs to reconnect or fail over, use a Client
with a ServerChooser
set, and the AMPS client library will automatically handle failover and reconnection. You control which servers the client fails over to by implementing the ServerChooser
and you can control the timing of the failover by using one of the provided ReconnectDelayStrategy
classes or implementing your own.
For most applications, the combination of the provided Client
disconnect handler and a ConnectionStateListener
gives you the ability to monitor disconnections and add custom behavior at the appropriate point in the reconnection process.
If you need to add custom behavior to the failover (such as logging, resetting an internal cache, refreshing credentials and so on), the ConnectionStateListener
class allows your application to be notified and take action when disconnection is detected and at each stage of the reconnection process.
To extend the behavior of the AMPS client during reconnection, implement a ConnectionStateListener
.
In some cases, an application does not want the AMPS Client
to reconnect, but instead wants to take a different action if disconnection occurs. For example, a stateless publisher that sends ephemeral data (such as telemetry or prices) may want to exit with an error if the connection is lost rather than risk falling behind and providing outdated messages. Often, in this case, a monitoring process will start another publisher if a publisher fails, and it is better for a message to be lost than to arrive late.
To cover cases where the application has unusual needs, the AMPS client library allows an application to provide custom disconnect handling.
Your application gets to specify exactly what happens when a disconnect occurs by supplying a function to client.setDisconnectHandler()
, which is invoked whenever a disconnect occurs. This may be helpful for situations where a particular connection needs to do something completely different than reconnecting or failing over to another AMPS server.
Setting the disconnect handler completely replaces the disconnection failover behavior for a Client
.
The example below shows the basics:
When using the asynchronous interface, errors can occur that are not thrown to the user. For example, when a message with invalid JSON data was received, the error occurs in the process of parsing its data inside of the AMPS JavaScript Client. Consider the following example:
In this example, we set up a subscription to wait for messages on the pokes topic, whose Pokee tag begins with our user ID. When messages arrive, we print a message out to the console.
Inside of the AMPS client, the client received an message that contains invalid JSON data that cannot be parsed. When the error occurs, there is no handler for it to be reported to, and by default it is ignored.
In applications where it is important to deal with every issue that occurs in using AMPS, you can set an error handler via Client.errorHandler()
that receives these otherwise-unhandled errors and exceptions. Making the modifications shown in the example below, to our previous example, will allow those errors to be caught and handled. In this case we are simply printing those caught errors out to the console.
In this example we have added a call to client.errorHandler()
, registering a simple function that writes the text of the error out to the console. If errors are thrown in the message handler, those errors are written to the console.