即时通信记录集之—Stomp协议

一、简介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.

  1. STOMP是专为实现客户端之间(通过中间服务器) 异步通信的一个简单通信协议
  2. 基于文本的消息格式

二、背景

1.STOMP arose from a need to connect to enterprise message brokers from scripting languages such as Ruby, Python and Perl.
需要脚本实现企业消息服务的环境下诞生。

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

三、协议概要

  1. Stomp类似HTTP协议是一个基于数据帧的协议。
    一个数据帧由 命令行 + 报头(optional) + 正文(optional)
  2. STOMP是基于文本的,但也允许二进制消息的传输。 STOMP的默认编码为UTF-8,支持为消息体指定其他编码。

3.1 Stomp服务器

(1). STOMP服务器被建模为可以向其发送消息的一组目的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客户端

两个角色:

  1. as a producer, sending messages to a destination on the server via a SEND frame
  2. as a consumer, sending a SUBSCRIBE frame for a given destination and receiving messages from the server as MESSAGE frames.

3.3 Stomp数据帧Frame

Stomp 是一个基于数据帧的通信协议,它的下层是可靠的Tcp协议。
一个数据帧由 命令行 + 报头(optional) + 正文(optional)组成

一个标准的数据帧像下面这样

COMMAND
header1:value1
header2:value2

Body^@

详细:

1.command + EOL结束换行符
//zero or more header entries in <key>:<value> format
2.一个或者多个(键值对+EOL)组成的报头
3.空行或者EOL代表报头的结束
4.Body 

3.4 编码

1.The commands and headers are encoded in UTF-8
2.除了CONNECT CONNECTED

回车符
换行符
冒号

帧外其他的帧都会对这些符号进行转意处理,CONNECT CONNECTED没有是因为为了兼容Stomp 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

常用的一些报头

|报头|说明|
|----|----|----|
|content-length|消息正文的长度|
|content-type|MUST be a MIME type which describes the format of the body 正文格式|

防止恶意的内存攻击,服务端应该:

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重复的报头

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 客户端与服务端Connect连接

客户端发出CONNECT frame 请求

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

^@

连接成功服务端会返回 a CONNECTED frame:

CONNECTED
version:1.2

^@

如过连接被拒绝服务端将会返回 an ERROR frame 告诉客户端被拒绝的原因,然后关闭连接。

3.8.1 Stomp 与 Connect

  1. STOMP 1.2客户端应该继续使用CONNECT命令保持与STOMP 1.0服务器的向后兼容性。
  2. 使用STOMP帧而不是CONNECT帧的客户端将只能连接到STOMP 1.2服务器(以及一些STOMP 1.1服务器),但优点是协议嗅探器/鉴别器能够区分STOMP连接和HTTP连接。
    STOMP 1.2客户端必须设置以下头:

|报头|说明|建议|
|---|---|---|---|
|accept-version|客户端支持的STOMP协议的版本。||
|host|客户端希望连接的虚拟主机的名称。|建议将host设置为提供服务的主机名或者是服务端定的虚拟主机的名字。如果host字段与已知的虚拟主机不匹配,则支持虚拟主机的服务器会选择默认虚拟主机或会拒绝客户端的连接。实际使用中,服务端笔者用的是rabbitMq服务器,如果host名称不对,会直接拒绝客户的连接。|

附rabbitMq 虚拟主机的设置方法与设置权限的方法:

STOMP 1.2客户端可以设置以下标题:

报头 说明
login 登录名
passcode 密码
heart-beat 心跳设置

3.8.2 服务端CONNECTED

STOMP 1.2服务器必须设置以下头:

报头 说明
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服务器信息

3.8.3 session使用的协议版本

从STOMP 1.1开始,CONNECT帧必须包含accept-version头。
它应该设置为客户端支持的STOMP协议版本递增顺序,不同的版本间以逗号分隔。

CONNECT
accept-version:1.0,1.1,2.0
host:stomp.github.org

^@

服务端将会返回服务端与客户端同时支持的Stmop版本的最高版本。
如:

CONNECTED
version:1.1

^@

如过客户端和服务端之间没有共同的Stomp协议版本,服务端将会返回ERROR Frame :

ERROR
version:1.2,2.1
content-type:text/plain

Supported protocol versions are 1.2 2.1^@

3.9 Heart-beating 心跳数据

心跳数据是为了测试底层的TCP协议是否可用,以及远端服务器是否运作正常,是否和服务器保持着连接。

格式:

heart-beat:正整数,正整数

第一个数值表示发送者可以输出的心跳

0 代表发送者不能输出心跳数据
num  发送者能保证输出心跳数据的最小间隔(ms为单位)

第二个数字则表示发送者想要获得的(传入心跳):

0      表示不想接收心跳
num 所需的心跳数据间隔(ms为单位)
CONNECT
heart-beat:<cx>,<cy>

CONNECTED:
heart-beat:<sx>,<sy>

对于服务端来说:

1.如果 <cx>,<sy> 等于0,客户端不能发送心跳数据,服务端不必接收心跳数据的情况。服务端返回的CONNECTED帧中将不会返回heart-beat字段。
2. 否则的话,心跳数据的频率将会以<cx>,<sy>两者中最大的那一个值输出。

心跳频率确定好后,假如是<n>ms每次的心跳频率那么:

  1. 发送者必须在<n>ms内发送一次新的心跳数据。
  2. 如果发送方没有要发送的实际STOMP帧, it MUST send an end-of-line (EOL)
  3. 如果在至少<n>毫秒的时间窗口内,接收器没有接收到任何新数据,则其可以认为连接为死
  4. 由于定时不准确,接收机应该容忍并考虑误差容限

4 客户端以及服务端使用的Frame帧

客户端:

报头 格式 说明
SEND

服务端:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,930评论 6 13
  • 摘要 STOMP是一个简单的可互操作的协议, 被用于通过中间服务器在客户端之间进行异步消息传递。它定义了一种在客户...
    Leon622阅读 21,987评论 3 7
  • 1.OkHttp源码解析(一):OKHttp初阶2 OkHttp源码解析(二):OkHttp连接的"前戏"——HT...
    隔壁老李头阅读 20,826评论 24 176
  • 四月,已转身要走了 左手握一束晚霞 右手牵着你的名字 顺波而下的浮云 尽情地挥霍着流年 岸边迷离的桃红 盘旋受阻于...
    老影子阅读 375评论 0 2
  • 从懂事起我就知道我们家和别人家是不同的,别人家只有一个小孩儿,而我还有我哥。 每次我和别人说我还有个哥哥,别人都...
    流光pen阅读 201评论 0 0