Skip to content

Instantly share code, notes, and snippets.

@torao
Last active December 14, 2021 10:57
Show Gist options
  • Save torao/fe3fab3ed879bb165c22b2f979d8a898 to your computer and use it in GitHub Desktop.
Save torao/fe3fab3ed879bb165c22b2f979d8a898 to your computer and use it in GitHub Desktop.
STOMP Specification, Version 1.2 日本語訳

Original Document

STOMP プロトコル仕様, Version 1.2 (日本語訳)

Abstract

STOPM は中継サーバを介してクライアント間での非同期メッセージパッシング用に設計されたシンプルで相互運用可能なプロトコルです。 それらのクライアントとサーバ間で渡されるテキストベースメッセージのワイヤーフォーマットを定義します。

STOMP は既に何年かのアクティブな利用実績があり多くのメッセージブローカーやクライアントライブラリによってサポートされています。 この仕様は STOMP 1.2 プロトコルを定義し STOMP 1.1 を更新します。

フィードバックはメーリングリスト stomp-spec@googlegroups.com へ送信して下さい。

Overview

Background

STOMP は Ruby, Python, Perl などのようなスクリプト言語からエンタープライズメッセージブローカーと接続する必要性から生まれました。 これらの環境では一般的に「確実に単一のメッセージと切断を送信する」または「指定した送信先のすべてのメッセージを消費する」ように 実施される論理的に簡単な操作となります。

これは AMQP のような他のオープンメッセージングプロトコルや、OpenWire のような JMS ブローカーで使用されている特定のワイヤー プロトコル実装の代替です。これらの違いは一般的に使用されるメッセージング操作の小さなサブセットをカバーするのではなく、総合的な メッセージング API を提供していることです。

最新の STOMP が提供しているワイヤーレベルの機能面では、これらのプロトコルの簡単なユースケース以上に使用することができる プロトコルに成熟しているが、それでもシンプルさと相互運用性のコア設計の原則を維持しています。

Protocol Overview

STOMP は HTTP をモデルとしたフレームによるフレームベースのプロトコルです。フレームはコマンドとオプションヘッダ、オプションの ボディで構成されています。STOMP はテキストベースですがバイナリメッセージの転送も可能です。STOMP のデフォルトのエンコーディングは UTF-8 ですがメッセージ本体の代替エンコーディングの指定をサポートしています。

STOMP サーバはメッセージを送信可能な送信先の集合として概念化されています。STOMP プロトコルは宛先を非空白文字列として扱い、 それらの構文はサーバ実装に固有です。さらに STOMP は宛先の配信セマンティクスがどうあるべきかを定義していません。目的地の 配信または「メッセージ交換」セマンティクスは宛先となるサーバからサーバ、さらには目的地から目的地で変化させることができます。 これはサーバが STOMP でサポートできるセマンティクスで創造的にできるようにします。

STOMP クライアントは 2 つのモデルを (おそらく同時に) 動作することが出来るユーザエージェントです:

  • Producer として、SEND フレームを使用してサーバ上の宛先にメッセージを送信する。
  • Consumer として、特定の宛先に SUBSCRIBE フレームを送信し、MESSAGE フレームとしてサーバからメッセージを受信する。

Changes in the Protocol

STOMP 1.2は STOMP 1.1 とほぼ下位互換性があります。 2つだけ互換性のない変更があります:

  • LF のみでなく CR LF でもフレーム行を終了することが可能になりました。
  • メッセージの確認応答 (acknowledgment) が簡素化され専用のヘッダを使用します。

これら以外に STOMP 1.2 では新機能が導入されていませんが、仕様における以下の領域の明確化に重点を置いています:

  • 重複するフレームヘッダのエントリ
  • content-lengthcontent-type ヘッダの使用
  • サーバによる STOMP フレームのサポートの必須
  • 接続の長引き (lingering)
  • 購読およびトランザクション識別子の範囲とユニーク性
  • 直前のフレームに関する RECEIPT フレームの意味

Design Philosophy

Conformance

STOMP Frames

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 を参照して下さい。

このドキュメントで参照している全てのコマンドとヘッダ名は大文字と小文字を区別します。

Value Encodign

Body

Standard Headers

Header content-length

Header content-type

Header receipt

Repeated Header Entries

Size Limits

Connection Lingering

Connecting

STOMP クライアントは CONNECT フレームをサーバへ送信することによりストリームまたは TCP 接続を開始します:

CONNECT
accept-version:1.2
host:stomp.github.org

^@

サーバが接続の試行を受け入れる場合は CONNECTED フレームで応答します:

CONNECTED
version:1.2

^@

サーバーは接続の試行を拒否することができます。サーバーは接続が拒否された理由を説明する ERROR フレームで応答を返し接続を閉じる 必要があります

CONNECT or STOMP Frame

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 設定。

CONNECTED Frame

Protocol Negotiation

Heart-beating

Client Frames

SEND

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

