You can find samples at: https://github.com/stomp-js/samples/.

The STOMP Broker

Ensure that your STOMP broker supports STOMP over WebSockets. Some messaging brokers supports it out of the box while some may need special configuration or activating plugins.

Include stompjs

This library is distributed as UMD package, so it allows usage from web browser, via require in Node, import from typescript/ES6.

Polyfills

Important: before using please check Polyfills & Critical Dependencies.

In Web Browser

In NodeJS

See Polyfills & Critical Dependencies for installing dependencies.

// For StompJs >= 5.1.0
StompJs = require('@stomp/stompjs');

// For StompJs 5.0.x
StompJs = require('@stomp/stompjs/esm5');

Read along to learn how to use the StompJs object.

TypeScript or ES6

See Polyfills & Critical Dependencies for installing dependencies.

These libraries have been developed using typescript and the distributions have typing already included.

You can import classes like the following:

import { Client, Message } from '@stomp/stompjs';

You can use these classes without prefixing with StompJs..

There is no StompJs class/object that can be imported.

Setting/getting options

All options can be set/get by directly operating on the client instance:

    const client = new StompJs.Client();
    client.brokerURL = "ws://localhost:15674/ws";
    
    console.log(client.brokerURL);

These can also be set passing key/value pairs to Client constructor or to Client#configure.

Create a STOMP client

STOMP JavaScript clients will communicate to a STOMP server using a ws:// or wss:// URL.

    const client = new StompJs.Client({
      brokerURL: "ws://localhost:15674/ws",
      connectHeaders: {
        login: "user",
        passcode: "password"
      },
      debug: function (str) {
        console.log(str);
      },
      reconnectDelay: 5000,
      heartbeatIncoming: 4000,
      heartbeatOutgoing: 4000
    });
    
    client.onConnect = function(frame) {
      // Do something, all subscribes must be done is this callback
      // This is needed because this will be executed after a (re)connect
    };
    
    client.onStompError = function (frame) {
      // Will be invoked in case of error encountered at Broker
      // Bad login/passcode typically will cause an error
      // Complaint brokers will set `message` header with a brief message. Body may contain details.
      // Compliant brokers will terminate the connection after any error
      console.log('Broker reported error: ' + frame.headers['message']);
      console.log('Additional details: ' + frame.body);
    };
    
    client.activate();

To deactivate a client call Client#deactivate. It will stop attempting to reconnect and disconnect if there is an active connection.

    client.deactivate();

Send messages

When the client is connected to the server, it can send STOMP messages using the Client#publish method.

    client.publish({destination: '/topic/general', body: 'Hello world'});

    // There is an option to skip content length header
    client.publish({destination: '/topic/general', body: 'Hello world', skipContentLengthHeader: true});
    
    // Additional headers
    client.publish({destination: '/topic/general', body: 'Hello world', headers: {'priority': '9'}});

Starting version 5, sending binary messages is supported. To send a binary message body use binaryBody parameter. It should be a Uint8Array.

    var binaryData = generateBinaryData(); // This need to be of type Uint8Array
    // setting content-type header is not mandatory, however a good practice
    client.publish({destination: '/topic/special', binaryBody: binaryData,
                    headers: {'content-type': 'application/octet-stream'}});

Subscribe and receive messages

To receive messages in the browser, the STOMP client must first subscribe to a destination.

You can use the Client#subscribe method to subscribe to a destination. The method takes 2 mandatory arguments: destination, a String corresponding to the destination and callback, a function with one message argument and an optional argument headers, a JavaScript object for additional headers.

  var subscription = client.subscribe("/queue/test", callback);

The subscribe() methods returns a JavaScript object with one attribute, id, that correspond to the client subscription ID and one method unsubscribe() that can be used later on to unsubscribe the client from this destination.

Every time the server sends a message to the client, the client will in turn invoke the callback with a Message object.

  callback = function(message) {
    // called when the client receives a STOMP message from the server
    if (message.body) {
      alert("got message with body " + message.body)
    } else {
      alert("got empty message");
    }
  };

The subscribe() method takes an optional headers argument to specify additional headers when subscribing to a destination:

  var headers = {ack: 'client'};
  client.subscribe("/queue/test", message_callback, headers);

The client specifies that it will handle the message acknowledgement.

To stop receiving messages, the client can use the unsubscribe method on the object returned by the Client#subscribe method.

  var subscription = client.subscribe("queue/test", onmessage);
 
  // ... use the subscription ...
  
  subscription.unsubscribe();

Binary messages

Prep your broker

