STOMP协议1.2

STOMP 协议规范,版本 1.2

  • 摘要
  • 概览
    • 背景
    • 协议概览
    • 协议变更
    • 设计哲学
  • 一致性
  • STOMP帧
    • 值的编码
    • 消息Body
    • 标准的Headers
      • Header content-length
      • Header content-type
      • Header receipt
    • 重复的Header Entries
    • 消息大小限制
    • 连接延迟关闭
  • Connecting
    • CONNECT或STOMP帧
    • CONNECTED帧
    • 协议协商
    • 心跳
  • 客户端可发送的帧
    • SEND
    • SUBSCRIBE
      • SUBSCRIBE id Header
      • SUBSCRIBE ack Header
    • UNSUSCRIBE
    • ACK
    • NACK
    • BEGIN
    • COMMIT
    • ABORT
    • DISCONNECT
  • 服务器可发送的帧
    • MESSAGE
    • RECEIPT
    • ERROR
  • 帧对应的Headers
  • 扩展的BNF
  • 许可

摘要

STOMP 是一个简单的可互操作协议,设计用于异步消息传递,通过中介服务器在客户端之间进行。它定义了客户端和服务器之间传递消息的基于文本的线路格式。

STOMP 已经活跃使用多年,并且被许多消息代理和客户端库支持。本规范定义了 STOMP 1.2 协议,并且是 STOMP 1.1 的更新。 请将反馈发送至stomp-spec@googlegroups.com邮件列表。

概览

背景

STOMP 起源于从 Ruby、Python 和 Perl 等脚本语言连接到企业消息代理的需求。在这样的环境中,通常执行的逻辑上简单的操作,如“可靠地发送单个消息并断开连接”或“消费给定目的地的所有消息”。

它是一种替代其他开放消息协议的选择,比如AMQP以及在JMS代理中使用的特定实现的线路协议,例如OpenWire。它通过覆盖一小部分常用的消息操作来区分自己,而不是提供全面的通信API。

复制再试一次分享

最近,STOMP已经成为一种成熟的协议,它可以用于这些简单用例之外的场合,因为它现在提供了wire-level特性,但仍然保持了其核心的设计原则,即简单性和互操作性。

协议概览

STOMP 是一个基于帧的协议,它的帧结构模仿了 HTTP。一个帧由命令、一组可选header和一个可选body组成。STOMP 是基于文本的,但也允许传输二进制消息。STOMP 的默认编码是 UTF-8,但它支持为消息主体指定备用编码。

STOMP 服务器被建模为一组destinations,消息可以发送到这些destinations。STOMP 协议将没有规定destination字符串的格式和内容,它们的语法与使用的服务器相关。此外,STOMP 没有定义destination的传递语义应该是什么。destination的传递,或“消息交换”语义,在不同服务器可以不同,甚至不同destination间也可以不同。这使得服务器能够更有创造性地使用 STOMP 支持的语义。

STOMP 客户端是一个用户代理,可以以两种(可能同时)模式运行:

  • 作为生产者,通过一个SEND帧向服务器上的destination发送消息。
  • 作为消费者,向给定的destination发送 SUBSCRIBE 帧,并从服务器接收作为 MESSAGE 帧的消息。

协议变更

STOMP 1.2 与 STOMP 1.1 大体上向后兼容。只有两个不兼容的变更:

  • 现在可以使用回车加换行符来代替换行符结束帧行。
  • 消息确认已经被简化,现在使用专门的header。

除了这些,STOMP 1.2 没有引入新特性,而是专注于阐明规范的某些领域,如:

  • 重复的帧header entries
  • content-lengthcontent-type headers的使用
  • 服务器必须支持 STOMP
  • 连接延迟关闭
  • 订阅和事务标识符的范围和唯一性
  • RECEIPT 帧相对于先前帧的含义

设计哲学

驱动 STOMP 设计的主要哲学是简单性和互操作性。

STOMP 被设计为一个轻量级协议,易于在大多数编程语言上同时实现客户端和服务器端的功能。这意味着,特别是对服务器架构没有太多限制,许多特性如destination命名和可靠性语义是特定于实现的。

在本规范中,我们将注意 STOMP 1.2 未明确定义的服务器功能。你应该查阅对应的STOMP 服务器的文档,了解这些功能的具体实现细节。

一致性

本文档中的关键词MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”和“OPTIONAL”应按照 R**RFC 2119** 中的描述进行解释。

实现可能会对不受约束的输入施加特定于实现的限制,例如,防止拒绝服务攻击、防止内存不足或解决特定于平台的限制。

本规范定义的一致性类别是 STOMP 客户端和 STOMP 服务器。

STOMP 的帧

STOMP 是一个基于帧的协议,它假设底层有一个可靠的双向流网络协议(如 TCP)。客户端和服务器将使用通过流发送的 STOMP 帧进行通信。一个帧的结构如下所示:

COMMAND
header1:value1
header2:value2

Body^@

帧以一个命令字符串开始,命令字符串紧接着结束行(EOL)表示命令行终止。EOL 由一个可选的回车(octet 13)后面跟着一个必需的换行(octet 10)组成。在命令之后是零个或多个以 <key>:<value> 格式的header内容。每个header都以 EOL 终止。一个空行(即额外的 EOL)表示headers的结束和body内容的开始。然后,body后面跟着 NULL octet。本文档中的示例将使用可视化字符 ^@表示,ASCII 中是用control-@ 来表示 NULL octet。NULL octet后面可以跟着多个 EOL。有关如何解析 STOMP 帧的更多详细信息,请参见本文档的“扩展的 BNF”部分。

本文档中引用的所有命令和header名称都是区分大小写的。

值编码

命令和headers使用 UTF-8 编码。除了 CONNECTCONNECTED 帧之外的所有帧,还将转义 UTF-8 编码的headers中发现的任何回车、换行或冒号。

转义是必要的,以允许header键和值包含那些作为值的帧header分隔octet。为了与 STOMP 1.0 保持向后兼容,CONNECT 和 CONNECTED 帧不转义回车、换行或冒号octet。

C 风格字符串文字转义用于编码在 UTF-8 已编码的headers中发现的任何回车、换行或冒号。在解码帧headers时,必须应用以下转换:

  • \\r (octet 92 and 114) 转换为回车 (octet 13)
  • \\n (octet 92 and 110) t转换为换行 (octet 10)
  • \\c (octet 92 and 99) 转换为 : (octet 58)
  • \\\\ (octet 92 and 92) 转换为 \\ (octet 92)

未定义的转义序列,如 \t (octet 92 和 116) 必须被视为致命的协议错误。反之,在编码帧headers时,必须应用反向转换。

STOMP 1.0 规范包括了许多带有headers填充的示例帧,许多服务器和客户端被实现为修剪或填充headers值。如果应用程序想要发送不应该被修剪的header,则这会引起问题。在 STOMP 1.2 中,客户端和服务器绝不能使用删掉headers的空格或往headers填充空格。

消息的主体

只有 SENDMESSAGE, 和 ERROR  帧可能有主体。所有其他帧必须没有主体。

标准的Headers

一些headers可能被使用,并且在大多数帧中具有特殊含义。

Header content-length

所有帧都可能包含 content-length 头部。这个header是消息body长度的字节数量。如果包含了 content-length header,就必须读取这么长的字节,不管body中是否有 NULL octets。帧的终止符仍然是用 NULL octets。

如果帧包含body,SENDMESSAGEERROR 帧应包括一个 content-length header以简化帧的解析。如果帧的body包含 NULL octets,帧必须包括一个 content-length header。

Header content-type

如果帧包含body,SENDMESSAGEERROR 帧应包括一个 content-type header以帮助接收方解释其body。如果设置了 content-type header,它的值必须是描述body格式的 MIME 类型。否则,接收方应将body视为二进制数据块。

text/ 开头的 MIME 类型的默认文本编码是 UTF-8。如果要使用不同编码的文本 MIME 类型,则应将;charset=<encoding>附加到 MIME 类型。例如,如果要发送 UTF-16 编码的 HTML body,则应使用 text/html;charset=utf-16 。;charset=<encoding> 还应被追加到任何可以被解释为文本的非 text/ MIME 类型。比如 UTF-8 编码的 XML。它的content-type 应设置为 application/xml;charset=utf-8

