Browse files

add STOMP documentation

Signed-off-by: Nicolas Sebrecht <ni.s@laposte.net>
  • Loading branch information...
1 parent cf6c6c1 commit f0f6cbe3a582504db4feb642060e5233b049a529 @nicolas33 committed Dec 7, 2011
Showing with 896 additions and 0 deletions.
  1. +896 −0 doc/stomp/stomp-specification-1.1.html
View
896 doc/stomp/stomp-specification-1.1.html
@@ -0,0 +1,896 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ Architecture
+-->
+<html lang="en">
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
+ <meta content="The Simple Text Oriented Messaging Protocol" name="description"/>
+ <meta content="stomp,messaging,mom,middleware,specification" name="keywords"/>
+ <meta content="STOMP Specification" name="author"/>
+ <link type="text/css" rel="stylesheet" href="styles/impact/css/pygmentize.css"/>
+ <link type="text/css" rel="stylesheet" href="styles/impact/css/site.css"/>
+ <title></title>
+ </head>
+ <body>
+ <div id="navigation">
+ <div class="wrapper">
+<ul>
+<li><a href="index.html">STOMP</a></li>
+<li><a href="stomp-specification-1.1.html">1.1</a></li>
+<li><a href="implementations.html">Implementations</a></li>
+</ul> <div></div>
+ </div>
+ </div>
+ <div id="content">
+ <div class="wrapper">
+<h1 id = "STOMP_Protocol_Specification__Version_1_1">STOMP Protocol Specification, Version 1.1</h1>
+
+<p><div class="toc"><ul style="list-style:none;">
+ <li><a href="#Abstract">Abstract</a></li>
+ <li><a href="#Overview">Overview</a></li>
+ <li><ul style="list-style:none;">
+ <li><a href="#Background">Background</a></li>
+ <li><a href="#Protocol_Overview">Protocol Overview</a></li>
+ <li><a href="#Changes_in_the_Protocol">Changes in the Protocol</a></li>
+ <li><a href="#Design_Philosophy">Design Philosophy</a></li>
+ </ul></li>
+ <li><a href="#Conformance">Conformance</a></li>
+ <li><a href="#STOMP_Frames">STOMP Frames</a></li>
+ <li><ul style="list-style:none;">
+ <li><a href="#Value_Encoding">Value Encoding</a></li>
+ <li><a href="#Size_Limits">Size Limits</a></li>
+ <li><a href="#Repeated_Header_Entries">Repeated Header Entries</a></li>
+ </ul></li>
+ <li><a href="#Connecting">Connecting</a></li>
+ <li><ul style="list-style:none;">
+ <li><a href="#CONNECT_or_STOMP_Frame">CONNECT or STOMP Frame</a></li>
+ <li><a href="#CONNECTED_Frame">CONNECTED Frame</a></li>
+ </ul></li>
+ <li><a href="#Protocol_Negotiation">Protocol Negotiation</a></li>
+ <li><a href="#Once_Connected">Once Connected</a></li>
+ <li><a href="#Client_Frames">Client Frames</a></li>
+ <li><ul style="list-style:none;">
+ <li><a href="#SEND">SEND</a></li>
+ <li><a href="#SUBSCRIBE">SUBSCRIBE</a></li>
+ <li><ul style="list-style:none;">
+ <li><a href="#SUBSCRIBE_id_Header">SUBSCRIBE id Header</a></li>
+ <li><a href="#SUBSCRIBE_ack_Header">SUBSCRIBE ack Header</a></li>
+ </ul></li>
+ <li><a href="#UNSUBSCRIBE">UNSUBSCRIBE</a></li>
+ <li><a href="#ACK">ACK</a></li>
+ <li><a href="#NACK">NACK</a></li>
+ <li><a href="#BEGIN">BEGIN</a></li>
+ <li><a href="#COMMIT">COMMIT</a></li>
+ <li><a href="#ABORT">ABORT</a></li>
+ <li><a href="#DISCONNECT">DISCONNECT</a></li>
+ </ul></li>
+ <li><a href="#Standard_Headers">Standard Headers</a></li>
+ <li><ul style="list-style:none;">
+ <li><a href="#Header_content-length">Header content-length</a></li>
+ <li><a href="#Header_content-type">Header content-type</a></li>
+ <li><a href="#Header_receipt">Header receipt</a></li>
+ </ul></li>
+ <li><a href="#Server_Frames">Server Frames</a></li>
+ <li><ul style="list-style:none;">
+ <li><a href="#MESSAGE">MESSAGE</a></li>
+ <li><a href="#RECEIPT">RECEIPT</a></li>
+ <li><a href="#ERROR">ERROR</a></li>
+ </ul></li>
+ <li><a href="#Heart-beating">Heart-beating</a></li>
+ <li><a href="#Augmented_BNF">Augmented BNF</a></li>
+ <li><a href="#License">License</a></li>
+</ul></div></p>
+
+<h2 id = "Abstract">Abstract</h2>
+
+<p>STOMP is a simple interoperable protocol designed for asynchronous message
+passing between clients via mediating servers. It defines a text based
+wire-format for messages passed between these clients and servers.</p>
+
+<p>STOMP has been in active use for several years and is supported by many
+message brokers and client libraries. This specification defines the STOMP 1.1
+protocol and is an update to <a href="stomp-specification-1.0.html">STOMP 1.0</a>.</p>
+
+<p>Please send feedback to the stomp-spec@googlegroups.com mailing list.</p>
+
+<h2 id = "Overview">Overview</h2>
+
+<h3 id = "Background">Background</h3>
+
+<p>STOMP arose from a need to connect to enterprise message brokers from
+scripting languages such as Ruby, Python and Perl. In such an
+environment it is typically logically simple operations that are
+carried out such as 'reliably send a single message and disconnect'
+or 'consume all messages on a given destination'.</p>
+
+<p>It is an alternative to other open messaging protocols such as AMQP
+and implementation specific wire protocols used in JMS brokers such
+as OpenWire. It distinguishes itself by covering a small subset of
+commonly used messaging operations rather than providing a
+comprehensive messaging API.</p>
+
+<p>More recently STOMP has matured into a protocol which can be used past
+these simple use cases in terms of the wire-level features it now
+offers, but still maintains its core design principles of simplicity
+and interoperability.</p>
+
+<h3 id = "Protocol_Overview">Protocol Overview</h3>
+
+<p>STOMP is a frame based protocol, with frames modelled on HTTP. A frame
+consists of a command, a set of optional headers and an optional body. STOMP
+is text based but also allows for the transmission of binary messages. The
+default encoding for STOMP is UTF-8, but it supports the specification of
+alternative encodings for message bodies.</p>
+
+<p>A STOMP server is modelled as a set of destinations to which messages can be
+sent. The STOMP protocol treats destinations as opaque string and their syntax
+is server implementation specific. Additionally STOMP does not define what the
+delivery semantics of destinations should be. The delivery, or &ldquo;message
+exchange&rdquo;, semantics of destinations can vary from server to server and even
+from destination to destination. This allows servers to be creative with the
+semantics that they can support with STOMP.</p>
+
+<p>A STOMP client is a user-agent which can act in two (possibly simultaneous)
+modes:</p>
+
+<ul>
+<li><p>As a producer, sending messages to a destination on the server via a <code>SEND</code>
+frame</p></li>
+<li><p>As a consumer, sending a <code>SUBSCRIBE</code> frame for a given destination and
+receiving messages from the server as <code>MESSAGE</code> frames.</p></li>
+</ul>
+
+<h3 id = "Changes_in_the_Protocol">Changes in the Protocol</h3>
+
+<p>STOMP 1.1 is designed to be backwards compatible with STOMP 1.0 while
+introducing several new features not present in STOMP 1.0:</p>
+
+<ul>
+<li><p>protocol negotiation to allow for interoperability between clients and
+servers supporting successive versions of STOMP</p></li>
+<li><p>heartbeats to allow for reliable detection of disconnecting clients and
+servers</p></li>
+<li><p><code>NACK</code> frames for negative acknowledgment of message receipt</p></li>
+<li><p>Support for virtual hosting</p></li>
+</ul>
+
+<h3 id = "Design_Philosophy">Design Philosophy</h3>
+
+<p>The main philosophies driving the design of STOMP are simplicity and
+interoperability.</p>
+
+<p>STOMP is designed to be a lightweight protocol that is easy to implement both
+on the client and server side in a wide range of languages. This implies, in
+particular, that there are not many constraints on the architecture of servers
+and many features such as destination naming and reliability semantics are
+implementation specific.</p>
+
+<p>In this specification we will note features of servers which are not
+explicitly defined by STOMP 1.1. You should consult your STOMP server's
+documentation for the implementation specific details of these features.</p>
+
+<h2 id = "Conformance">Conformance</h2>
+
+<p>The key words &ldquo;MUST&rdquo;, &ldquo;MUST NOT&rdquo;, &ldquo;REQUIRED&rdquo;, &ldquo;SHALL&rdquo;, &ldquo;SHALL NOT&rdquo;, &ldquo;SHOULD&rdquo;,
+&ldquo;SHOULD NOT&rdquo;, &ldquo;RECOMMENDED&rdquo;, &ldquo;MAY&rdquo;, and &ldquo;OPTIONAL&rdquo; in this document are to be
+interpreted as described in RFC 2119.</p>
+
+<p>Implementations may impose implementation-specific limits on unconstrained
+inputs, e.g. to prevent denial of service attacks, to guard against running
+out of memory, or to work around platform-specific limitations.</p>
+
+<p>The conformance classes defined by this specification are STOMP clients and
+STOMP servers.</p>
+
+<h2 id = "STOMP_Frames">STOMP Frames</h2>
+
+<p>STOMP is a frame based protocol which assumes a reliable 2-way streaming
+network protocol (such as TCP) underneath. The client and server will
+communicate using STOMP frames sent over the stream. A frame's structure
+looks like:</p>
+
+<pre><code>COMMAND
+header1:value1
+header2:value2
+
+Body^@</code></pre>
+
+<p>The frame starts with a command string terminated by a newline. Following the
+command are one or more header entries in <code>&lt;key&gt;:&lt;value&gt;</code> format. Each header
+entry is terminated by a newline. A blank line indicates the end of the
+headers and the beginning of the body. The body is then followed by the null
+byte (0x00). The examples in this document will use <code>^@</code>, control-@ in ASCII,
+to represent the null byte. The null byte can be optionally followed by
+multiple newlines. For more details, on how to parse STOMP frames, see the
+<a href="#Augmented&#95;BNF">Augmented BNF</a> section of this document.</p>
+
+<p>All commands and header names referenced in this document are case sensitive.</p>
+
+<h3 id = "Value_Encoding">Value Encoding</h3>
+
+<p>The commands and headers are encoded in UTF-8. All frames except the <code>CONNECT</code>
+and <code>CONNECTED</code> frames will also escape any colon or newline octets found in
+the resulting UTF-8 encoded headers.</p>
+
+<p>Escaping is needed to allow header keys and values to contain those frame
+header delimiting octets as values. The <code>CONNECT</code> and <code>CONNECTED</code> frames do not
+escape the colon or newline octets in order to remain backward compatible with
+STOMP 1.0.</p>
+
+<p>C style string literal escapes are used to encode any colons and newlines that
+are found within the UTF-8 encoded headers. When decoding frame headers, the
+following transformations MUST be applied:</p>
+
+<ul>
+<li><code>\n</code> (octet 92 and 110) translates to newline (octet 10)</li>
+<li><code>\c</code> (octet 92 and 99) translates to <code>:</code> (octet 58)</li>
+<li><code>\\</code> (octet 92 and 92) translates to <code>\</code> (octet 92)</li>
+</ul>
+
+<p>Undefined escape sequences such as <code>\r</code> (octet 92 and 114) MUST be treated as
+a fatal protocol error. Conversely when encoding frame headers, the reverse
+transformation MUST be applied.</p>
+
+<p>Only the <code>SEND</code>, <code>MESSAGE</code>, and <code>ERROR</code> frames can have a body. All other
+frames MUST NOT have a body.</p>
+
+<p>The STOMP 1.0 specification included many example frames with padding in the
+headers and many servers and clients were implemented to trim or pad header
+values. This causes problems if applications want to send headers that SHOULD
+not get trimmed. In STOMP 1.1, clients and servers MUST never trim or pad
+headers with spaces.</p>
+
+<h3 id = "Size_Limits">Size Limits</h3>
+
+<p>To prevent malicious clients from exploiting memory allocation in a
+server, servers MAY place maximum limits on:</p>
+
+<ul>
+<li>the number of frame headers allowed in a single frame</li>
+<li>the maximum length of header lines</li>
+<li>the maximum size of a frame body</li>
+</ul>
+
+<p>If these limits are exceeded the server SHOULD send the client an <code>ERROR</code>
+frame and disconnect the client.</p>
+
+<h3 id = "Repeated_Header_Entries">Repeated Header Entries</h3>
+
+<p>Since messaging systems can be organized in store and forward topologies,
+similar to SMTP, a message may traverse several messaging servers before
+reaching a consumer. The intermediate server MAY 'update' header values by
+either prepending headers to the message or modifying a header in-place in
+the message.</p>
+
+<p>If the client receives repeated frame header entries, only the first header
+entry SHOULD be used as the value of header entry. Subsequent values are only
+used to maintain a history of state changes of the header. For example, if the
+client receives:</p>
+
+<pre><code>MESSAGE
+foo:World
+foo:Hello
+
+^@</code></pre>
+
+<p>The value of the <code>foo</code> header is just <code>World</code>.</p>
+
+<h2 id = "Connecting">Connecting</h2>
+
+<p>A STOMP client initiates the stream or TCP connection to the server by sending
+the <code>CONNECT</code> frame:</p>
+
+<pre><code>CONNECT
+accept-version:1.1
+host:stomp.github.org
+
+^@</code></pre>
+
+<p>If the server accepts the connection attempt it will respond with a
+<code>CONNECTED</code> frame:</p>
+
+<pre><code>CONNECTED
+version:1.1
+
+^@</code></pre>
+
+<p>The sever can reject any connection attempt. The server SHOULD respond back
+with an <code>ERROR</code> frame listing why the connection was rejected and then close
+the connection. STOMP servers MUST support clients which rapidly connect and
+disconnect. This implies a server will likely only allow closed connections
+to linger for short time before the connection is reset. This means that a
+client may not receive the <code>ERROR</code> frame before the socket is reset.</p>
+
+<h3 id = "CONNECT_or_STOMP_Frame">CONNECT or STOMP Frame</h3>
+
+<p>STOMP servers SHOULD handle a <code>STOMP</code> frame in the same manner as a <code>CONNECT</code>
+frame. STOMP 1.1 clients SHOULD continue to use the <code>CONNECT</code> command to
+remain backward compatible with STOMP 1.0 servers.</p>
+
+<p>Clients that use the <code>STOMP</code> frame instead of the <code>CONNECT</code> frame will only
+be able to connect to STOMP 1.1 servers but the advantage is that a protocol
+sniffer/discriminator will be able to differentiate the STOMP connection from
+an HTTP connection.</p>
+
+<p>STOMP 1.1 clients MUST set the following headers:</p>
+
+<ul>
+<li><p><code>accept-version</code> : The versions of the STOMP protocol the client supports.
+See <a href="#protocol&#95;negotiation">Protocol Negotiation</a> for more details.</p></li>
+<li><p><code>host</code> : The name of a virtual host that the client wishes to connect to.
+It is recommended clients set this to the host name that the socket
+was established against, or to any name of their choosing. If this
+header does not match a known virtual host, servers supporting virtual
+hosting MAY select a default virtual host or reject the connection.</p></li>
+</ul>
+
+<p>STOMP 1.1 clients MAY set the following headers:</p>
+
+<ul>
+<li><p><code>login</code> : The user id used to authenticate against a secured STOMP server.</p></li>
+<li><p><code>passcode</code> : The password used to authenticate against a secured STOMP
+server.</p></li>
+</ul>
+
+<h3 id = "CONNECTED_Frame">CONNECTED Frame</h3>
+
+<p>STOMP 1.1 servers MUST set the following headers:</p>
+
+<ul>
+<li><code>version</code> : The version of the STOMP protocol the session will be using.
+See <a href="#protocol&#95;negotiation">Protocol Negotiation</a> for more details.</li>
+</ul>
+
+<p>STOMP 1.1 servers MAY set the following headers:</p>
+
+<ul>
+<li><p><code>session</code> : A session id that uniquely identifies the session.</p></li>
+<li><p><code>server</code> : A field that contains information about the STOMP server.
+The field MUST contain a server-name field and MAY be followed by optional
+comment feilds delimited by a space character.</p>
+
+<p>The server-name field consists of a name token followed by an optional version
+number token.</p>
+
+<p><code>server = name ["/" version] *(comment)</code></p>
+
+<p>Example:</p>
+
+<p><code>server:Apache/1.3.9</code></p></li>
+</ul>
+
+<h2 id = "Protocol_Negotiation">Protocol Negotiation</h2>
+
+<p>From STOMP 1.1 and onwards, the <code>CONNECT</code> frame MUST include the
+<code>accept-version</code> header. It SHOULD be set to a comma separated list of
+incrementing STOMP protocol versions that the client supports. If the
+<code>accept-version</code> header is missing, it means that the client only supports
+version 1.0 of the protocol.</p>
+
+<p>The protocol that will be used for the rest of the session will be the
+highest protocol version that both the client and server have in common.</p>
+
+<p>For example, if the client sends:</p>
+
+<pre><code>CONNECT
+accept-version:1.0,1.1,2.0
+host:stomp.github.org
+
+^@</code></pre>
+
+<p>The server will respond back with the highest version of the protocol that
+it has in common with the client:</p>
+
+<pre><code>CONNECTED
+version:1.1
+
+^@</code></pre>
+
+<p>If the client and server do not share any common protocol versions, then the
+sever SHOULD respond with an <code>ERROR</code> frame similar to:</p>
+
+<pre><code>ERROR
+version:1.2,2.1
+content-type:text/plain
+
+Supported protocol versions are 1.2 2.1^@</code></pre>
+
+<h2 id = "Once_Connected">Once Connected</h2>
+
+<p>A client MAY send a frame not in this list, but for such a frame a
+STOMP 1.1 server MAY respond with an <code>ERROR</code> frame.</p>
+
+<ul>
+<li><a href="#SEND"><code>SEND</code></a></li>
+<li><a href="#SUBSCRIBE"><code>SUBSCRIBE</code></a></li>
+<li><a href="#UNSUBSCRIBE"><code>UNSUBSCRIBE</code></a></li>
+<li><a href="#BEGIN"><code>BEGIN</code></a></li>
+<li><a href="#COMMIT"><code>COMMIT</code></a></li>
+<li><a href="#ABORT"><code>ABORT</code></a></li>
+<li><a href="#ACK"><code>ACK</code></a></li>
+<li><a href="#NACK"><code>NACK</code></a></li>
+<li><a href="#DISCONNECT"><code>DISCONNECT</code></a></li>
+</ul>
+
+<h2 id = "Client_Frames">Client Frames</h2>
+
+<h3 id = "SEND">SEND</h3>
+
+<p>The <code>SEND</code> frame sends a message to a destination in the messaging system. It
+has one REQUIRED header, <code>destination</code>, which indicates where to send the
+message. The body of the <code>SEND</code> frame is the message to be sent. For example:</p>
+
+<pre><code>SEND
+destination:/queue/a
+content-type:text/plain
+
+hello queue a
+^@</code></pre>
+
+<p>This sends a message to a destination named <code>/queue/a</code>. Note that STOMP treats
+this destination as an opaque string and no delivery semantics are assumed by
+the name of a destination. You should consult your STOMP server's
+documentation to find out how to construct a destination name which gives you
+the delivery semantics that your application needs.</p>
+
+<p>The reliability semantics of the message are also server specific and will
+depend on the destination value being used and the other message headers
+such as the <code>transaction</code> header or other server specific message headers.</p>
+
+<p><code>SEND</code> supports a <code>transaction</code> header which allows for transactional sends.</p>
+
+<p><code>SEND</code> frames SHOULD include a
+<a href="#Header&#95;content-length"><code>content-length</code></a> header and a
+<a href="#Header&#95;content-type"><code>content-type</code></a> header if a body is present.</p>
+
+<p>An application MAY add any arbitrary user defined headers to the <code>SEND</code> frame.
+User defined headers are typically used to allow consumers to filter
+messages based on the application defined headers using a selector
+on a <code>SUBSCRIBE</code> frame. The user defined headers MUST be passed through
+in the <code>MESSAGE</code> frame.</p>
+
+<p>If the sever cannot successfully process the <code>SEND</code> frame frame for any reason,
+the server MUST send the client an <code>ERROR</code> frame and disconnect the client.</p>
+
+<h3 id = "SUBSCRIBE">SUBSCRIBE</h3>
+
+<p>The <code>SUBSCRIBE</code> frame is used to register to listen to a given destination.
+Like the <code>SEND</code> frame, the <code>SUBSCRIBE</code> frame requires a <code>destination</code> header
+indicating the destination to which the client wants to subscribe. Any
+messages received on the subscribed destination will henceforth be delivered
+as <code>MESSAGE</code> frames from the server to the client. The <code>ack</code> header controls
+the message acknowledgement mode.</p>
+
+<p>Example:</p>
+
+<pre><code>SUBSCRIBE
+id:0
+destination:/queue/foo
+ack:client
+
+^@</code></pre>
+
+<p>If the sever cannot successfully create the subscription,
+the server MUST send the client an <code>ERROR</code> frame and disconnect the client.</p>
+
+<p>STOMP servers MAY support additional server specific headers to customize the
+delivery semantics of the subscription. Consult your server's documentation for
+details.</p>
+
+<h4 id = "SUBSCRIBE_id_Header">SUBSCRIBE id Header</h4>
+
+<p>An <code>id</code> header MUST be included in the frame to uniquely identify the subscription within the
+STOMP connection session. Since a single connection can have multiple open
+subscriptions with a server, the <code>id</code> header allows the client and server to
+relate subsequent <code>ACK</code>, <code>NACK</code> or <code>UNSUBSCRIBE</code> frames to the original
+subscription.</p>
+
+<h4 id = "SUBSCRIBE_ack_Header">SUBSCRIBE ack Header</h4>
+
+<p>The valid values for the <code>ack</code> header are <code>auto</code>, <code>client</code>, or
+<code>client-individual</code>. If the header is not set, it defaults to <code>auto</code>.</p>
+
+<p>When the the <code>ack</code> mode is <code>auto</code>, then the client does not need to send the
+server <code>ACK</code> frames for the messages it receives. The server will assume the
+client has received the message as soon as it sends it to the the client.
+This acknowledgment mode can cause messages being transmitted to the client
+to get dropped.</p>
+
+<p>When the the <code>ack</code> mode is <code>client</code>, then the client MUST send the server
+<code>ACK</code> frames for the messages it processes. If the connection fails before a
+client sends an <code>ACK</code> for the message the server will assume the message has
+not been processed and MAY redeliver the message to another client. The <code>ACK</code>
+frames sent by the client will be treated as a cumulative <code>ACK</code>. This means the <code>ACK</code> operates on the message specified in the <code>ACK</code> frame
+and all messages sent to the subscription before the <code>ACK</code>-ed message.</p>
+
+<p>When the the <code>ack</code> mode is <code>client-individual</code>, the ack mode operates just
+like the <code>client</code> ack mode except that the <code>ACK</code> or <code>NACK</code> frames sent by the
+client are not cumulative. This means that an <code>ACK</code> or <code>NACK</code> for a
+subsequent message MUST NOT cause a previous message to get acknowledged.</p>
+
+<h3 id = "UNSUBSCRIBE">UNSUBSCRIBE</h3>
+
+<p>The <code>UNSUBSCRIBE</code> frame is used to remove an existing subscription. Once the
+subscription is removed the STOMP connections will no longer receive messages
+from that destination. It requires that the <code>id</code> header matches the <code>id</code>
+value of previous <code>SUBSCRIBE</code> operation. Example:</p>
+
+<pre><code>UNSUBSCRIBE
+id:0
+
+^@</code></pre>
+
+<h3 id = "ACK">ACK</h3>
+
+<p><code>ACK</code> is used to acknowledge consumption of a message from a subscription
+using <code>client</code> or <code>client-individual</code> acknowledgment. Any messages received
+from such a subscription will not be considered to have been consumed until
+the message has been acknowledged via an <code>ACK</code> or a <code>NACK</code>.</p>
+
+<p><code>ACK</code> has two REQUIRED headers: <code>message-id</code>, which MUST contain a value
+matching the <code>message-id</code> for the <code>MESSAGE</code> being acknowledged and
+<code>subscription</code>, which MUST be set to match the value of the subscription's
+<code>id</code> header. Optionally, a <code>transaction</code> header MAY be specified, indicating
+that the message acknowledgment SHOULD be part of the named transaction.</p>
+
+<pre><code>ACK
+subscription:0
+message-id:007
+transaction:tx1
+
+^@</code></pre>
+
+<h3 id = "NACK">NACK</h3>
+
+<p><code>NACK</code> is the opposite of <code>ACK</code>. It is used to tell the server that the
+client did not consume the message. The server can then either send the
+message to a different client, discard it, or put it in a dead letter queue.
+The exact behavior is server specific.</p>
+
+<p><code>NACK</code> takes the same headers as <code>ACK</code>: <code>message-id</code> (mandatory),
+<code>subscription</code> (mandatory) and <code>transaction</code> (OPTIONAL).</p>
+
+<p><code>NACK</code> applies either to one single message (if the subscription's ack mode
+is <code>client-individual</code>) or to all messages sent before and not yet <code>ACK</code>'ed
+or <code>NACK</code>'ed.</p>
+
+<h3 id = "BEGIN">BEGIN</h3>
+
+<p><code>BEGIN</code> is used to start a transaction. Transactions in this case apply to
+sending and acknowledging - any messages sent or acknowledged during a
+transaction will be handled atomically based on the transaction.</p>
+
+<pre><code>BEGIN
+transaction:tx1
+
+^@</code></pre>
+
+<p>The <code>transaction</code> header is REQUIRED, and the transaction identifier will be
+used for <code>SEND</code>, <code>COMMIT</code>, <code>ABORT</code>, <code>ACK</code>, and <code>NACK</code> frames to bind them to
+the named transaction.</p>
+
+<p>Any started transactions which have not been committed will be implicitly
+aborted if the client sends a <code>DISCONNECT</code> frame or if the TCP connection
+fails for any reason.</p>
+
+<h3 id = "COMMIT">COMMIT</h3>
+
+<p><code>COMMIT</code> is used to commit a transaction in progress.</p>
+
+<pre><code>COMMIT
+transaction:tx1
+
+^@</code></pre>
+
+<p>The <code>transaction</code> header is REQUIRED and MUST specify the id of the transaction to
+commit&#33;</p>
+
+<h3 id = "ABORT">ABORT</h3>
+
+<p><code>ABORT</code> is used to roll back a transaction in progress.</p>
+
+<pre><code>ABORT
+transaction:tx1
+
+^@</code></pre>
+
+<p>The <code>transaction</code> header is REQUIRED and MUST specify the id of the transaction to
+abort&#33;</p>
+
+<h3 id = "DISCONNECT">DISCONNECT</h3>
+
+<p>A client can disconnect from the server at anytime by closing the socket but
+there is no guarantee that the previously sent frames have been received by
+the server. To do a graceful shutdown, where the client is assured that all
+previous frames have been received by the server, the client SHOULD:</p>
+
+<ol>
+<li><p>send a <code>DISCONNECT</code> frame with a <code>receipt</code> header set. Example:</p>
+
+<pre><code>DISCONNECT
+receipt:77
+^@</code></pre></li>
+<li><p>wait for the <code>RECEIPT</code> frame response to the <code>DISCONNECT</code>. Example:</p>
+
+<pre><code>RECEIPT
+receipt-id:77
+^@</code></pre></li>
+<li><p>close the socket.</p></li>
+</ol>
+
+<p>Clients MUST NOT send any more frames after the <code>DISCONNECT</code> frame is sent.</p>
+
+<h2 id = "Standard_Headers">Standard Headers</h2>
+
+<p>Some headers MAY be used, and have special meaning, with most frames.</p>
+
+<h3 id = "Header_content-length">Header content-length</h3>
+
+<p>The <code>SEND</code>, <code>MESSAGE</code> and <code>ERROR</code> frames SHOULD include a <code>content-length</code>
+header if a frame body is present. If a frame's body contains NULL octets, the
+frame MUST include a <code>content-length</code> header. The header is a byte count for
+the length of the message body. If a <code>content-length</code> header is included, this
+number of bytes MUST 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.</p>
+
+<h3 id = "Header_content-type">Header content-type</h3>
+
+<p>The <code>SEND</code>, <code>MESSAGE</code> and <code>ERROR</code> frames SHOULD include a <code>content-type</code>
+header if a frame body is present. It SHOULD be set to a mime type which
+describes the format of the body to help the receiver of the frame interpret
+it's contents. If the <code>content-type</code> header is not set, the receiver SHOULD
+consider the body to be a binary blob.</p>
+
+<p>The implied text encoding for mime types starting with <code>text/</code> is UTF-8. If
+you are using a text based mime type with a different encoding then you
+SHOULD append <code>;charset=&lt;encoding&gt;</code> to the mime type. For example,
+<code>text/html;charset=utf-16</code> SHOULD be used if your sending an html body in
+UTF-16 encoding. The <code>;charset=&lt;encoding&gt;</code> SHOULD also get appended to any
+non <code>text/</code> mime types which can be interpreted as text. A good example of
+this would be a UTF-8 encoded XML. It's <code>content-type</code> SHOULD get set to
+<code>application/xml;charset=utf-8</code></p>
+
+<p>All STOMP clients and servers MUST support UTF-8 encoding and decoding. Therefore,
+for maximum interoperability in a heterogeneous computing environment, it is
+RECOMMENDED that text based content be encoded with UTF-8.</p>
+
+<h3 id = "Header_receipt">Header receipt</h3>
+
+<p>Any client frame other than <code>CONNECT</code> MAY specify a <code>receipt</code>
+header with an arbitrary value. This will cause the server to acknowledge
+receipt of the frame with a <code>RECEIPT</code> frame which contains the value of this
+header as the value of the <code>receipt-id</code> header in the <code>RECEIPT</code> frame.</p>
+
+<pre><code>SEND
+destination:/queue/a
+receipt:message-12345
+
+hello queue a^@</code></pre>
+
+<h2 id = "Server_Frames">Server Frames</h2>
+
+<p>The server will, on occasion, send frames to the client (in addition to the
+initial <code>CONNECTED</code> frame). These frames MAY be one of:</p>
+
+<ul>
+<li><a href="#MESSAGE"><code>MESSAGE</code></a></li>
+<li><a href="#RECEIPT"><code>RECEIPT</code></a></li>
+<li><a href="#ERROR"><code>ERROR</code></a></li>
+</ul>
+
+<h3 id = "MESSAGE">MESSAGE</h3>
+
+<p><code>MESSAGE</code> frames are used to convey messages from subscriptions to the
+client. The <code>MESSAGE</code> frame will include a <code>destination</code> header indicating
+the destination the message was sent to. It will also contain a <code>message-id</code>
+header with a unique identifier for that message. The <code>subscription</code> header
+will be set to match the <code>id</code> header of the subscription that is receiving
+the message. The frame body contains the contents of the message:</p>
+
+<pre><code>MESSAGE
+subscription:0
+message-id:007
+destination:/queue/a
+content-type:text/plain
+
+hello queue a^@</code></pre>
+
+<p><code>MESSAGE</code> frames SHOULD include a
+<a href="#Header&#95;content-length"><code>content-length</code></a> header and a
+<a href="#Header&#95;content-type"><code>content-type</code></a> header if a body is present.</p>
+
+<p><code>MESSAGE</code> frames will also include all user defined headers that were present
+when the message was sent to the destination in addition to the server
+specific headers that MAY get added to the frame. Consult your server's
+documentation to find out the server specific headers that it adds to
+messages.</p>
+
+<h3 id = "RECEIPT">RECEIPT</h3>
+
+<p>A <code>RECEIPT</code> frame is sent from the server to the client once a server has has
+successfully processed a client frame that requests a receipt. A <code>RECEIPT</code>
+frame will include the header <code>receipt-id</code>, where the value is the value of
+the <code>receipt</code> header in the frame which this is a receipt for.</p>
+
+<pre><code>RECEIPT
+receipt-id:message-12345
+
+^@</code></pre>
+
+<p>The receipt body will be empty.</p>
+
+<h3 id = "ERROR">ERROR</h3>
+
+<p>The server MAY send <code>ERROR</code> frames if something goes wrong. The error frame
+SHOULD contain a <code>message</code> header with a short description of the error, and
+the body MAY contain more detailed information (or MAY be empty).</p>
+
+<pre><code>ERROR
+receipt-id:message-12345
+content-type:text/plain
+content-length:171
+message: malformed frame received
+
+The message:
+-----
+MESSAGE
+destined:/queue/a
+receipt:message-12345
+
+
+Hello queue a!
+-----
+Did not contain a destination header, which is REQUIRED
+for message propagation.
+^@</code></pre>
+
+<p>If the error is related to specific frame sent from the client, the server
+SHOULD add additional headers to help identify the original frame that caused
+the error. For example, if the frame included a receipt header, the <code>ERROR</code>
+frame SHOULD set the <code>receipt-id</code> header to match the value of the <code>receipt</code>
+header of the frame which the error is related to.</p>
+
+<p><code>ERROR</code> frames SHOULD include a
+<a href="#Header&#95;content-length"><code>content-length</code></a> header and a
+<a href="#Header&#95;content-type"><code>content-type</code></a> header if a body is present.</p>
+
+<h2 id = "Heart-beating">Heart-beating</h2>
+
+<p>Heart-beating can optionally be used to test the healthiness of the
+underlying TCP connection and to make sure that the remote end is alive and
+kicking.</p>
+
+<p>In order to enable heart-beating, each party has to declare what it can do
+and what it would like the other party to do. This happens at the very
+beginning of the STOMP session, by adding a <code>heart-beat</code> header to the
+<code>CONNECT</code> and <code>CONNECTED</code> frames.</p>
+
+<p>When used, the <code>heart-beat</code> header MUST contain two positive integers
+separated by a comma.</p>
+
+<p>The first number represents what the sender of the frame can do (outgoing
+heart-beats):</p>
+
+<ul>
+<li><p>0 means it cannot send heart-beats</p></li>
+<li><p>otherwise it is the smallest number of milliseconds between heart-beats
+that it can guarantee</p></li>
+</ul>
+
+<p>The second number represents what the sender of the frame would like
+to get (incoming heart-beats):</p>
+
+<ul>
+<li><p>0 means it does not want to receive heart-beats</p></li>
+<li><p>otherwise it is the desired number of milliseconds between heart-beats</p></li>
+</ul>
+
+<p>The <code>heart-beat</code> header is OPTIONAL. A missing <code>heart-beat</code> header MUST be
+treated the same way as a &ldquo;heart-beat:0,0&rdquo; header, that is: the party cannot
+send and does not want to receive heart-beats.</p>
+
+<p>The <code>heart-beat</code> header provides enough information so that each party can
+find out if heart-beats can be used, in which direction, and with which
+frequency.</p>
+
+<p>More formally, the initial frames look like:</p>
+
+<pre><code>CONNECT
+heart-beat:&lt;cx&gt;,&lt;cy&gt;
+
+CONNECTED:
+heart-beat:&lt;sx&gt;,&lt;sy&gt;</code></pre>
+
+<p>For heart-beats from the client to the server:</p>
+
+<ul>
+<li><p>if <code>&lt;cx&gt;</code> is 0 (the client cannot send heart-beats) or <code>&lt;sy&gt;</code> is 0 (the
+server does not want to receive heart-beats) then there will be none</p></li>
+<li><p>otherwise, there will be heart-beats every MAX(<code>&lt;cx&gt;</code>,<code>&lt;sy&gt;</code>) milliseconds</p></li>
+</ul>
+
+<p>In the other direction, <code>&lt;sx&gt;</code> and <code>&lt;cy&gt;</code> are used the same way.</p>
+
+<p>Regarding the heart-beats themselves, any new data received over the network
+connection is an indication that the remote end is alive. In a given
+direction, if heart-beats are expected every <code>&lt;n&gt;</code> milliseconds:</p>
+
+<ul>
+<li><p>the sender MUST send new data over the network connection at least every
+<code>&lt;n&gt;</code> milliseconds</p></li>
+<li><p>if the sender has no real STOMP frame to send, it MUST send a single
+newline byte (0x0A)</p></li>
+<li><p>if, inside a time window of at least <code>&lt;n&gt;</code> milliseconds, the receiver did
+not receive any new data, it CAN consider the connection as dead</p></li>
+<li><p>because of timing inaccuracies, the receiver SHOULD be tolerant and take
+into account an error margin</p></li>
+</ul>
+
+<h2 id = "Augmented_BNF">Augmented BNF</h2>
+
+<p>A STOMP session can be more formally described using the
+Backus-Naur Form (BNF) grammar used in HTTP/1.1
+<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.1">rfc2616</a>.</p>
+
+<pre><code>LF = &lt;US-ASCII new line (line feed) (octet 10)&gt;
+OCTET = &lt;any 8-bit sequence of data&gt;
+NULL = &lt;octet 0&gt;
+
+frame-stream = 1*frame
+
+frame = command LF
+ *( header LF )
+ LF
+ *OCTET
+ NULL
+ *( LF )
+
+command = client-command | server-command
+
+client-command = "SEND"
+ | "SUBSCRIBE"
+ | "UNSUBSCRIBE"
+ | "BEGIN"
+ | "COMMIT"
+ | "ABORT"
+ | "ACK"
+ | "NACK"
+ | "DISCONNECT"
+ | "CONNECT"
+ | "STOMP"
+
+server-command = "CONNECTED"
+ | "MESSAGE"
+ | "RECEIPT"
+ | "ERROR"
+
+header = header-name ":" header-value
+header-name = 1*&lt;any OCTET except LF or ":"&gt;
+header-value = *&lt;any OCTET except LF or ":"&gt;</code></pre>
+
+<h2 id = "License">License</h2>
+
+<p>This specification is licensed under the
+<a href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution v2.5</a>
+license.</p>
+ <div></div>
+ </div>
+ </div>
+ </body>
+</html>

0 comments on commit f0f6cbe

Please sign in to comment.