Introducing the AMPS JavaScript Client

  Mar 15, 2017   |      Pavel K.

amps javascript client

minified JavaScript client code

AMPS is a very robust system due to its amazing performance, flexibility, and reliability. 60East already provides client libraries for C/C++, C#, Java, and Python, and today we introduce the first version of our official JavaScript client that will power up both modern front end web applications and Node.js-backed back end applications.

Features available in this version of the JavaScript client:

  • Minimal external dependencies (WebSocket and Promise)
  • A fully asynchronous Promise-based interface
  • Convenience methods for common commands, such as publish, subscribe, sow, deltaSubscribe
  • A heartbeat mode for quickly detecting connection failures
  • A Command interface for fine-grained control over commands and their options
  • Support of enterprise authentication systems, such as Kerberos, NTLM, and Basic Auth
  • Support of Authenticators for custom authentication scenarios

Let’s take a closer look and see it in action!

Easy to Get, Easy to Use

The client is designed and built to have as few dependencies as possible. It is compatible with both Browser and Node.js environments.

For example, in order to use it in the browser environment, here’s all it takes to get a working AMPS client in your web application:

<!-- Optional import support for obsolete browsers -->
<script src="es6-promise.min.js"></script>
<script src="amps.js"></script>

The distribution already contains ES6-Promise polyfill to support obsolete browsers.

Born Asynchronous to Live Free (From Blocking)

The client adopts the JavaScript style and design approach in order to deliver the most intuitive, fully asynchronous interface for JavaScript developers. The client is very easy to use due to heavy use of the Promise feature.

Promises are objects that encapsulate values that may be available now, in the future, or never. In the asynchronous world of JavaScript this is a convenient way of structuring and organizing actions that may take an uncertain amount of time to execute.

To demonstrate the idea of the Promise, check out how the client connects to the AMPS server:

let client = new amps.Client()

client
  .connect('wss://fortune500company.com:9100/amps/json')
  .then(() => client.publish('test-topic', {id: 7}))
  .catch(err => console.error('Connection Error: ', err))
In code examples, we use the new JavaScript ES6 syntax

Even though the above code is executed in the non-blocking asynchronous mode, the syntax is very compact and resembles the traditional synchronous style, thanks to Promises!

Get Used to Convenience

The client includes a full set of convenience methods that make common tasks easier to do. Here’s how we can subscribe to topics, and then publish to them using subscribe() and publish():

let onMessage = (message) => console.log(message.data)
let client = new amps.Client()

client
  .connect('wss://fortune500company.com:9100/amps/json')

  // connected, subscribe for the first topic
  .then(() => client.subscribe(onMessage, 'orders', '/qty > 0'))
  // second subscription
  .then(() => client.subscribe(onMessage, 'reservations'))
  // third subscription
  .then(() => client.subscribe(onMessage, 'notifications'))

  // now we can publish messages to these topics
  .then(() => {
    client.publish('notifications', {note: 'Ordered Tesla 3'})
    client.publish('orders', {order: 'Tesla 3', qty: 10})
    client.publish('reservations', {res: 'Tesla 3', qty: 10})
  })

  // if any subscription failed, the chain will end up here
  .catch(console.error)

In the example above we subscribe to three different topics, and make the subscriptions sequentially. That is, we’re waiting for the first subscription to be processed, then the second and finally the third. However, we can make our application a bit faster by parallelizing this process:

client
  .connect('wss://fortune500company.com:9100/amps/json')

  // connected, subscribe to topics in parallel
  .then(() => Promise.all([
    client.subscribe(onMessage, 'orders', '/qty > 0'),
    client.subscribe(onMessage, 'reservations'),
    client.subscribe(onMessage, 'notifications')
  ]))

  // subscribed to all topics at this point
  .then(subscriptionIds => {
    console.log('ids of subscriptions: ', subscriptionIds)

    client.publish('notifications', {note: 'Ordered Tesla 3'})
    client.publish('orders', {order: 'Tesla 3', qty: 10})
    client.publish('reservations', {res: 'Tesla 3', qty: 10})
  })

All convenience methods return a Promise object, which allows us to chain and parallelize them. The publish() method is an exception, since publish() does not wait for confirmation of processing from the server by default. (It is possible to confirm the publish by making a custom Command object.)

I Measure the Moment in the Heartbeats I Skip

The heartbeat feature is a quick and reliable way of detecting connection failures. It’s simple to set up, and convenient to use:

let onError = err => console.log('Heartbeat: ', err)

let client = new amps.Client()
  .heartbeat(5) // 5 seconds between beats
  .errorHandler(onError)

In the above example the AMPS server will publish periodic heartbeat messages every 5 seconds to the client and will expect the client to respond with a heartbeat message. If the client does not provide a heartbeat within the time specified, the server logs an error and disconnects the connection. The client will report the heartbeat error to its dedicated error handler. The heartbeat() command can be used again in order to refresh the timer and/or change the heartbeat period.

Command Interface: You Have Full Control

The client includes a low-level interface for constructing AMPS commands, the Command interface. Compared to the convenience methods, Commands have the full range of options and controls to set:

  • command name
  • message hander
  • options, such as ackType, orderBy, bookmark and many more
  • flags (a comma separated list of values available to a command)

Here’s the example of a publish command that confirms the processing of a published message by the server:

let client = new amps.Client()

client
  .connect('wss://fortune500company.com:9100/amps/json')

  // connected, let's publish a message with confirmation
  .then(() => {
    let publishCommand = new amps.Command('publish')
      .topic('orders')
      .data({order: 'Tesla 3', qty: 10})
      .ackType('persisted')

    return client.execute(
      publishCommand,
      ack => {
        console.log('message persisted: ', ack)
        client.disconnect()
      })
  })

  // connection or command execution error
  .catch(console.error)

Try it Today!

The new JavaScript client is available starting today for all our customers. Get the latest version from the Downloads page. The API reference and the quick-start guide are available here.

It’s Not What JavaScript Can Do for AMPS, It’s What AMPS Can Do for JavaScript

Behind the scenes, AMPS offers rich features to create the most flexible, scalable and responsive view servers. By combining database, messaging and aggregation technology into one integrated engine, one can reduce data movement and exploit concurrency. More importantly, this design allows us to offer extremely valuable capabilities. For example, imagine being able to populate your GUIs with a query to the AMPS State of the World database and subscribing to the real time message flow in one single atomic step!

Here are just some of the other ways that AMPS amplifies your JavaScript systems:

  • The power of Content Filtering. AMPS allows you to flexibly reduce the message flow to clients based on the content of each message - mitigating network congestion when scaling up to thousands of users or more and reducing the processing burden on each client at the same time;
  • With Delta Messaging, your applications can publish or subscribe to only the parts of a message with changed data;
  • With Out of Focus Notification, applications receive notification when a previously-received message is no longer relevant to a subscription;
  • With Aggregations with Joins, AMPS offers real time aggregation of streams of data, including the ability to join and aggregate streams of different message types;
  • A powerful Replay Engine for back testing and rapid recovery.

Please share your feedback and comments with us. We also want to express our gratitude for those customers who worked with us while the JavaScript client was in beta testing stages. Who knew that there were that many browsers to test on??? :)

Want to see the JavaScript client in action now, right from your browser? Check out the Basketball Replay Demo and the related blog post

Read Next:   Get more AMPS with Galvanometer