一惯悠、簡(jiǎn)介Abstract
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.
- STOMP是專為實(shí)現(xiàn)客戶端之間(通過中間服務(wù)器) 異步通信的一個(gè)簡(jiǎn)單通信協(xié)議
- 基于文本的消息格式
二奔缠、背景
1.STOMP arose from a need to connect to enterprise message brokers from scripting languages such as Ruby, Python and Perl.
需要腳本實(shí)現(xiàn)企業(yè)消息服務(wù)的環(huán)境下誕生喂饥。
2.It is an alternative to other open messaging protocols such as AMQP and implementation specific wire protocols used in JMS brokers such as OpenWire.
其他消息的替代方案如AMQP 與 OpenWire
三窄陡、協(xié)議概要
- Stomp類似HTTP協(xié)議是一個(gè)基于數(shù)據(jù)幀的協(xié)議永部。
一個(gè)數(shù)據(jù)幀由 命令行 + 報(bào)頭(optional) + 正文(optional) - STOMP是基于文本的甲脏,但也允許二進(jìn)制消息的傳輸碱鳞。 STOMP的默認(rèn)編碼為UTF-8,支持為消息體指定其他編碼麻昼。
3.1 Stomp服務(wù)器
(1). STOMP服務(wù)器被建模為可以向其發(fā)送消息的一組目的destinations奠支。
(2). 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.
3.2 Stomp客戶端
兩個(gè)角色:
- as a producer, sending messages to a destination on the server via a SEND frame。
- as a consumer, sending a SUBSCRIBE frame for a given destination and receiving messages from the server as MESSAGE frames.
3.3 Stomp數(shù)據(jù)幀F(xiàn)rame
Stomp 是一個(gè)基于數(shù)據(jù)幀的通信協(xié)議抚芦,它的下層是可靠的Tcp協(xié)議倍谜。
一個(gè)數(shù)據(jù)幀由 命令行 + 報(bào)頭(optional) + 正文(optional)組成
一個(gè)標(biāo)準(zhǔn)的數(shù)據(jù)幀像下面這樣
COMMAND
header1:value1
header2:value2
Body^@
詳細(xì):
1.command + EOL結(jié)束換行符
//zero or more header entries in <key>:<value> format
2.一個(gè)或者多個(gè)(鍵值對(duì)+EOL)組成的報(bào)頭
3.空行或者EOL代表報(bào)頭的結(jié)束
4.Body
3.4 編碼
1.The commands and headers are encoded in UTF-8
2.除了CONNECT CONNECTED
回車符
換行符
冒號(hào)
幀外其他的幀都會(huì)對(duì)這些符號(hào)進(jìn)行轉(zhuǎn)意處理,CONNECT CONNECTED沒有是因?yàn)闉榱思嫒軸tomp 1.0以下版本叉抡。
\r (octet 92 and 114) translates to carriage return (octet 13)
\n (octet 92 and 110) translates to line feed (octet 10)
\c (octet 92 and 99) translates to : (octet 58)
\\ (octet 92 and 92) translates to \ (octet 92)
3.5 Body
Only the SEND, MESSAGE, and ERROR frames MAY have a body. All other frames MUST NOT have a body.
3.6 Standard Headers
常用的一些報(bào)頭
|報(bào)頭|說明|
|----|----|----|
|content-length|消息正文的長(zhǎng)度|
|content-type|MUST be a MIME type which describes the format of the body 正文格式|
防止惡意的內(nèi)存攻擊尔崔,服務(wù)端應(yīng)該:
the number of frame headers allowed in a single frame
the maximum length of header lines
the maximum size of a frame body
3.7重復(fù)的報(bào)頭
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.
1. A STOMP server MAY 'update' header values by either prepending headers to the message or modifying a header in-place in the message.
2. 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.
For example, if the client receives:
MESSAGE
foo:World
foo:Hello
^@
The value of the foo header is just World.
3.8 客戶端與服務(wù)端Connect連接
客戶端發(fā)出CONNECT frame 請(qǐng)求
CONNECT
accept-version:1.2
host:stomp.github.org
^@
連接成功服務(wù)端會(huì)返回 a CONNECTED frame:
CONNECTED
version:1.2
^@
如過連接被拒絕服務(wù)端將會(huì)返回 an ERROR frame 告訴客戶端被拒絕的原因,然后關(guān)閉連接褥民。
3.8.1 Stomp 與 Connect
- STOMP 1.2客戶端應(yīng)該繼續(xù)使用CONNECT命令保持與STOMP 1.0服務(wù)器的向后兼容性季春。
- 使用STOMP幀而不是CONNECT幀的客戶端將只能連接到STOMP 1.2服務(wù)器(以及一些STOMP 1.1服務(wù)器),但優(yōu)點(diǎn)是協(xié)議嗅探器/鑒別器能夠區(qū)分STOMP連接和HTTP連接消返。
STOMP 1.2客戶端必須設(shè)置以下頭:
|報(bào)頭|說明|建議|
|---|---|---|---|
|accept-version|客戶端支持的STOMP協(xié)議的版本载弄。||
|host|客戶端希望連接的虛擬主機(jī)的名稱。|建議將host設(shè)置為提供服務(wù)的主機(jī)名或者是服務(wù)端定的虛擬主機(jī)的名字撵颊。如果host字段與已知的虛擬主機(jī)不匹配宇攻,則支持虛擬主機(jī)的服務(wù)器會(huì)選擇默認(rèn)虛擬主機(jī)或會(huì)拒絕客戶端的連接。實(shí)際使用中倡勇,服務(wù)端筆者用的是rabbitMq服務(wù)器逞刷,如果host名稱不對(duì),會(huì)直接拒絕客戶的連接妻熊。|
附rabbitMq 虛擬主機(jī)的設(shè)置方法與設(shè)置權(quán)限的方法:
STOMP 1.2客戶端可以設(shè)置以下標(biāo)題:
報(bào)頭 | 說明 |
---|---|
login | 登錄名 |
passcode | 密碼 |
heart-beat | 心跳設(shè)置 |
3.8.2 服務(wù)端CONNECTED
STOMP 1.2服務(wù)器必須設(shè)置以下頭:
報(bào)頭 | 說明 |
---|---|
version | The version of the STOMP protocol the session will be using |
heart-beat | The Heart-beating settings. |
session | A session identifier that uniquely identifies the session. |
server | Stomp服務(wù)器信息 |
3.8.3 session使用的協(xié)議版本
從STOMP 1.1開始夸浅,CONNECT幀必須包含accept-version頭。
它應(yīng)該設(shè)置為客戶端支持的STOMP協(xié)議版本遞增順序固耘,不同的版本間以逗號(hào)分隔题篷。
CONNECT
accept-version:1.0,1.1,2.0
host:stomp.github.org
^@
服務(wù)端將會(huì)返回服務(wù)端與客戶端同時(shí)支持的Stmop版本的最高版本。
如:
CONNECTED
version:1.1
^@
如過客戶端和服務(wù)端之間沒有共同的Stomp協(xié)議版本厅目,服務(wù)端將會(huì)返回ERROR Frame :
ERROR
version:1.2,2.1
content-type:text/plain
Supported protocol versions are 1.2 2.1^@
3.9 Heart-beating 心跳數(shù)據(jù)
心跳數(shù)據(jù)是為了測(cè)試底層的TCP協(xié)議是否可用番枚,以及遠(yuǎn)端服務(wù)器是否運(yùn)作正常法严,是否和服務(wù)器保持著連接。
格式:
heart-beat:正整數(shù)葫笼,正整數(shù)
第一個(gè)數(shù)值表示發(fā)送者可以輸出的心跳
0 代表發(fā)送者不能輸出心跳數(shù)據(jù)
num 發(fā)送者能保證輸出心跳數(shù)據(jù)的最小間隔(ms為單位)
第二個(gè)數(shù)字則表示發(fā)送者想要獲得的(傳入心跳):
0 表示不想接收心跳
num 所需的心跳數(shù)據(jù)間隔(ms為單位)
CONNECT
heart-beat:<cx>,<cy>
CONNECTED:
heart-beat:<sx>,<sy>
對(duì)于服務(wù)端來說:
1.如果 <cx>,<sy> 等于0,客戶端不能發(fā)送心跳數(shù)據(jù)深啤,服務(wù)端不必接收心跳數(shù)據(jù)的情況。服務(wù)端返回的CONNECTED幀中將不會(huì)返回heart-beat字段路星。
2. 否則的話溯街,心跳數(shù)據(jù)的頻率將會(huì)以<cx>,<sy>兩者中最大的那一個(gè)值輸出。
心跳頻率確定好后洋丐,假如是<n>ms每次的心跳頻率那么:
- 發(fā)送者必須在<n>ms內(nèi)發(fā)送一次新的心跳數(shù)據(jù)呈昔。
- 如果發(fā)送方?jīng)]有要發(fā)送的實(shí)際STOMP幀, it MUST send an end-of-line (EOL)
- 如果在至少<n>毫秒的時(shí)間窗口內(nèi)友绝,接收器沒有接收到任何新數(shù)據(jù)堤尾,則其可以認(rèn)為連接為死
- 由于定時(shí)不準(zhǔn)確,接收機(jī)應(yīng)該容忍并考慮誤差容限
4 客戶端以及服務(wù)端使用的Frame幀
客戶端:
報(bào)頭 | 格式 | 說明 | |
---|---|---|---|
SEND |
服務(wù)端: