## Protocol Details

### Overview

This section describes the format of Stomp data packets , as well as the semantics of the data packet exchanges. Stomp is a relatively simple wire protocol—it is even possible to communicate manually with a Stomp broker using a `telnet` client (see Stomp Tutorial ).

### Transport protocols

In principal, Stomp can be combined with any transport protocol, including connection-oriented and non-connection-oriented transports. In practice, though, Stomp is usually implemented over TCP and this is the only transport currently supported by FUSE Message Broker.

### Licence

The Stomp specification is licensed under the Creative Commons Attribution v2.5

### Stomp frame format

The Stomp specification defines the term frame to refer to the data packets transmitted over a Stomp connection. A Stomp frame has the following general format:

    <StompCommand>
    <HeaderName_1>:<HeaderValue_1>
    <HeaderName_2>:<HeaderValue_2>

    <FrameBody>
    ^@

A Stomp frame always starts with a Stomp command (for example, `SEND`) on a line by itself. The Stomp command may then be followed by zero or more header lines: each header is in a `<key>:<value>` format and terminated by a newline. A blank line indicates the end of the headers and the beginning of the body, `<FrameBody>`, (which is empty for many of the commands). The frame is terminated by the null character, which is represented as `^@` above (Ctrl-@ in ASCII)).

### Oneway and RPC commands

Most Stomp commands have oneway semantics (that is, after sending a frame, the sender does not expect any reply). The only exceptions are:

- `CONNECT` command—after a client sends a `CONNECT` frame, it expects the server to reply with a `CONNECTED` frame.

- Commands with a `receipt` header—a client can force the server to acknowledge receipt of a command by adding a `receipt` header to the outgoing frame.

- Erroneous commands—if a client sends a frame that is malformed, or otherwise in error, the server may reply with an `ERROR` frame. Note, however, that the `ERROR` frame is not formally correlated with the original frame that caused the error (Stomp frames are not required to include a unique identifier).

### Receipt header

Any client frame, other than `CONNECT`, may specify a `receipt` header with an arbitrary value. This causes the server to acknowledge receipt of the frame with a `RECEIPT` frame, which contains the value of this header as the value of the `receipt-id` header in the `RECEIPT` frame. For example, the following frame shows a `SEND` command that includes a receipt header:

    SEND
    destination:/queue/a
    receipt:message-12345

    Hello a!^@

### Client commands

Table 3.2 lists the client commands for the Stomp protocol. The Reply column indicates whether or not the server sends a reply frame by default.

Table 3.2. Client Commands for the Stomp Protocol

Command | Reply? | Role | Description
--- | --- | --- | ---
CONNECT | Yes | Producer, Consumer | Open a connection to a Stomp broker (server).
SEND | No | Producer | Send a message to a particular queue or topic on the server.
SUBSCRIBE | No | Consumer | Subscribe to a particular queue or topic on the server.
UNSUBSCRIBE | No | Consumer | Cancel a subscription to a particular queue or topic.
ACK | No | Consumer | Acknowledge receipt of one message.
BEGIN | No | Producer, Consumer | Start a transaction (applies to `SEND` or `ACK` commands).
COMMIT | No | Producer, Consumer | Commit a transaction.
ABORT | No | Producer, Consumer | Roll back a transaction.
DISCONNECT | No | Producer, Consumer | Shut down the existing connection gracefully.

### CONNECT

After opening a socket to connect to the remote server, the client sends a `CONNECT` command to initiate a Stomp session. For example, the following frame shows a typical `CONNECT` command, including a `login` header and a `passcode` header:

    CONNECT
    login: <username>
    passcode:<passcode>

    ^@

After the client sends the `CONNECT` frame, the server always acknowledges the connection by sending a frame, as follows:

    CONNECTED
    session: <session-id>

    ^@

The `session-id` header is a unique identifier for this session (currently unused).

### SEND

The `SEND` command sends a message to a destination—for example, a queue or a topic—in the messaging system. It has one required header, `destination`, which indicates where to send the message. The body of the `SEND` command is the message to be sent. For example, the following frame sends a message to the `/queue/a` destination:

    SEND
    destination:/queue/a
    hello queue a

    ^@

From the client’s perspective, the destination name, `/queue/a`, is an arbitrary string. Despite seeming to indicate that the destination is a queue it does not, in fact, specify any such thing. Destination names are simply strings that are mapped to some form of destination on the server; how the server translates these strings is up to the implementation.

The `SEND` command also supports the following optional headers:

- `transaction`—specifies the transaction ID. Include this header, if the `SEND` command partakes in a transaction (see BEGIN ).

- `content-length`—specifies the byte count for the length of the message body. If a `content-length` header is included, this number of bytes should be read, regardless of whether or not there are null characters in the body. The frame still needs to be terminated with a null byte and if a content-length is not specified, the first null byte encountered signals the end of the frame.

### SUBSCRIBE

The `SUBSCRIBE` command registers a client’s interest in listening to a specific destination. Like the `SEND` command, the `SUBSCRIBE` command requires a `destination` header. Henceforth, any messages received on the subscription are delivered as `MESSAGE` frames, from the server to the client. For example, the following frame shows a client subscribing to the destination, `/queue/a`:

    SUBSCRIBE
    destination: /queue/foo
    ack: client

    ^@

