forked from stomp/stomp.github.com
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstomp-specification-1.2.html
1035 lines (799 loc) · 42.2 KB
/
stomp-specification-1.2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!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/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.2.html">1.2</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_2">STOMP Protocol Specification, Version 1.2</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="#Body">Body</a></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="#Repeated_Header_Entries">Repeated Header Entries</a></li>
<li><a href="#Size_Limits">Size Limits</a></li>
<li><a href="#Connection_Lingering">Connection Lingering</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>
<li><a href="#Protocol_Negotiation">Protocol Negotiation</a></li>
<li><a href="#Heart-beating">Heart-beating</a></li>
</ul></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="#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="#Frames_and_Headers">Frames and Headers</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.2
protocol and is an update to <a href="stomp-specification-1.1.html">STOMP 1.1</a>.</p>
<p>Please send feedback to the [email protected] 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 “message
exchange”, 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.2 is mostly backwards compatible with STOMP 1.1. There are only two
incompatible changes:</p>
<ul>
<li><p>it is now possible to end frame lines with carriage return plus line feed
instead of only line feed</p></li>
<li><p>message acknowledgment has been simplified and now uses a dedicated header</p></li>
</ul>
<p>Apart from these, STOMP 1.2 introduces no new features but focuses on clarifying
some areas of the specification such as:</p>
<ul>
<li><p>repeated frame header entries</p></li>
<li><p>use of the <code>content-length</code> and <code>content-type</code> headers</p></li>
<li><p>required support of the <code>STOMP</code> frame by servers</p></li>
<li><p>connection lingering</p></li>
<li><p>scope and uniqueness of subscription and transaction identifiers</p></li>
<li><p>meaning of the <code>RECEIPT</code> frame with regard to previous frames</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.2. 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 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”,
“SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be
interpreted as described in <a href="http://tools.ietf.org/html/rfc2119">RFC 2119</a>.</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 an end-of-line (EOL),
which consists of an OPTIONAL carriage return (octet 13) followed by a
REQUIRED line feed (octet 10). Following the command are zero or more header
entries in <code><key>:<value></code> format. Each header entry is terminated by an EOL.
A blank line (i.e. an extra EOL) indicates the end of the headers and the
beginning of the body. The body is then followed by the NULL octet. The
examples in this document will use <code>^@</code>, control-@ in ASCII, to represent
the NULL octet. The NULL octet can be optionally followed by multiple EOLs.
For more details, on how to parse STOMP frames, see the
<a href="#Augmented_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 carriage return, line feed or colon
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 carriage return, line feed or colon octets in order to remain backward
compatible with STOMP 1.0.</p>
<p>C style string literal escapes are used to encode any carriage return, line feed
or colon that are found within the UTF-8 encoded headers. When decoding frame headers,
the following transformations MUST be applied:</p>
<ul>
<li><code>\r</code> (octet 92 and 114) translates to carriage return (octet 13)</li>
<li><code>\n</code> (octet 92 and 110) translates to line feed (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>\t</code> (octet 92 and 116) MUST be treated as
a fatal protocol error. Conversely when encoding frame headers, the reverse
transformation MUST be applied.</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.2, clients and servers MUST never trim or pad
headers with spaces.</p>
<h3 id = "Body">Body</h3>
<p>Only the <code>SEND</code>, <code>MESSAGE</code>, and <code>ERROR</code> frames MAY have a body. All other
frames MUST NOT have a body.</p>
<h3 id = "Standard_Headers">Standard Headers</h3>
<p>Some headers MAY be used, and have special meaning, with most frames.</p>
<h4 id = "Header_content-length">Header content-length</h4>
<p>All frames MAY include a <code>content-length</code> header. This header is an octet
count for the length of the message body. If a <code>content-length</code> header is
included, this number of octets MUST be read, regardless of whether or not
there are NULL octets in the body. The frame still needs to be terminated
with a NULL octet.</p>
<p>If a frame body is present, the <code>SEND</code>, <code>MESSAGE</code> and <code>ERROR</code> frames SHOULD
include a <code>content-length</code> header to ease frame parsing. If the frame body
contains NULL octets, the frame MUST include a <code>content-length</code> header.</p>
<h4 id = "Header_content-type">Header content-type</h4>
<p>If a frame body is present, the <code>SEND</code>, <code>MESSAGE</code> and <code>ERROR</code> frames SHOULD
include a <code>content-type</code> header to help the receiver of the frame interpret
its body. If the <code>content-type</code> header is set, its value MUST be a MIME type
which describes the format of the body. Otherwise, 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=<encoding></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=<encoding></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. Its <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>
<h4 id = "Header_receipt">Header receipt</h4>
<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 the processing of
the client frame with a <code>RECEIPT</code> frame (see the <a href="#RECEIPT">RECEIPT</a> frame
for more details).</p>
<pre><code>SEND
destination:/queue/a
receipt:message-12345
hello queue a^@</code></pre>
<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. A STOMP server MAY 'update' header values by either
prepending headers to the message or modifying a header in-place in the
message.</p>
<p>If a client or a server 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
and MAY be ignored.</p>
<p>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>
<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 then close the connection.</p>
<h3 id = "Connection_Lingering">Connection Lingering</h3>
<p>STOMP servers must be able to support clients which rapidly connect and
disconnect.</p>
<p>This implies a server will likely only allow closed connections to linger
for short time before the connection is reset.</p>
<p>As a consequence, a client may not receive the last frame sent by the server
(for instance an <code>ERROR</code> frame or the <code>RECEIPT</code> frame in reply to a
<code>DISCONNECT</code> frame) before the socket is reset.</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.2
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.2
^@</code></pre>
<p>The server can reject any connection attempt. The server SHOULD respond back
with an <code>ERROR</code> frame explaining why the connection was rejected and then close
the connection.</p>
<h3 id = "CONNECT_or_STOMP_Frame">CONNECT or STOMP Frame</h3>
<p>STOMP servers MUST handle a <code>STOMP</code> frame in the same manner as a <code>CONNECT</code>
frame. STOMP 1.2 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.2 servers (as well as some 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.2 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_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.2 clients MAY set the following headers:</p>
<ul>
<li><p><code>login</code> : The user identifier 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>
<li><p><code>heart-beat</code> : The <a href="#Heart-beating">Heart-beating</a> settings.</p></li>
</ul>
<h3 id = "CONNECTED_Frame">CONNECTED Frame</h3>
<p>STOMP 1.2 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_Negotiation">Protocol Negotiation</a> for more details.</li>
</ul>
<p>STOMP 1.2 servers MAY set the following headers:</p>
<ul>
<li><p><code>heart-beat</code> : The <a href="#Heart-beating">Heart-beating</a> settings.</p></li>
<li><p><code>session</code> : A session identifier 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 fields 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>
<h3 id = "Protocol_Negotiation">Protocol Negotiation</h3>
<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 MUST respond with an <code>ERROR</code> frame similar to the following and then
close the connection:</p>
<pre><code>ERROR
version:1.2,2.1
content-type:text/plain
Supported protocol versions are 1.2 2.1^@</code></pre>
<h3 id = "Heart-beating">Heart-beating</h3>
<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 “heart-beat:0,0” 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:<cx>,<cy>
CONNECTED:
heart-beat:<sx>,<sy></code></pre>
<p>For heart-beats from the client to the server:</p>
<ul>
<li><p>if <code><cx></code> is 0 (the client cannot send heart-beats) or <code><sy></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><cx></code>,<code><sy></code>) milliseconds</p></li>
</ul>
<p>In the other direction, <code><sx></code> and <code><cy></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><n></code> milliseconds:</p>
<ul>
<li><p>the sender MUST send new data over the network connection at least every
<code><n></code> milliseconds</p></li>
<li><p>if the sender has no real STOMP frame to send, it MUST send an end-of-line (EOL)</p></li>
<li><p>if, inside a time window of at least <code><n></code> milliseconds, the receiver did
not receive any new data, it MAY 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 = "Client_Frames">Client Frames</h2>
<p>A client MAY send a frame not in this list, but for such a frame a STOMP 1.2
server MAY respond with an <code>ERROR</code> frame and then close the connection.</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>
<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_content-length"><code>content-length</code></a> header and a
<a href="#Header_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 for any reason,
the server MUST send the client an <code>ERROR</code> frame and then close the connection.</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 acknowledgment 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 then close the connection.</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>Since a single connection can have multiple open subscriptions with a
server, an <code>id</code> header MUST be included in the frame to uniquely identify
the subscription. The <code>id</code> header allows the client and server to relate
subsequent <code>MESSAGE</code> or <code>UNSUBSCRIBE</code> frames to the original subscription.</p>
<p>Within the same connection, different subscriptions MUST use different
subscription identifiers.</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 <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 client.
This acknowledgment mode can cause messages being transmitted to the client
to get dropped.</p>
<p>When 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> frame 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 acknowledgment.
This means the acknowledgment 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>In case the client did not process some messages, it SHOULD send <code>NACK</code> frames
to tell the server it did not consume these messages.</p>
<p>When the <code>ack</code> mode is <code>client-individual</code>, the acknowledgment operates just
like the <code>client</code> acknowledgment 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>
frame 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 subscription.</p>
<p>Since a single connection can have multiple open subscriptions with a
server, an <code>id</code> header MUST be included in the frame to uniquely identify
the subscription to remove. This header MUST match the subscription
identifier of an existing subscription.</p>
<p>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>.</p>
<p>The <code>ACK</code> frame MUST include an <code>id</code> header matching the <code>ack</code> header of the
<code>MESSAGE</code> being acknowledged. 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
id:12345
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>id</code> (REQUIRED) and <code>transaction</code>
(OPTIONAL).</p>
<p><code>NACK</code> applies either to one single message (if the subscription's <code>ack</code>
mode is <code>client-individual</code>) or to all messages sent before and not yet
<code>ACK</code>'ed or <code>NACK</code>'ed (if the subscription's <code>ack</code> mode is <code>client</code>).</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 processed 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. Within the same connection, different transactions MUST
use different transaction identifiers.</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 identifier of the
transaction to commit.</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 identifier of the
transaction to abort.</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>Note that, if the server closes its end of the socket too quickly, the
client might never receive the expected <code>RECEIPT</code> frame. See the
<a href="#Connection_Lingering">Connection Lingering</a> section for more information.</p>
<p>Clients MUST NOT send any more frames after the <code>DISCONNECT</code> frame is sent.</p>
<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.</p>
<p>The <code>MESSAGE</code> frame MUST include a <code>destination</code> header indicating the
destination the message was sent to. If the message has been sent using
STOMP, this <code>destination</code> header SHOULD be identical to the one used in the
corresponding <code>SEND</code> frame.</p>
<p>The <code>MESSAGE</code> frame MUST also contain a <code>message-id</code> header with a unique
identifier for that message and a <code>subscription</code> header matching the
identifier of the subscription that is receiving the message.</p>
<p>If the message is received from a subscription that requires explicit
acknowledgment (either <code>client</code> or <code>client-individual</code> mode) then the
<code>MESSAGE</code> frame MUST also contain an <code>ack</code> header with an arbitrary
value. This header will be used to relate the message to a subsequent
<code>ACK</code> or <code>NACK</code> frame.</p>
<p>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_content-length"><code>content-length</code></a> header and a
<a href="#Header_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
successfully processed a client frame that requests a receipt. A <code>RECEIPT</code>
frame MUST 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>A <code>RECEIPT</code> frame is an acknowledgment that the corresponding client frame
has been <em>processed</em> by the server. Since STOMP is stream based, the receipt
is also a cumulative acknowledgment that all the previous frames have been
<em>received</em> by the server. However, these previous frames may not yet be
fully <em>processed</em>. If the client disconnects, previously received frames
SHOULD continue to get processed by the server.</p>
<h3 id = "ERROR">ERROR</h3>
<p>The server MAY send <code>ERROR</code> frames if something goes wrong. In this case, it
MUST then close the connection just after sending the <code>ERROR</code> frame. See the
next section about <a href="#Connection_Lingering">connection lingering</a>.</p>
<p>The <code>ERROR</code> 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 a 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_content-length"><code>content-length</code></a> header and a
<a href="#Header_content-type"><code>content-type</code></a> header if a body is present.</p>
<h2 id = "Frames_and_Headers">Frames and Headers</h2>
<p>In addition to the <a href="#Standard_Headers">standard headers</a> described above
(<code>content-length</code>, <code>content-type</code> and <code>receipt</code>), here are all the headers
defined in this specification that each frame MUST or MAY use:</p>
<ul>
<li><code>CONNECT</code> or <code>STOMP</code>
<ul>
<li>REQUIRED: <code>accept-version</code>, <code>host</code></li>
<li>OPTIONAL: <code>login</code>, <code>passcode</code>, <code>heart-beat</code></li>
</ul></li>
<li><code>CONNECTED</code>
<ul>
<li>REQUIRED: <code>version</code></li>
<li>OPTIONAL: <code>session</code>, <code>server</code>, <code>heart-beat</code></li>
</ul></li>
<li><code>SEND</code>
<ul>
<li>REQUIRED: <code>destination</code></li>
<li>OPTIONAL: <code>transaction</code></li>
</ul></li>
<li><code>SUBSCRIBE</code>
<ul>
<li>REQUIRED: <code>destination</code>, <code>id</code></li>
<li>OPTIONAL: <code>ack</code></li>
</ul></li>
<li><code>UNSUBSCRIBE</code>
<ul>
<li>REQUIRED: <code>id</code></li>
<li>OPTIONAL: none</li>
</ul></li>
<li><code>ACK</code> or <code>NACK</code>
<ul>
<li>REQUIRED: <code>id</code></li>
<li>OPTIONAL: <code>transaction</code></li>
</ul></li>
<li><code>BEGIN</code> or <code>COMMIT</code> or <code>ABORT</code>
<ul>
<li>REQUIRED: <code>transaction</code></li>
<li>OPTIONAL: none</li>
</ul></li>
<li><code>DISCONNECT</code>
<ul>
<li>REQUIRED: none</li>
<li>OPTIONAL: <code>receipt</code></li>
</ul></li>
<li><code>MESSAGE</code>
<ul>
<li>REQUIRED: <code>destination</code>, <code>message-id</code>, <code>subscription</code></li>
<li>OPTIONAL: <code>ack</code></li>
</ul></li>
<li><code>RECEIPT</code>
<ul>
<li>REQUIRED: <code>receipt-id</code></li>
<li>OPTIONAL: none</li>
</ul></li>
<li><code>ERROR</code>
<ul>
<li>REQUIRED: none</li>
<li>OPTIONAL: <code>message</code></li>
</ul></li>
</ul>
<p>In addition, the <code>SEND</code> and <code>MESSAGE</code> frames MAY include arbitrary user
defined headers that SHOULD be considered as being part of the carried
message. Also, the <code>ERROR</code> frame SHOULD include additional headers to help
identify the original frame that caused the error.</p>
<p>Finally, STOMP servers MAY use additional headers to give access to features
like persistency or expiration. Consult your server's documentation for
details.</p>
<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://tools.ietf.org/html/rfc2616#section-2.1">RFC 2616</a>.</p>
<pre><code>NULL = <US-ASCII null (octet 0)>
LF = <US-ASCII line feed (aka newline) (octet 10)>
CR = <US-ASCII carriage return (octet 13)>
EOL = [CR] LF
OCTET = <any 8-bit sequence of data>
frame-stream = 1*frame
frame = command EOL
*( header EOL )
EOL
*OCTET
NULL