3. Your First AMPS Program

In this chapter, we will learn more about the structure and features of the AMPS JavaScript client and build our first JavaScript program using AMPS.

Let’s begin by writing a simple program that connects to an AMPS server and sends a single message to a topic. This code will be covered in detail just following the example.

About the Client Library

The AMPS client library is packaged as a single file, amps.js in development environments, or amps.min.js for production. Every JavaScript application you build will need to reference this file, and the file must be deployed along with your application in order for your application to function properly. Alternatively, for applications that are distributed through NPM, the client library can be listed as a dependency, and thus installed automatically.

Including the Client in a Project

There are several ways of including the JavaScript client in order to use it. Depending on your project’s structure and environment, you can include the client in one of the following ways.

Node.js / CommonJS module

// Include the library installed through NPM
var amps = require('amps');

// or

// Include the library after manual download
var amps = require('./lib/amps');

Example 3.1: Node.js / CommonJS module

ES6 / TypeScript module

// NPM installation: Import everything at once
import * as amps from 'amps';

// or

// NPM installation: Include only selected components of AMPS
import { Client, Command } from 'amps';

// Same as above with manual installation
import * as amps from './lib/amps';
import { Client, Command } from './lib/amps';

Example 3.2: ES6 / TypeScript module

In case of TypeScript and manual installation, you need to reference the typing file (provided within the client package) at the top of the file:

/// <reference path="./lib/amps.d.ts" />

The AMPS JavaScript NPM package already includes typings, so that the library can be seamlessly used in native TypeScript projects.

AMD / RequireJS module

