STOPM は中継サーバを介してクライアント間での非同期メッセージパッシング用に設計されたシンプルで相互運用可能なプロトコルです。 それらのクライアントとサーバ間で渡されるテキストベースメッセージのワイヤーフォーマットを定義します。
STOMP は既に何年かのアクティブな利用実績があり多くのメッセージブローカーやクライアントライブラリによってサポートされています。 この仕様は STOMP 1.2 プロトコルを定義し STOMP 1.1 を更新します。
フィードバックはメーリングリスト [email protected] へ送信して下さい。
STOMP は Ruby, Python, Perl などのようなスクリプト言語からエンタープライズメッセージブローカーと接続する必要性から生まれました。 これらの環境では一般的に「確実に単一のメッセージと切断を送信する」または「指定した送信先のすべてのメッセージを消費する」ように 実施される論理的に簡単な操作となります。
これは AMQP のような他のオープンメッセージングプロトコルや、OpenWire のような JMS ブローカーで使用されている特定のワイヤー プロトコル実装の代替です。これらの違いは一般的に使用されるメッセージング操作の小さなサブセットをカバーするのではなく、総合的な メッセージング API を提供していることです。
最新の STOMP が提供しているワイヤーレベルの機能面では、これらのプロトコルの簡単なユースケース以上に使用することができる プロトコルに成熟しているが、それでもシンプルさと相互運用性のコア設計の原則を維持しています。
STOMP は HTTP をモデルとしたフレームによるフレームベースのプロトコルです。フレームはコマンドとオプションヘッダ、オプションの ボディで構成されています。STOMP はテキストベースですがバイナリメッセージの転送も可能です。STOMP のデフォルトのエンコーディングは UTF-8 ですがメッセージ本体の代替エンコーディングの指定をサポートしています。
STOMP サーバはメッセージを送信可能な送信先の集合として概念化されています。STOMP プロトコルは宛先を非空白文字列として扱い、 それらの構文はサーバ実装に固有です。さらに STOMP は宛先の配信セマンティクスがどうあるべきかを定義していません。目的地の 配信または「メッセージ交換」セマンティクスは宛先となるサーバからサーバ、さらには目的地から目的地で変化させることができます。 これはサーバが STOMP でサポートできるセマンティクスで創造的にできるようにします。
STOMP クライアントは 2 つのモデルを (おそらく同時に) 動作することが出来るユーザエージェントです:
- Producer として、
SEND
フレームを使用してサーバ上の宛先にメッセージを送信する。 - Consumer として、特定の宛先に
SUBSCRIBE
フレームを送信し、MESSAGE
フレームとしてサーバからメッセージを受信する。
STOMP 1.2は STOMP 1.1 とほぼ下位互換性があります。 2つだけ互換性のない変更があります:
- LF のみでなく CR LF でもフレーム行を終了することが可能になりました。
- メッセージの確認応答 (acknowledgment) が簡素化され専用のヘッダを使用します。
これら以外に STOMP 1.2 では新機能が導入されていませんが、仕様における以下の領域の明確化に重点を置いています:
- 重複するフレームヘッダのエントリ
content-length
とcontent-type
ヘッダの使用- サーバによる
STOMP
フレームのサポートの必須 - 接続の長引き (lingering)
- 購読およびトランザクション識別子の範囲とユニーク性
- 直前のフレームに関する
RECEIPT
フレームの意味
STOMP は下層に (TCP のような) 信頼できる双方向ストリーミングネットワークプロトコルを前提としたフレームベースのプロトコルです。 クライアントとサーバはストリームを介して送信される STOMP フレームを使用して通信します。 フレームの構造は以下のようになります。
COMMAND
header1:value1
header2:value2
Body^@
フレームは 必須の* LF (オクテット10) に続く 任意の CR (オクテット13) で構成された行末 (EOL) で終了するコマンド文字列から
開始します。コマンドに続き <key>:<value>
形式の 0 個以上のヘッダエントリが存在します。それぞれのヘッダエントリは EOL で終了します。
ブランク行 (つまり余分な EOL) はヘッダの終わりとボディの開始を表しています。ボディは NULL オクテットが続いています。このドキュメントの
例では NULL オクテットを表すのに ASCII で ^@
、control-@ を使用します。NULL オクテットは必要に応じて複数の EOL を続けることが出来ます。
STOMP フレームを解析する方法の詳細についてはこのドキュメントの Augmented BNF を参照して下さい。
このドキュメントで参照している全てのコマンドとヘッダ名は大文字と小文字を区別します。
STOMP クライアントは CONNECT
フレームをサーバへ送信することによりストリームまたは TCP 接続を開始します:
CONNECT
accept-version:1.2
host:stomp.github.org
^@
サーバが接続の試行を受け入れる場合は CONNECTED
フレームで応答します:
CONNECTED
version:1.2
^@
サーバーは接続の試行を拒否することができます。サーバーは接続が拒否された理由を説明する ERROR
フレームで応答を返し接続を閉じる
必要があります。
STOMP サーバは CONNECT
フレームと同様に STOMP
フレームを処理しなければならない。STOPM 1.2 クライアントは STOMP 1.0
サーバとの下位互換性を維持するために CONNECT
コマンドを使用すべきである。
CONNECT
フレームの代わりに STOMP
フレームを使うクライアントは STOMP 1.2 サーバにのみ接続することができるが (STOMP 1.1
サーバと同様に)、プロトコルスニファや弁別装置で HTTP 接続の中から STOMP 接続を区別することができる利点があります。
STOMP 1.2 クライアントは以下のヘッダを設定しなければならない。
accept-version
: クライアントがサポートする STOMP プロトコルバージョン。詳細は Protocol Negotiation を参照。host
: クライアントが接続しようとしている仮想ホストの名前。クライアントはソケットが確立されたホスト名、またはそれらが選択した任意の名前に設定することを推奨します。このヘッダが既知の仮想ホストと一致しない場合、仮想ホスティングをサポートするサーバはデフォルトの仮想ホストを選択するか、接続を拒否することができます。
STOMP 1.2 クライアントは以下のヘッダを設定することができます。
login
: セキュアな STOMP サーバに対して認証するために使用するユーザID。passcode
: セキュアな STOMP サーバに対して認証するために使用するパスワード。heart-beat
: Heart-beating 設定。
SEND
フレームはメッセージングシステム内の宛先にメッセージを送信します。
メッセージを送信する宛先となる 1 つの必須ヘッダ destination
を持ちます。
SEND
フレームのボディは送信するメッセージです。例えば:
SEND
destination:/queue/a
content-type:text/plain
hello queue a
^@
これは /queue/a
という名の宛先にメッセージを送信します。
STOMP は宛先を非空白文字列として扱い、宛先の名前に対してどのような配信セマンティクスも想定されていないことに注意して下さい。
あなたのアプリケーションが必要とする配信セマンティクスを与える宛先名を構築する方法を見つけるために、あなたの STOMP サーバの
ドキュメントを参照して下さい。
メッセージの信頼性セマンティクスもサーバ固有のものです。使用されている宛先値や transaction
ヘッダ、その他のサーバ固有の
メッセージヘッダのような他のメッセージヘッダに依存するでしょう。
SEND
はトランザクションでの送信を可能にする transaction
ヘッダをサポートしています。
SEND
フレームはもしボディが与えられるなら content-length
ヘッダと content-type
ヘッダを含むべきです。
アプリケーションは SEND
フレームに任意のユーザ定義ヘッダを追加することができます。ユーザ定義ヘッダは一般的に Consumer が
SUBSCRIBE
フレーム上のセレクタを使用して、アプリケーション定義のヘッダに基づいてメッセージをフィルタリングできるようにする
目的で使用されます。ユーザ定義ヘッダは MESSAGE
フレームにパススルーされなければいけません。
サーバが何らかの理由で SEND
フレームを処理できない場合、サーバはクライアントに ERROR
フレームを送信し接続を閉じ
なければいけません。
SUBSCRIBE
フレームは与えられた宛先の購読を開始するために使用されます。
SEND
フレームと同様に、SUBSCRIBE
フレームはクライアントが購読を希望している宛先を示す destination
ヘッダを必要とします。
購読している宛先が受信した全てのメッセージはその後にサーバからクライアントへ MESSAGE
フレームとして配信されます。
ack
ヘッダはメッセージの確認応答モードを制御します。
SUBSCRIBE
id:0
destination:/queue/foo
ack:client
^@
サーバが正常に購読を行えない場合、クライアントに ERROR
フレームを送信し接続を閉じなければならない。
STOMP サーバは購読の配信セマンティクスをカスタマイズするために追加のサーバ固有ヘッダをサポートすることができます。 詳細はあなたのサーバのドキュメントを参照して下さい。
単一の接続上で複数の購読をオープンすることができるため、購読を識別するために一意の id
ヘッダがフレームに含まれなければいけません。
id
ヘッダはクライアントとサーバがオリジナルの購読に後続の MESSAGE
または UNSUBSCRIBE
フレームを関連付けできるようにします。
同じ接続内では異なる購読は異なる購読識別子を使用しなければいけません。
ack
ヘッダの有効な値は auto
、client
、client-individual
です。このヘッダが設定されていない場合 auto
がデフォルトとして使用されます。
ack
モードが auto
の場合、クライアントはクライアントは受信したメッセージに対してサーバに ACK
フレームを送信する必要がありません。
サーバはクライアントにメッセージを送信してすぐクライアントが受信したものと想定します。この確認応答モードではクライアントに送信される
メッセージが破棄される事があります。
ack
モードが client
の場合、クライアントはメッセージ処理に対してサーバへ ACK
フレームを送信しなければいけません。
クライアントがメッセージに対する ACK
フレームを送信する前に接続に失敗した場合、サーバはメッセージが処理されていないものとして
別のクライアントにメッセージを再配信してもよい。
クライアントが送信する ACK
フレームは累積確認応答として扱われます。
これは、その確認応答が ACK
フレームで指定されたメッセージと ACK
されたメッセージより前の購読で送信された全てのメッセージに対しての操作であることを意味します。
クライアントが複数のメッセージを処理しなかった場合、それらのメッセージを Consume しなかったことをサーバに伝えるために NACK
フレームを使用すべきです。
ack
モードが client-individual
の場合、確認応答はクライアントから送信された ACK
または NACK
フレームが累積されないことを除いて client
確認応答と同じように動作します。
これは後続のメッセージに対する ACK
または NACK
フレームが前のメッセージに確認応答を引き起こしてはならないことを意味します。
ACK
は client
または client-individual
確認応答を使用している区汚毒からメッセージの Consume を確認応答するために使用されます。
メッセージが ACK
を介して確認応答されるまで、購読から受信した全てのメッセージが Consume されたと見なされることはありません。
ACK
フレームは確認応答された MESSAGE
の ack
ヘッダと一致する id
ヘッダを含まなければいけません。
必要に応じて、メッセージの応答確認が指定されたトランザクションの一部でなければいけないことを示す transaction
ヘッダを含むことができます。
ACK
id:12345
transaction:tx1
^@
ABORT
は進行中のトランザクションをロールバックするために使用します。
ABORT
transaction:tx1
^@
transaction
ヘッダは必須であり中断するトランザクションの識別子を指定しなければいけません。
クライアントはソケットをクローズすることでいつでもサーバから切断することが出来ますが、直前に送信したフレームがサーバによって処理されている保証はありません。クライアントが送信した全てのフレームがサーバによって受信されたことが保証される Gracefull なシャットダウンを行うために、クライアントは:
receipt
ヘッダセット付きのDISCONNECT
フレームを送信する。例えば:
DISCONNECT
receipt:77
^@
DISCONNECT
に対するRECEIPT
フレームを待機する。例えば:
RECEIPT
receipt-id:77
^@
- ソケットをクローズする。
上記の手順を行うべきです。
サーバが予期せずソケットをクローズした場合、クライアントは期待する RECEIPT
を受け取れないかもしれないことに注意して下さい。詳細については Connection Lingering を参照。
クライアントは DISCONNECT
フレームの後にいかなるフレームも送信してはならない。
サーバはしばしば (初期接続の CONNECTED
フレームに加えて) クライアントにフレームを送信することがあります。
これらのフレームは以下のいずれかを指定できます:
MESSAGE
フレームはクライアントへ購読のメッセージを運ぶために使用されます。
MESSAGE
フレームはメッセージが送られた送信先を示す destination
ヘッダを含まなければなりません。
メッセージが STOMP を使用して送信されている場合、この destination
ヘッダは対応する SEND
フレームで使用したものと同一である必要があります。
このメッセージフレームはメッセージの一意な識別子 message-id
ヘッダと、メッセージを受信している購読の識別子と一致する subscription
ヘッダも含まなければならない。
メッセージが (client
または client-individual
モードのいずれか) 明示的な確認応答を必要とする購読から受信された場合、MESSAGE
フレームも任意の値の ack
ヘッダを含まなければならない。
このヘッダは後続の ACK
または NACK
フレームにメッセージを関連づけるために使用されます。
フレームのボディはメッセージの内容が含まれています:
MESSAGE
subscription:0
message-id:007
destination:/queue/a
content-type:text/plain
hello queue a^@
MESSAGE
フレームはもしボディが存在するなら content-length
ヘッダと content-type
ヘッダを含む必要があります。
MESSAGE
フレームは、フレームに追加することができるサーバ固有のヘッダに加えてメッセージが宛先に送信された時に存在した全てのユーザ定義ヘッダも含みます。
メッセージに追加されるサーバ固有のヘッダはサーバのドキュメントを参照して下さい。
RECEIPT
フレームはサーバが受領を要求するクライアントフレームの処理を正常に終えた後にサーバからクライアントに送信されます。
RECEIPT
フレームは、値が受領となるフレームの receipt
ヘッダの値となる receipt-id
ヘッダを含まなければならない。
RECEIPT
receipt-id:message-12345
^@
RECEIPT
フレームは、対応するクライアントのフレームがサーバによって処理されたことに対する確認応答です。
STOMP はストリームベースであるため、受領もまた前の全てのフレームがサーバによって受信されたことを示す累積確認応となります。
しかしながら、これらの前のフレームはまだ完全に処理されていないかもしれません。
クライアントが切断した場合、それより前に受信したフレームはサーバによって処理をし続けなければいけません。
この仕様は Creative Commons Attributes v3.0 の下でライセンスされています。