In this case the `ack` header is set to `client`, which means that messages are considered delivered only after the client specifically acknowledges them with an `ACK` frame. The body of the `SUBSCRIBE` command is ignored.

The `SUBSCRIBE` command supports the following optional headers:

- `ack`—specify the acknowledgement mode for this subscription. The following modes are recognized:

  - `auto`—messages are considered delivered as soon as the server delivers them to the client (in the form of a `MESSAGE` command). The server does not expect to receive any `ACK` commands from the client for this subscription.

  - `client`—messages are considered delivered only after the client specifically acknowledges them with an `ACK` frame.

- `selector`—specifies a SQL 92 selector on the message headers, which acts as a filter for content based routing.

- `id`—specify an ID to identify this subscription. Later, you can use the ID to `UNSUBSCRIBE` from this subscription (you may end up with overlapping subscriptions, if multiple selectors match the same destination).

  When an `id` header is supplied, the server should append a `subscription` header to any `MESSAGE` commands sent to the client. When using wildcards and selectors, this enables clients to figure out which subscription triggered the message.

### UNSUBSCRIBE

The `UNSUBSCRIBE` command removes an existing subscription, so that the client no longer receives messages from that destination. It requires either a `destination` header or an `id` header (if the previous `SUBSCRIBE` operation passed an `id` value). For example, the following frame cancels the subscription to the `/queue/a` destination:

    UNSUBSCRIBE
    destination: /queue/a

    ^@

### ACK

The `ACK` command acknowledges the consumption of a message from a subscription. If the client issued a `SUBSCRIBE` frame with an `ack` header set to `client`, any messages received from that destination are not considered to have been consumed until the message is acknowledged by an `ACK` frame.

The `ACK` command has one required header, `message-id`, which must contain a value matching the `message-id` for the `MESSAGE` being acknowledged. Optionally, a `transaction` header may be included, if the acknowledgment participates in a transaction. For example, the following frame acknowledges a message in the context of a transaction:

    ACK
    message-id: <message-identifier>
    transaction: <transaction-identifier>

    ^@

### BEGIN

The `BEGIN` command initiates a transaction. Transactions can be applied to `SEND` and `ACK` commands. Any messages sent or acknowledged during a transaction can either be commited or rolled back at the end of the transaction.

    BEGIN
    transaction: <transaction-identifier>

    ^@

The `transaction` header is required and the `<transaction-identifier>` can be included in `SEND`, `COMMIT`, `ABORT`, and `ACK` frames to bind them to the named transaction.

### COMMIT

The `COMMIT` command commits a specific transaction.

    COMMIT
    transaction: <transaction-identifier>

    ^@

The `transaction` header is required and specifies the transaction, `<transaction-identifier>`, to commit.

### ABORT

The `ABORT` command rolls back a specific transaction.

    ABORT
    transaction: <transaction-identifier>

    ^@

The `transaction` header is required and specifies the transaction, `<transaction-identifier>`, to roll back.

### DISCONNECT

The `DISCONNECT` command disconnects gracefully from the server.

    DISCONNECT

    ^@

### Server commands

Table 3.3 lists the commands that the server can send to a Stomp client. These commands all have oneway semantics.

Table 3.3. Server Commands for the Stomp Protocol

Command | Description
--- | ---
MESSAGE | Send a message to the client, where the client has previously registered a subscription with the server.
RECEIPT | Acknowledges receipt of a client command, if the client requested a receipt by included a `receipt-id` header.
ERROR | Error message sent from the server to the client.

### MESSAGE

The `MESSAGE` command conveys messages from a subscription to the client. The `MESSAGE` frame must include a `destination` header, which identifies the destination from which the message is taken. The `MESSAGE` frame also contains a `message-id` header with a unique message identifier. The frame body contains the message contents. For example, the following frame shows a typical `MESSAGE` command with `destination` and `message-id` headers:

    MESSAGE
    destination:/queue/a
    message-id: <message-identifier>

    hello queue a^@

The `MESSAGE` command supports the following optional headers:

- `content-length`—specifies the byte count for the length of the message body. If a `content-length` header is included, this number of bytes should be read, regardless of whether or not there are null characters in the body. The frame still needs to be terminated with a null byte and if a content-length is not specified, the first null byte encountered signals the end of the frame.

### RECEIPT

A `RECEIPT` frame is issued from the server whenever the client requests a receipt for a given command. The `RECEIPT` frame includes a `receipt-id`, containing the value of the `receipt-id` from the original client request. For example, the following frame shows a typical `RECEIPT` command with `receipt-id` header:

    RECEIPT
    receipt-id:message-12345

    ^@

The receipt body is always empty.

### ERROR

The server may send `ERROR` frames if something goes wrong. The error frame should contain a `message` header with a short description of the error. The body may contain more detailed information (or may be empty). For example, the following frame shows an `ERROR` command with a non-empty body:

    ERROR
    message: malformed packet received

    The message:
    -----
    MESSAGE
    destined:/queue/a
    Hello queue a!
    -----
    Did not contain a destination header, which is required for message
    propagation.
    ^@

The `ERROR` command supports the following optional headers:

- `content-length`—specifies the byte count for the length of the message body. If a `content-length` header is included, this number of bytes should be read, regardless of whether or not there are null characters in the body. The frame still needs to be terminated with a null byte and if a content-length is not specified, the first null byte encountered signals the end of the frame.