// Included library will be available as the parameter `amps`
define(['./lib/amps'], function(amps) {
    // ...
}

Example 3.3: AMD / RequireJS module

Global import in a Browser environment

<!-- Optional import, to support obsolete browsers like IE11 -->
<script src="/lib/es6-promise.min.js"></script>
<script src="/lib/amps.js"></script>

Example 3.4: Global import in a Browser

Once the library in included in the HTML file, it becomes available as a global object, either as amps or window.amps.

Connecting to AMPS

/**
 * The URI to use to connect to AMPS. The URI consists of
 * the transport, the address, and the protocol to use for
 * the AMPS connection. In this case, the transport is `wss`
 * (WebSocket Secure), the address is `127.0.0.1:9007`, and
 * the protocol is `amps`. This connection will be used for
 * JSON messages. Check with the person who manages the AMPS
 * instance to get the connection string to use for your programs.
 */
var uri = 'wss://127.0.0.1:9007/amps/json';

/**
 * This line creates a new Client object. Client encapsulates
 * a single connection to an AMPS server. Methods on Client allow
 * for connecting, disconnecting, publishing, and subscribing to
 * an AMPS server. The argument to the Client constructor,
 * `examplePublisher`, is a name chosen by the client to identify
 * itself to the server. Errors relating to this connection will be
 * logged with reference to this name, and AMPS uses this name to
 * help detect duplicate messages. AMPS enforces uniqueness for
 * client names when a transaction log is configured, and it is
 * good practice to always use unique client names.
 */
var client = new amps.Client('examplePublisher');

/**
 * Now, we attempt to connect to the AMPS server. Most API methods
 * use the Promise pattern to encapsulate asynchronous operations,
 * such as connecting or subscribing.
 * For example, once the connection is established, the function
 * in the `then()` clause will be called; if the call to connect()
 * fails because the provided address is not reachable, the function
 * in `catch()` clause will be called with an Error object argument
 * that contains information about the occurred error.
 */

// Here, we provide URI to the client and declare the AMPS connection.
client.connect(uri)

    // Successful connection
    .then(function() {
        /**
        * Here, we publish a single message to AMPS on the messages
        * topic, containing the data `Hello, world!`. This data is
        * placed into a JSON message and sent to the server. Upon
        * successful completion of this function, the AMPS client has
        * sent the message to be sent to the server, and subscribers
        * to the messages topic will receive this JSON message:
        * { "hi": "Hello, world!" }.
        */
        client.publish('messages', {hi: 'Hello, world!'});

        /**
        * We close the connection to AMPS. While that doesn't matter
        * here, since the application exits immediately after calling
        * disconnect(), it's good practice to close connections when you
        * are done using them.
        */
        client.disconnect();
    })

    // Failed connection error
    .catch(function(error) {
        console.error(error);
    });

Example 3.5: Connecting to AMPS

Syntax convention

In the above example and throughout this guide we use the classic JavaScript syntax which is widely supported and does not require additional conversions or transpiling to be executed. However, the JavaScript client library fully supports modern syntax as well. Below is the same program, written in the new ES7 syntax.

import { Client } from 'amps'

(async function main() {

  const client = new Client('examplePublisher')

  try {
    await client.connect('wss://127.0.0.1:9007/amps/json')

    client.publish('messages', {hi: 'Hello, World!'})
    client.disconnect()
  }
  catch (error) {
    console.error(error)
  }

})()

Example 3.6: Connecting to AMPS: ES7 Syntax

Client Names

AMPS uses the name of the client as a session identifier and as part of the identifier for a message. For this reason, when a transaction log is enabled in the AMPS instance (that is, when the instance is recording a sequence of publishes and attempting to eliminate duplicate publishes), an AMPS instance will only allow one application with a given client name to connect to the instance.

When a transaction log is present, AMPS requires the Client Name for a publisher to be:

  • Unique within a set of replicated AMPS instances
  • Consistent from invocation to invocation if the publisher will be publishing tthe same logical stream of messages

60East recommends always using consistent, unique client names. For example, the client name could be formed by combining the application name, an identifier for the host system, and the id of the user running the application. A strategy like this provides a name that will be different for different users or on different systems, but consistent for instances of the application that should be treated as equivalent to the AMPS system.

Connection Strings

The AMPS clients use connection strings to determine the server, port, transport, and protocol to use to connect to AMPS. When the connection point in AMPS accepts multiple message types, the connection string also specifies the precise message type to use for this connection. Connection strings have a number of elements.

elements of a connection string

Figure 3.1: elements of a connection string

As shown in the figure above, connection strings have the following elements:

  • Transport defines the network used to send and receive messages from AMPS. In this case, the transport is wss.

    caution ws (WebSocket) and wss (WebSocket Secure) are the only supported transports for the JavaScript client.


  • Host address defines the destination on the network where the AMPS instance receives messages. The format of the address is dependent on the transport. For ws and wss, the address consists of a host name and port number. In this case, the host address is localhost:9007.

  • Protocol sets the format in which AMPS receives commands from the client. Most code uses the default amps protocol, which sends header information in JSON format. AMPS supports the ability to develop custom protocols as extension modules, and AMPS also supports legacy protocols for backward compatibility.

  • Message Type specifies the message type that this connection uses. This component of the connection string is required if the protocol accepts multiple message types and the transport is configured to accept multiple message types. If the protocol does not accept multiple message types, this component of the connection string is optional, and defaults to the message type specified in the transport.

    Legacy protocols such as fix, nvfix and xml only accept a single message type, and therefore do not require or accept a message type in the connection string.

The JavaScript client does not support legacy protocols, the amps protocol is required.

As an example, a connection string such as

ws://localhost:9007/amps/json

would work for programs connecting from the local host to a Transport configured as follows:

<AMPSConfig>
...

<Protocols>
    ...

    <!-- This protocol is using the websocket module,which is
    required for JavaScript client. -->
    <Protocol>
        <Name>websocket-any</Name>
        <Module>websocket</Module>
    </Protocol>

</Protocols>

...

<Transports>
    ...

    <!-- This transport accepts any known message type for
    the instance: the client must specify the message type. -->
    <Transport>
        <Name>websocket-any</Name>
        <Type>tcp</Type>
        <InetAddr>9007</InetAddr>
        <Protocol>websocket-any</Protocol>
    </Transport>

</Transports>

...

</AMPSConfig>

See the AMPS Configuration Guide for more information on configuring transports and protocols.

Providing Credentials in a Connection String

When using the default authenticator, the AMPS clients support the standard format for including a username and password in a URI, as shown below:

ws://user:password@host:port/protocol/message_type

When provided in this form, the default authenticator provides the username and password specified in the URI. If you have implemented another authenticator, that authenticator controls how passwords are provided to the AMPS server.

Next steps

You are now able to develop and deploy an application in JavaScript that publishes messages to AMPS. In the following chapters, you will learn how to subscribe to messages, use content filters, work with SOW caches, and fine-tune messages that you send.