所有 STOMP 的客户端和服务器必须支持 UTF-8 编码和解码。因此,为了在异构计算环境中实现最大的互操作性,建议使用 UTF-8 对基于文本的内容进行编码。

Header receipt

除了 CONNECT 之外的任何客户端帧都可能指定一个带有任意值的 receipt header。这将让服务器返回一个 RECEIPT 帧给客户端,表示已处理完成客户端发来的帧(有关更多详细信息,请参见 RECEIPT 帧)。

SEND
destination:/queue/a
receipt:message-12345

hello queue a^@

重复的Header Entries

由于消息系统可以像 SMTP 一样以存储和转发拓扑结构进行组织,因此一条消息在到达消费者之前可能会经过多个消息服务器。STOMP 服务器可以通过在消息中添加headers或修改现有header来“更新”header值。

如果客户端或服务器接收到重复的帧header entries,应只使用第一个header entry作为头部条目的值。后续值仅用于维护头部状态更改的历史记录,并且可以被忽略。

例如,如果客户端接收到这样的消息:

MESSAGE
foo:World
foo:Hello

^@

foo header的值是 World。

大小限制

为了防止恶意客户端利用服务器的内存分配机制,服务器可能对以下内容设置最大限制:

  • 单个帧中允许的headers数量
  • header行的最大长度
  • 帧body的最大大小

如果超过这些限制,服务器应该向客户端发送一个 ERROR 帧,然后关闭连接。

连接延迟关闭

STOMP 服务器必须能够支持客户端的快速连接和断开。

这意味着服务器可能只允许已关闭的连接,在连接重置之前保留很短的时间。

因此,客户端可能在套接字被重置之前,无法正常接收服务器发送的最后一个帧(例如响应 DISCONNECT 帧的 ERROR 帧或 RECEIPT 帧)。

Connecting

STOMP 客户端通过发送 CONNECT 帧来启动到服务器的stream或 TCP 连接:

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

^@

如果服务器接受连接尝试,它将响应 CONNECTED 帧:

CONNECTED
version:1.2

^@

服务器可以拒绝任何连接尝试。服务器应响应一个 ERROR 帧,解释拒绝连接的原因,然后关闭该连接。

CONNECT or STOMP 帧

STOMP 的服务器处理STOMP 帧的方式和处理 CONNECT 帧相同。STOMP 1.2 版本的客户端应继续支持 CONNECT 命令来保持与 STOMP 1.0 版本服务器的向后兼容性。

客户端连接STOMP 1.2 服务器(以及一些 STOMP 1.1 服务器)能使用 STOMP 帧来代替 CONNECT 帧,优点是协议嗅探器/鉴别器将能够将 STOMP 连接与 HTTP 连接区分开来。

STOMP 1.2 客户端必须设置以下headers:

  • accept-version : 客户端支持的 STOMP 协议版本。有关协议协商的更多详细信息,请参阅协议协商
  • host :客户端希望连接的虚拟主机的名称。建议客户端将这个值设置为建立套接字的主机名,或者其他任意名称。如果这个header不匹配已有的虚拟主机,支持虚拟托管的服务器可以选择一个默认虚拟主机或拒绝连接。

STOMP 1.2 客户端可选的headers:

  • login: 有安全要求的 STOMP 服务器进行身份验证的用户标识符。
  • passcode: 有安全要求的 STOMP 服务器进行身份验证的密码。
  • heart-beat : 心跳设置。

CONNECTED 帧

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

  • version : 会话将使用的 STOMP 协议版本。有关更多详细信息,请参阅协议协商

STOMP 1.2 服务器可选的headers:

  • heart-beat : 心跳设置。

  • session : 用于标识会话的唯一会话标识符。

  • server : 包含有关 STOMP 服务器信息的字段。该字段必须包含server-name字段,并且后面可以是由空格octet分隔的可选注释字段。

    server-name 字段由一个名称标记和一个可选的版本号标记组成。

    server = name ["/" version] *(comment)

    例如:

    server:Apache/1.3.9