SUBSCRIBE フレームは与えられた宛先の購読を開始するために使用されます。 SEND フレームと同様に、SUBSCRIBE フレームはクライアントが購読を希望している宛先を示す destination ヘッダを必要とします。 購読している宛先が受信した全てのメッセージはその後にサーバからクライアントへ MESSAGE フレームとして配信されます。 ack ヘッダはメッセージの確認応答モードを制御します。

SUBSCRIBE
id:0
destination:/queue/foo
ack:client

^@

サーバが正常に購読を行えない場合、クライアントに ERROR フレームを送信し接続を閉じなければならない

STOMP サーバは購読の配信セマンティクスをカスタマイズするために追加のサーバ固有ヘッダをサポートすることができます。 詳細はあなたのサーバのドキュメントを参照して下さい。

SUBSCRIBE id Header

単一の接続上で複数の購読をオープンすることができるため、購読を識別するために一意の id ヘッダがフレームに含まれなければいけませんid ヘッダはクライアントとサーバがオリジナルの購読に後続の MESSAGE または UNSUBSCRIBE フレームを関連付けできるようにします。

同じ接続内では異なる購読は異なる購読識別子を使用しなければいけません

SUBSCRIBE ack Header

ack ヘッダの有効な値は autoclientclient-individual です。このヘッダが設定されていない場合 auto がデフォルトとして使用されます。

ack モードが auto の場合、クライアントはクライアントは受信したメッセージに対してサーバに ACK フレームを送信する必要がありません。 サーバはクライアントにメッセージを送信してすぐクライアントが受信したものと想定します。この確認応答モードではクライアントに送信される メッセージが破棄される事があります。

ack モードが client の場合、クライアントはメッセージ処理に対してサーバへ ACK フレームを送信しなければいけません。 クライアントがメッセージに対する ACK フレームを送信する前に接続に失敗した場合、サーバはメッセージが処理されていないものとして 別のクライアントにメッセージを再配信してもよい。 クライアントが送信する ACK フレームは累積確認応答として扱われます。 これは、その確認応答が ACK フレームで指定されたメッセージと ACK されたメッセージより前の購読で送信された全てのメッセージに対しての操作であることを意味します。

クライアントが複数のメッセージを処理しなかった場合、それらのメッセージを Consume しなかったことをサーバに伝えるために NACK フレームを使用すべきです

ack モードが client-individual の場合、確認応答はクライアントから送信された ACK または NACK フレームが累積されないことを除いて client 確認応答と同じように動作します。 これは後続のメッセージに対する ACK または NACK フレームが前のメッセージに確認応答を引き起こしてはならないことを意味します。

UNSUBSCRIBE

ACK

ACKclient または client-individual 確認応答を使用している区汚毒からメッセージの Consume を確認応答するために使用されます。 メッセージが ACK を介して確認応答されるまで、購読から受信した全てのメッセージが Consume されたと見なされることはありません。

ACK フレームは確認応答された MESSAGEack ヘッダと一致する id ヘッダを含まなければいけません。 必要に応じて、メッセージの応答確認が指定されたトランザクションの一部でなければいけないことを示す transaction ヘッダを含むことができます

ACK
id:12345
transaction:tx1

^@

NACK

BEGIN

COMMIT

ABORT

ABORT は進行中のトランザクションをロールバックするために使用します。

ABORT
transaction:tx1

^@

transaction ヘッダは必須であり中断するトランザクションの識別子を指定しなければいけません

DISCONNECT

クライアントはソケットをクローズすることでいつでもサーバから切断することが出来ますが、直前に送信したフレームがサーバによって処理されている保証はありません。クライアントが送信した全てのフレームがサーバによって受信されたことが保証される Gracefull なシャットダウンを行うために、クライアントは:

  1. receipt ヘッダセット付きの DISCONNECT フレームを送信する。例えば:
DISCONNECT
receipt:77
^@
  1. DISCONNECT に対する RECEIPT フレームを待機する。例えば:
RECEIPT
receipt-id:77
^@
  1. ソケットをクローズする。

上記の手順を行うべきです

サーバが予期せずソケットをクローズした場合、クライアントは期待する RECEIPT を受け取れないかもしれないことに注意して下さい。詳細については Connection Lingering を参照。

クライアントは DISCONNECT フレームの後にいかなるフレームも送信してはならない

Server Frames

サーバはしばしば (初期接続の CONNECTED フレームに加えて) クライアントにフレームを送信することがあります。 これらのフレームは以下のいずれかを指定できます:

MESSAGE

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 ヘッダの値となる receipt-id ヘッダを含まなければならない

RECEIPT
receipt-id:message-12345

^@

RECEIPT フレームは、対応するクライアントのフレームがサーバによって処理されたことに対する確認応答です。 STOMP はストリームベースであるため、受領もまた前の全てのフレームがサーバによって受信されたことを示す累積確認応となります。 しかしながら、これらの前のフレームはまだ完全に処理されていないかもしれません。 クライアントが切断した場合、それより前に受信したフレームはサーバによって処理をし続けなければいけません

ERROR

Frames and Headers

Augmented BNF

License

この仕様は Creative Commons Attributes v3.0 の下でライセンスされています。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment