------------恢复内容开始------------
原文来自:https://xmpp.org/extensions/xep-0198.html,只翻译了技术方面的内容。
摘要:这个规范定义了一个XMPP协议扩展,用于在两个XMPP实体之间对XML流进行主动管理,包括stanza确认和流恢复的特性。
作者:Justin Karneges,Peter Saint-Andre,Joe Hildebrand,Fabio Forno,Dave Cridland,Matthew Wild
状态:草案。
注意:这里定义的协议是XMPP标准基金会的一个标准草案。我们鼓励实现这个协议,协议适合在生产系统中部署,但是在协议变成最终标准前可以对其进行一些修改。
类型:Standards Track(可参考RFC 2026)
版本:1.6(2018-07-25)
1.介绍
XMPP Core定义了XMPP使用的基本流XML技术(例如:流的建立和终止,包括认证和加密)。但是,核心XMPP规范不提供工具主动管理活跃的XML流。
流管理背后的基本概念是发起实体(客户端或服务端)和接收实体(服务器)能够交换“命令”来主动管理流。下面流管理的功能特别值得关注,因为它们有望提升网络可靠性和最终的用户体验:
Stanza确认:知道一个或一些列stanza是否被一端接收的能力。
流恢复:快速恢复已经被终止流的能力。
流管理在流的根等级使用简短XML元素实现了这些功能。这些元素不是XMPP场景里的stanza(例如:不是在http://wiki.jabbercn.org/RFC6120定义的
流管理在XML流等级中被使用,为了检查给定流下的TCP连接,建议使whitespace keepalives(RFC 6120),XMPP Ping(XEP-0199)或TCP keepalives。与流管理相比,高级消息处理(XEP-0079)和消息交换凭证(XEP-0184)定义了在多个流发送点对点的确认。这些工具在特殊场景中很有用,但是对于检查两个XMPP实体之间的直接流来说是不需要的。
注意:流管理可以用在服务器到服务器之间的流上,也可以用在客户端到服务器的流上。但是,这个规范只讨论客户端到服务器的流。同样的原则也适合于服务器到服务器的流。
2.流特性
服务器向客户端返回携带流特性的流头部,流特性包括一个由命名空间'urn:xmpp:sm:3'限定的
注意:客户端在与服务器进行身份认证并绑定资源前不能协商流管理,具体限制见下文。
Example 1:服务器发送伴随流特性的流头部
3.启用流管理
为了启用流管理,客户端发送
Example 2:客户端允许流管理
如果客户端希望被启用恢复流,必须要包含一个布尔类型的'resume'属性,默认为false。有关恢复一个前面会话的信息,请查看文档的恢复章节。
在接收到enable请求后,服务器必须回复一个携带'urn:xmpp:sm:3'命名空间的
Example 3:服务器允许流管理
接下来参与者就可以使用下面定义的流管理特性了。
如果服务器允许会话恢复,服务器必须包含一个设置为‘true’或‘1’的‘resume’属性。
Example 4:服务器允许会话恢复的流管理
客户端不能在认证前尝试协商流管理,例如:客户端不能在认证成功完成前发送
对于客户端到服务器的连接,客户端在完成资源绑定前不能尝试启用流管理,除非它正在恢复前一个会话。
服务将强制执行此命令,如果违反则响应
Example 5:客户端在绑定资源前尝试启动流管理时,服务器返回error
请注意,客户端最多只能尝试一次启动流管理,如果服务端接收到第二个
Example 6:如果客户端不止一次尝试启动流管理,服务器返回错误
4.确认
在启动流管理后,客户端或服务器可以在任何时候通过流发送ack元素,ack元素可以是下面的任意一种:
属性定义如下:
'h'属性标识了最后一个处理过的stanza(例如:服务器接收后确认的最后一个stanza)
定义:确认一个以前接收的ack元素表示从这之前的stanza都被服务器处理了。我们说的“已处理”是指服务器接收到了stanza的职责(例如,直接处理stanza,或传递stanza给一个本地实体,如同一服务器的另一个连接客户端,或者路由stanza到不同服务器的远程实体)。在stanza被服务器确认为处理之前,该stanza由发送方负责(例如,如果stanza从未被服务器确认为处理时,重新发送或生成一个错误)。
接收到
在流管理被启动或被请求启动的时间点,'h'的值从0开始。在第一个stanza被处理后'h'值被增加,并且在处理每个后续stanza后都加一。在不太可能的情况下,流管理会话期间处理的stanza数量超过了unsignedint数据类型的数据范围,范围在XML Schema Part 2有指定(最大可为4294967295),‘h’的值将从max-1被重置为0,而不是增加到max。
注意:每个实体为给定的流维持了两个计数器:一个是已发送stanza的计数器,一个是已经接收并处理('h')的计数器。实体的发送stanza计数器在发送
以下带注释的例子显示了客户端发送的消息,请求确认和stanza的确认。
Example 7:简单的stanza确认
当接收到一个
任何一方都可以在任何时候发送元素(例如:在收到确定数量stanza后,或在确定的时间后),即使没有从其它方接收到
当一方接收到一个元素,它应该保留返回的'h'属性值,这个值是当前流的上一个已被处理的发送类型stanza(并且放弃前一个值)的序列号。
如果一个流结束了并且没有在
服务器应该像处理发送到不可用资源的stanza一样处理未确认的stanza,或是返回错误给发送者,或是提交stanza给备用资源,或是提交stanza给离线存储。(注意:服务器应该根据延迟发送(XEP-0203)增加一个带有发送时间戳的延迟元素)
面向用户的客户端应该尝试在重新连接时静默重发stanza,或者通过适当的用户界面元素通知用户失败了。客户端还应该添加一个携带时间戳的延迟元素,以便保留原始的发送日期。否则接收方的客户端只能显示发送方的重新连接时间戳,这可能会使用户感到困惑。
因为未确认的stanza可能被另一方接收了,重新发送可能会导致重复,在本协议中没有办法避免这个结果,虽然使用在所有stanza上的id属性可以帮助接收方处理重复的stanza。
5.恢复
这在XML流在非预期情况下被终止。(例如:网络中断)在这种情况下,最好是快速恢复以前的流,而不是通过完成流建立,名单检索和状态广播的繁琐处理流程。
此外,此协议交换上一次连接接收到的最后一次stanza序列号,允许实体确定哪些stanza需要重传,哪些stanza不需要重传,从而通过重放消除重复。
为了使请求的流是可恢复的,当启用流管理时,客户端必须在
Example 8:客户端启动流管理
如果服务器允许恢复流,服务器必须包含一个设置为'true'或'1'的resume属性在
Example 9:服务端允许流恢复
定义:id属性定义了一个用于流管理的唯一标识符(SM-ID)。SM-ID必须由服务端生成。客户端必须把SM-ID当成是不透明的,因此不能赋予SM-ID任何语义。服务端可以将认为有用的任何信息编码到SM-ID中,例如连接客户端的完整JID
Example 10:服务器倾向于在特定位置重新连接
如果流意外终止,客户端会打开到服务器的TCP连接,事件顺序如下:
(1)断开连接后,客户端打开一个新的到服务器的TCP连接,倾向于使用location属性指定的地址(如果存在)。
(2)客户端发送启动流头部。
(3)服务端发送响应流头部。
(4)服务端发送流特性。
(5)客户端发送STARTTLS请求。
(6)服务端通知客户端进行TLS协商。
(7)双方完成TLS握手。(注意:在执行会话恢复和使用TLS时,建议使用TLS会话恢复(RFC-5077)来进一步优化XML流的恢复)
(8)客户端发送新的启动流头部。
(9)服务端发送响应流头部。
(10)服务端发送流特性,需要SASL协商并提供适当的SASL机制。(注意:如果服务器认为在TLS会话恢复过程中提供的信息已足够认证,服务端会提供SASL外部机制,详情可查阅draft-cridland-sasl-tls-sessions)
(11)双方完成SASL协商。
(12)客户端发送新的启动流头部。
(13)服务端发送响应流头部。
(14)服务端发送流特性,提供SM特性。
(15)客户端请求恢复前面一个流。
注意:事件的顺序可能与上面显示的不同,这取决于服务端何时提供SM特性,客户端是否选择STARTTLS等等。此外,在实践中,服务端到服务端通常不完成SASL协商,甚至不完成TLS协商。上述文本不修改在RFC 6120中关于流协商过程中的任何规则。但是,由于流管理被应用于stanza的交换(不是任何其它的XML元素),所以当另一方能够开始发送stanza时(而不是之前),服务端提供的SM特性是有意义的。See also Recommended Order of Stream Feature Negotiation (XEP-0170)
为了请求恢复前一个流,客户端发送一个限定'urn:xmpp:sm:3'命名空间的
Example 11:流恢复请求
如果服务端能够恢复上一个流,服务端必须返回一个
Example 12:流恢复
如果服务器不支持会话恢复,它必须返回一个
Example 13:流超时
在这些失败情况下,服务器应该允许客户端在此时绑定资源,而不是轻质客户端重启流协商过程和重新认证。
如果前一个流被恢复,并且此时服务端还有之前识别会话的流处于打开状态,服务器应该发送'conflict'流并且关闭流。
当一个会话被恢复后,各方按下列步骤进行:
序列值从上一个会话传递下来并且不会为新的流重置。
在接收到
双方应该重发在前一个会话期间未处理的任何stanza,这要依据对方报告的序列号。
重新连接的客户端不应该请求名单,因为在客户端断开连接所有名单的修改都会在流管理会话恢复后发送给客户端。
客户端不应该重新发送状态stanza来尝试恢复到以前的presence状态,因为服务器会保留此状态。
双方都不应该尝试重新建立状态信息。(例如 Service Discovery (XEP-0030)信息)
6.错误处理
如果关于
例子如下:
Example 15:服务端返回错误
流管理错误应该被认为是可恢复的,无用流管理可能会导致流的终止。
当一个远程实体确认它已处理的stanza数量比发送的stanza数量更多(通过发送一个很大的'h'值),本地实体因该生成一个undefined-condition流错误,它包含了一个
Example 16:由于一端确认的stanza比发送的更多
7.流关闭
一个明确的关闭流不同于一个未完成的流。如果客户端希望明确地关闭流并终止会话,它必须发送,便于服务端发送unavailable presence给客户端。
如果流没有明确地关闭,服务端应该认为流处于未完成的状态(即使客户端关闭了连接服务端的TCP连接)并且应该在有限的时间内维持客户端的会话权力。客户端可以在离开流的未完成状态前发送任何presence。
8.场景
下面的场景演示了流管理的几种不同用法,例子都是有一个客户端和一个服务端,但是流管理同样可以用在服务端和服务端之间的流。
8.1 基本的确认场景
流管理协议可以用来提升使用确认的可靠性,但没有能力恢复会话。一个基础的实现如下:
作为一个客户端,发送无属性的
作为一个服务端,忽略接收到的
当接收到一个
为这个流会话保留一个整数X,初始化为0。当准备发送stanza时,首先把stanza(与当前的X对应)放在未确认队列。然后通过网络发送携带
这种时间最低程度满足对方,并且允许对每个出站stanza进行基本的追踪。如果流连接中断,应用程序拥有一个未确认stanza队列,它可以适当地选择处理这些stanza。(例如:警告用户或重连后静默发送)
下面的示例演示了基本的确认(在这里客户端自动确认从服务端接收到的每个stanza,而不是先通过
首先,在认证和绑定资源后,客户端启动流管理。
Example 17:客户端启动流管理
服务端启动流管理。
Example 18:服务端启动流管理
客户端见过名单并马上发送一个
Example 19:(客户端发送stanza并且请求确认)
服务端处理客户端stanza(这里的是返回名单)并且发送一个元素来确认stanza的处理。
Example 20:服务端处理客户端的stanza并且确认处理了客户端的stanza
客户端选择确认从服务端接收到的stanza(虽然这里没必要这么做,因为服务端没有请求确认)。发送启动presence,并且马上发送
Example 21:客户端确认处理服务端的第一个stanza,发送stanza并且请求确认。
服务端立即发送一个来确认对stanza的处理,然后广播用户状态(包括如下所示的用户本身)。
Example 22:服务端确认第二个客户端stanza并且发送stanza
客户端确认服务端的第二个stanza并且发送一个出站消息,后面携带一个
Example 23:客户端确认服务端的第二个stanza,并且发送一个stanza,随后请求确认
服务端立即发送一个元素来确认第三个客户端stanza,然后将该stanza路由到远程联系人(这里没有显示是因为服务端没有想客户端发送stanza)
Example 24:(服务端确认第三个客户端stanza)
等等。
8.2 高效的确认场景
基本的确认场景是浪费资源的,因为客户端为每个stanza都请求确认。一个更有效的方式是定期请求确认(例如,每5个stanza)。这在下面的伪XML中有显示。
Example 25:(一个高效的会话)
特别是在移动网络,建议只有当实体有其它的数据要发送时才请求并且/或者发送确认,或者通过whitespace keepalive或XMPP ping(XEP-0199)代替。
9.安全考虑
综上所述,服务端必须在客户端通过身份认证后才允许客户端恢复流管理会话,这有助于防止会话劫持。
10.INNA注意事项
本XEP不需要和Internet Assigned Numbers Authority (IANA)交互。
11.XMPP注册注意事项
11.1 协议命名空间
该规范定义了如下的XML命名空间:
urn:xmpp:sm:3
XMPP Registrar 包含了上述命名空间在注册列表中(https://xmpp.org/registrar/namespaces.html),这在XMPP Registrar Function (XEP-0053) 中有定义。
11.2 协议版本控制
如果本规范中定义的协议修订后不完全兼容旧版本,则XMPP注册商应按照XEP-0053 Section 4的描述,增加命名空间末尾的版本号。
11.3 流特性
XMPP注册商在注册表中包含了'urn:xmpp:sm:3'的流特性,在https://xmpp.org/registrar/stream-features.html有定义。
12.XML文档结构
手机扫一扫
移动阅读更方便
你可能感兴趣的文章