协议协商

从 STOMP 1.1 及以后,CONNECT 帧必须包含 accept-version header。它应设置为客户端支持的STOMP 协议版本的集合(集合里的版本号用逗号分隔,并且随版本号数值递增)。如果缺少 accept-version header,则意味着客户端仅支持 1.0 版本的协议。

后面的会话将使用客户端和服务器之间共同支持的协议的最高版本。

例如,如果客户端发送以下消息:

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

^@

服务器将响应用它与客户端支持的最高版本:

CONNECTED
version:1.1

^@

如果客户端和服务器没有共同支持的协议版本,那么服务器必须响应类似示例里的ERROR帧,然后关闭连接:

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

Supported protocol versions are 1.2 2.1^@

心跳机制

可以选择使用心跳机制来测试底层 TCP 连接的健康状况,并确保远端处于活动状态。

为了启用心跳机制,双方都必须声明它能够做什么以及它希望对方做什么。这发生在 STOMP 会话的一开始,通过向 CONNECTCONNECTED 帧添加一个 heart-beat header。

当使用心跳机制时,heart-beat header必须包含两个由逗号分隔的正整数。

第一个数字表示发送方能够做的事情(传出心跳):

  • 0 表示它不能发送心跳
  • 否则,表示可以保证发送心跳间隔的最小毫秒数

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

  • 0 表示它不想接收心跳
  • 否则,它表示心跳之间所需的毫秒数

heart-beat header是可选的。缺少的 heart-beat header必须被视为与“heart-beat:0,0”header相同,即:该方不能发送也不想接收到心跳。

heart-beat header提供了足够的信息,以便各方可以找出是否可以使用心跳,心跳的方向以及频率。

更具体地说,初始帧看起来像这样的格式:

CONNECT
heart-beat:<cx>,<cy>

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

对于客户端发给服务器的心跳:

  • 如果 <cx> 是 0(客户端不能发送心跳)或 <sy> 是 0(服务器不想接收心跳),那么就没有心跳
  • 否则,每 MAX(<cx>,<sy>) 毫秒会有心跳

在另一个方向上(服务器给客户端发送心跳),<sx><cy> 以相同的方式使用。

关于心跳本身,通过网络连接接收到的任何新数据都是远端活动的迹象。在给定方向上,如果心跳每 <n> 毫秒预期一次:

  • 发送方必须至少每 <n> 毫秒发送一次新数据到网络连接
  • 如果发送方没有真实的 STOMP 帧要发送,它必须发送一个结束行(EOL)
  • 如果,在至少 <n> 毫秒的时间窗口内,接收方没有接收到任何新数据,它可能会认为连接已死亡
  • 由于计时不准确,接收方应该容忍并考虑误差范围

客户端发送的帧