Not every broker will support binary messages out of the box. For example RabbitMQ (see: https://www.rabbitmq.com/web-stomp.html) will need following to be added to the server configuration:

web_stomp.ws_frame = binary

Publishing binary messages

Use parameter binaryBody of Client#publish to send binary data of type Uint8Array.

See Send messages for an example.

Receiving binary messages

The library does not try to guess whether the incoming data is text/binary. When you access Message#body the message will be returned as string. To access the message body as binary please call Message#binaryBody.

There is no generally accepted convention in STOMP (actually messaging in general) to indicate that a message is binary. The message senders and receivers will need to agree on required convention.

You may choose to set content-type header to indicate binary message.

    // within message callback
    if (message.headers['content-type'] === 'application/octet-stream') {
      // message is binary
      // call message.binaryBody 
    } else {
      // message is text
      // call message.body
    }

JSON support

The body of a STOMP message must be a String. If you want to send and receive JSON objects, you can use JSON.stringify() and JSON.parse() to transform the JSON object to a String and vice versa.

  var quote = {symbol: 'APPL', value: 195.46};
  client.send("/topic/stocks", {}, JSON.stringify(quote));

  client.subcribe("/topic/stocks", function(message) {
    var quote = JSON.parse(message.body);
    alert(quote.symbol + " is at " + quote.value);
  });

Acknowledgment

By default, STOMP messages will be automatically acknowledged by the server before the message is delivered to the client.

The client can choose instead to handle message acknowledgement by subscribing to a destination and specify a ack header set to client or client-individual.

In that case, the client must use the Message#ack method to inform the server that it has processed the message.

  var subscription = client.subscribe("/queue/test",
    function(message) {
      // do something with the message
      // ...
      // and acknowledge it
      message.ack();
    },
    {ack: 'client'}
  );

The Message#ack method accepts headers argument for additional headers. For example, it is possible to acknowledge a message as part of a transaction and ask for a receipt when the ACK has effectively been processed by the broker:

  var tx = client.begin();
  message.ack({ transaction: tx.id, receipt: 'my-receipt' });
  tx.commit();

The Message#nack method can also be used to inform STOMP 1.1 or higher brokers that the client did not consume the message. It takes the same arguments than the Message#ack method.

Transactions

Messages can be sent and acknowledged in a transaction.

A transaction is started by the client using its Client#begin method which takes an optional transaction_id.

This methods returns a JavaScript object with an id attribute corresponding to the transaction ID and two methods:

The client can then send and/or acknowledge messages in the transaction by specifying a transaction set with the transaction id.

  // start the transaction
  var tx = client.begin();
  // send the message in a transaction
  client.publish({destination: "/queue/test", headers: {transaction: tx.id}, body: "message in a transaction"});
  // commit the transaction to effectively send the message
  tx.commit();

If you forget to add the transaction header when calling Client#publish the message will not be part of the transaction and will be sent directly without waiting for the completion of the transaction.

  // start the transaction
  var tx = client.begin();
  // oops! send the message outside the transaction
  client.publish({destination: "/queue/test", body: "message in a transaction"});
  tx.abort(); // Too late! the message has been sent

Heart-beating

If the STOMP broker accepts STOMP 1.1 or higher frames, heart-beating is enabled by default. Options Client#heartbeatIncoming and Client#heartbeatOutgoing can be used to control heart-beating (default value for both is 10,000ms). These can be disabled by setting to 0.

    client.heartbeatOutgoing = 20000; // client will send heartbeats every 20000ms
    client.heartbeatIncoming = 0;     // client does not want to receive heartbeats
                                       // from the server

Auto Reconnect

The client supports automatic reconnecting in case of a connection failure. It is controlled by a option Client#reconnectDelay. Default value is 5000ms, which indicates that a attempt to connect will be made after 5000ms of a connection drop.

  // Add the following if you need automatic reconnect (delay is in milli seconds)
  client.reconnectDelay = 300;

This can be set quite small.

Debug

By default, the debug messages are ignored. On a busy system volume of logs can be overwhelming.

Client#debug property can be set to a function (which will receive a String argument) to enable debug statements:

  client.debug = function(str) {
    console.log(str);
  };

Usually headers of the incoming and outgoing frames are logged. Set Client#logRawCommunication to log entire frames.

Callbacks

Lifecycle callbacks

  • Client#beforeConnect - invoked each time before connection to STOMP broker is attempted. You can modify connection parameters and other callbacks.
  • Client#onConnect - invoked for each time STOMP broker connects and STOMP handshake is complete
  • Client#onDisconnect - invoked after each graceful disconnection. If the connection breaks because of an error or network failure, it will no tbe called.
  • Client#onStompError - invoked when the broker reports an Error
  • Client#onWebSocketClose - when the WebSocket closes. It is most reliable way of knowing that the connection has terminated.

Frame callbacks

  • Client#onUnhandledMessage - typically brokers will send messages corresponding to subscriptions. However, brokers may support concepts that are beyond standard definition of STOMP - for example RabbitMQ support concepts of temporary queues. If any message is received that is not linked to a subscription, this callback will be invoked.
  • Client#onUnhandledReceipt - you should prefer Client#watchForReceipt. If there is any incoming receipt for which there is no active watcher, this callback will be invoked.
  • Client#onUnhandledFrame - it will be invoked if broker sends a non standard STOMP command.

Advanced notes

The version 5 of this library has taken significant variation from previous syntax. This version allows all of the options and callbacks to be altered. New values will take effect as soon as possible. For example:

The callback sequences are arranged in a way that most expected operations should work. For example it is possible to call Client#deactivate within Client#onStompError or Client#onWebSocketClose. This is useful if we determine that we have incorrect credentials and no point keep on trying to connect.

The above also allows readjusting Client#reconnectDelay in Client#onWebSocketClose. This can be used to implement exponential back-off before each successive reconnect attempt.

Even Client#brokerURL or Client#connectHeaders can be altered which would get used in a subsequent reconnect. However, I will suggest creating a new instance of the STOMP client in this scenario.