客户端可以发送不在本列表中的帧,但对于这样的帧,STOMP 1.2 服务器可能会响应一个ERROR 帧,然后关闭连接。

  • [SEND](<https://stomp.github.io/stomp-specification-1.2.html#SEND>)
  • [SUBSCRIBE](<https://stomp.github.io/stomp-specification-1.2.html#SUBSCRIBE>)
  • [UNSUBSCRIBE](<https://stomp.github.io/stomp-specification-1.2.html#UNSUBSCRIBE>)
  • [BEGIN](<https://stomp.github.io/stomp-specification-1.2.html#BEGIN>)
  • [COMMIT](<https://stomp.github.io/stomp-specification-1.2.html#COMMIT>)
  • [ABORT](<https://stomp.github.io/stomp-specification-1.2.html#ABORT>)
  • [ACK](<https://stomp.github.io/stomp-specification-1.2.html#ACK>)
  • [NACK](<https://stomp.github.io/stomp-specification-1.2.html#NACK>)
  • [DISCONNECT](<https://stomp.github.io/stomp-specification-1.2.html#DISCONNECT>)

SEND

SEND 帧向消息系统中的destination发送消息。它有一个必需的destination header,指示消息发送的目的地。SEND 帧的body是要发送的消息内容。例如:

SEND
destination:/queue/a
content-type:text/plain

hello queue a
^@

这给消息值为/queue/a 的destination发送了一条消息。请注意,STOMP协议 将这个destination值视为一个普通的字符串,不会假设它会传递任何语义。你应查阅你的 STOMP 服务器的文档,来找出如何构造一个destination名称,该名称为你提供应用程序所需的传递语义。

消息的可靠性语义也是特定服务器相关,并且取决于所使用的destination值和其他消息headers,例如transaction header或其他服务器特定的消息headers。

SEND 支持一个transaction header,允许事务性发送消息。

如果存在body,SEND 帧应包括一个 [content-length](<https://stomp.github.io/stomp-specification-1.2.html#Header_content-length>) header和一个**[content-type](<https://stomp.github.io/stomp-specification-1.2.html#Header_content-type>)** header。

应用程序可以向 SEND 帧添加任意用户定义的headers。用户定义的headers通常用于允许消费者基于 SUBSCRIBE 帧上的选择器使用应用程序定义的headers来过滤消息。用户定义的headers必须在 MESSAGE 帧中传递。

如果服务器由于任何原因无法成功处理 SEND 帧,服务器必须向客户端发送一个 ERROR 帧,然后关闭连接。

SUBSCRIBE

SUBSCRIBE 帧用于注册给定destination的监听。像 SEND 帧一样,SUBSCRIBE 帧需要一个 destination header,表示客户端想要订阅的destination。此后,在订阅destination上收到的任何消息都将作为 MESSAGE 帧从服务器传递到客户端。 ack header用于控制消息的确认模式。

示例:

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

^@

如果服务器无法成功创建订阅,服务器必须向客户端发送一个 ERROR 帧,然后关闭连接。

STOMP 服务器可以支持附加的服务器特定headers来自定义订阅的传递语义。有关详细信息,请参阅服务器的文档。

SUBSCRIBE id Header

由于单个连接可以与服务器有多个打开的订阅,因此必须在帧中包含一个 id 头部,以唯一标识订阅。id 头部允许客户端和服务器将后续的 MESSAGE 或 UNSUBSCRIBE 帧与原始订阅关联起来。

由于单个连接可以与服务器打开多个订阅,因此帧中必须包含 id header 用以唯一标识一个订阅。 id header 允许客户端和服务器将后续的 MESSAGEUNSUBSCRIBE 帧与原始订阅关联起来。

在同一连接内,不同的订阅必须使用不同的订阅标识符。

SUBSCRIBE ack Header

ack header的可选值有 autoclientclient-individual。如果该值未设置,默认为 auto

ack 模式是 auto 时,客户端不需要在它接收到的消息后,向服务器发送 ACK 帧。一旦服务器将消息发送给客户端,服务器就会认为客户端已收到消息。这种确认模式可能会导致传输到客户端的消息被丢弃。

ack 模式为 client 时,客户端必须为它处理过消息,向服务器发送 ACK 帧。如果连接在客户端发送 ACK 帧之前失败,服务器将假定消息尚未被处理,并且可能会将消息重新传递给另一个客户端。客户端发送的 ACK 帧将被视为累积确认。这意味着确认操作适用于 ACK 帧中指定的消息,以及在 ACK'ed 消息之前发送到订阅的所有消息。

如果客户端没有处理某些消息,它应发送 NACK 帧来告诉服务器它没有消费这些消息。

ack 模式为 client-individual 时,确认操作就像 client 确认模式一样,只是客户端发送的 ACKNACK 帧不是累积的。这意味着对后续消息的 ACKNACK 帧不应导致之前的消息被确认。

UNSUBSCRIBE

UNSUBSCRIBE 帧用于删除现有的订阅。一旦订阅被删除,STOMP 连接将不再从该订阅接收消息。

由于单个连接可以与服务器有多个打开的订阅,因此必须在帧中包含一个 id header ,用来唯一标识要删除的订阅。这个header的值必须和已订阅的订阅标识符匹配。

示例:

UNSUBSCRIBE
id:0

^@

ACK

ACKclientclient-individual 确认模式下,用于确认消费的消息。从这样的订阅通道接收到的任何的消息,在通过 ACK 确认之前都不会被认为已被消费。

ACK 帧必须包括一个与被确认的 MESSAGEack header匹配的 id header。可选地,可以指定一个transaction header,表示消息确认是当前事务的一部分。

ACK
id:12345
transaction:tx1

^@

NACK

NACKACK 相反。它用于告诉服务器客户端没有消费消息。服务器随后可以将消息发送给其他的客户端、丢弃它,或者将它放入死信队列。具体的行为是特定服务器有关的。

NACK 使用与 ACK 相同的headers:id(必需)和 transaction(可选)。

如果订阅的 ack 模式是 client-individual,则 NACK 适用于单个消息。如果订阅的 ack 模式是 client,则适用于所有在未被 ACK'ed 或 NACK'ed 确认之前发送的消息。

BEGIN

BEGIN 用于开启一个事务。在这种情况下,事务适用于发送和确认 - 在事务期间发送或确认的任何消息将根据事务以原子方式处理。

BEGIN
transaction:tx1

^@

transaction header是必填的,事务标识符将用于 SENDCOMMITABORTACKNACK 帧,将它们绑定到相同名称的事务上。在同一连接内,不同的事务必须使用不同的事务标识符。

如果客户端发送了 DISCONNECT 帧,或者 TCP 连接由于任何原因失败,任何未提交的开始事务将被隐式中止。

COMMIT

COMMIT 用于提交正在进行的事务。

COMMIT
transaction:tx1

^@

transaction heade是必填的,并且必须指定要提交的事务的标识符。

ABORT

ABORT 用于回滚正在进行的事务。

ABORT
transaction:tx1

^@

transaction heade是必填的,并且必须指定要中止的事务的标识符。

DISCONNECT

客户端可以随时通过关闭套接字与服务器断开连接,但不能保证先前发送的帧已被服务器接收。要进行优雅地关闭,客户端可以确保所有先前发送的帧都已被服务器接收,客户端应该:

  1. 发送一个带有设置了 receipt header的 DISCONNECT 帧。示例:
DISCONNECT
receipt:77
^@
  1. 等待 DISCONNECT 响应的 RECEIPT 帧。示例:

    RECEIPT
    receipt-id:77
    ^@
    
  2. 关闭套接字。

请注意,如果服务器关闭它的套接字太快了,客户端可能永远收不到期望的 RECEIPT 帧。有关更多信息,请参见“连接挂起”部分。

在发送 DISCONNECT 帧后,客户端绝不能发送其他的帧。

服务端发送的帧

有时,服务器会向客户端发送帧(除了初始的 CONNECTED 帧之外)。这些帧可能是以下之一:

  • [MESSAGE](<https://stomp.github.io/stomp-specification-1.2.html#MESSAGE>)
  • [RECEIPT](<https://stomp.github.io/stomp-specification-1.2.html#RECEIPT>)
  • [ERROR](<https://stomp.github.io/stomp-specification-1.2.html#ERROR>)

MESSAGE

MESSAGE 帧用于将订阅中的消息传递给客户端。

MESSAGE 帧必须包括一个 destination header,指示消息发送到的目的地。如果消息是使用 STOMP 发送的,那么这个 destination header 应该是与相应 SEND 帧中使用的destination header相同。

MESSAGE 帧还必须包含一个 message-id header,该header具有该消息的唯一标识符,以及一个与接收该消息的订阅的标识符相匹配的subscription header。

如果消息是从需要显式确认(ack是 clientclient-individual 模式)的订阅中接收的,那么 MESSAGE 帧还必须包含一个 ack header,该header可以是任意值。这个header将用于将消息与后续的 ACKNACK 帧关联。

帧体包含消息的内容如下:

MESSAGE
subscription:0
message-id:007
destination:/queue/a
content-type:text/plain

hello queue a^@

如果消息包含body,MESSAGE 帧应包括一个 [content-length](<https://stomp.github.io/stomp-specification-1.2.html#Header_content-length>) header和一个 [content-type](<https://stomp.github.io/stomp-specification-1.2.html#Header_content-type>) header。

除了添加和特定服务器相关的header之外,MESSAGE帧还将包含消息发送到目的地时,包含的所有用户定义的标头。

请查阅你使用的服务器的文档,了解它向消息额外添加的headers。

RECEIPT

RECEIPT 帧是服务器在成功处理要求返回收据的客户端帧后,发送给客户端的消息。RECEIPT 帧必须包括一个receipt-id header,其中该值是作为收据的帧中的receipt header的值。

RECEIPT
receipt-id:message-12345

^@

RECEIPT 帧是对相应客户端帧已由服务器处理完毕的确认消息。由于 STOMP 是基于流的,因此收据也是服务器已接收到所有先前帧的累积确认。但是,这些先前的帧可能尚未完全处理。如果客户端断开连接,先前接收到的帧应该继续由服务器处理。

ERROR

如果出现问题,服务器可能会发送 ERROR 帧。在这种情况下,它必须在发送 ERROR 帧后立即关闭连接。参考下一节有关连接挂起

ERROR 帧应包含一个 message header来简要描述错误原因,并且body 里可以包含更详细的信息(或者也可以为空)。

ERROR
receipt-id:message-12345
content-type:text/plain
content-length:170
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.
^@

如果错误的发生与客户端发送的某个帧有关,服务器应在 ERROR 帧中添加额外的headers,来帮助客户端识别引起错误的原始帧。例如,如果该帧包含了一个 receipt header,ERROR 帧应将 receipt-id header设置为成引起错误帧的 receipt header 一样的值。

如果消息包含body,ERROR 帧应包括一个 [content-length](<https://stomp.github.io/stomp-specification-1.2.html#Header_content-length>) header和一个 [content-type](<https://stomp.github.io/stomp-specification-1.2.html#Header_content-type>) header。

Frames and Headers

除了上面描述的标准头部(content-lengthcontent-type 和 receipt),这里是本规范中定义的每个帧对应的必须或可选的头部:

  • CONNECT 或 STOMP
    • 必填: accept-versionhost
    • 可选: loginpasscodeheart-beat
  • CONNECTED
    • 必填: version
    • 可选: sessionserverheart-beat
  • SEND
    • 必填: destination
    • 可选: transaction
  • SUBSCRIBE
    • 必填: destinationid
    • OPTIONAL: ack
  • UNSUBSCRIBE
    • 必填: id
    • 可选: none
  • ACK or NACK
    • 必填: id
    • 可选: transaction
  • BEGIN 或 COMMIT 或 ABORT
    • REQUIRED: transaction
    • 可选: none
  • DISCONNECT
    • 必填: none
    • 可选: receipt
  • MESSAGE
    • 必填: destinationmessage-idsubscription
    • 可选: ack
  • RECEIPT
    • 必填: receipt-id
    • 可选: none
  • ERROR
    • 必填: none
    • 可选: message

此外,SENDMESSAGE 帧可能包含用户自定义的headers,这些headers应被视为消息的一部分。此外,ERROR 帧应包括额外的headers,来帮助客户端识别引起错误的原始帧。

最后,STOMP 服务器可以使用额外的headers来提供对持久性或过期等功能的访问。有关详细信息,请参阅服务器的文档。

扩展的 BNF

STOMP 会话可以使用 HTTP/1.1 RFC 2616 中使用的Backus-Naur Form(BNF)语法进行更正式的描述。

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
                      *( EOL )

command             = client-command | server-command

client-command      = "SEND"
                      | "SUBSCRIBE"
                      | "UNSUBSCRIBE"
                      | "BEGIN"
                      | "COMMIT"
                      | "ABORT"
                      | "ACK"
                      | "NACK"
                      | "DISCONNECT"
                      | "CONNECT"
                      | "STOMP"

server-command      = "CONNECTED"
                      | "MESSAGE"
                      | "RECEIPT"
                      | "ERROR"

header              = header-name ":" header-value
header-name         = 1*<any OCTET except CR or LF or ":">
header-value        = *<any OCTET except CR or LF or ":">

License

本规范根据 Creative Commons Attribution v3.0 许可协议授权。

引用

https://stomp.github.io/stomp-specification-1.2.html

  • 50
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昂的数字之旅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值