Network Working Group                                P. Saint-Andre, Ed.
Request for Comments: 3921                    Jabber Software Foundation
Category: Standards Track                                   October 2004
        
Network Working Group                                P. Saint-Andre, Ed.
Request for Comments: 3921                    Jabber Software Foundation
Category: Standards Track                                   October 2004
        

Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence

可扩展消息和状态协议(XMPP):即时消息和状态

Status of this Memo

本备忘录的状况

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.

本文件规定了互联网社区的互联网标准跟踪协议,并要求进行讨论和提出改进建议。有关本协议的标准化状态和状态,请参考当前版本的“互联网官方协议标准”(STD 1)。本备忘录的分发不受限制。

Copyright Notice

版权公告

Copyright (C) The Internet Society (2004).

版权所有(C)互联网协会(2004年)。

Abstract

摘要

This memo describes extensions to and applications of the core features of the Extensible Messaging and Presence Protocol (XMPP) that provide the basic instant messaging (IM) and presence functionality defined in RFC 2779.

本备忘录描述了可扩展消息和状态协议(XMPP)核心功能的扩展和应用,该协议提供RFC 2779中定义的基本即时消息(IM)和状态功能。

Table of Contents

目录

   1.   Introduction . . . . . . . . . . . . . . . . . . . . . . . .   2
   2.   Syntax of XML Stanzas  . . . . . . . . . . . . . . . . . . .   4
   3.   Session Establishment  . . . . . . . . . . . . . . . . . . .  10
   4.   Exchanging Messages  . . . . . . . . . . . . . . . . . . . .  13
   5.   Exchanging Presence Information  . . . . . . . . . . . . . .  16
   6.   Managing Subscriptions . . . . . . . . . . . . . . . . . . .  26
   7.   Roster Management  . . . . . . . . . . . . . . . . . . . . .  27
   8.   Integration of Roster Items and Presence Subscriptions . . .  32
   9.   Subscription States  . . . . . . . . . . . . . . . . . . . .  56
   10.  Blocking Communication . . . . . . . . . . . . . . . . . . .  62
   11.  Server Rules for Handling XML Stanzas  . . . . . . . . . . .  85
   12.  IM and Presence Compliance Requirements  . . . . . . . . . .  88
   13.  Internationalization Considerations  . . . . . . . . . . . .  89
   14.  Security Considerations  . . . . . . . . . . . . . . . . . .  89
   15.  IANA Considerations  . . . . . . . . . . . . . . . . . . . .  90
   16.  References . . . . . . . . . . . . . . . . . . . . . . . . .  91
   A.   vCards . . . . . . . . . . . . . . . . . . . . . . . . . . .  93
   B.   XML Schemas. . . . . . . . . . . . . . . . . . . . . . . . .  93
   C.   Differences Between Jabber IM/Presence Protocols and XMPP. . 105
   Contributors . . . . . . . . . . . . . . . . . . . . . . . . . .  106
   Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . .  106
   Author's Address. . . . . . . . . . . . . . . . . . . . . . . . . 106
   Full Copyright Statement. . . . . . . . . . . . . . . . . . . . . 107
        
   1.   Introduction . . . . . . . . . . . . . . . . . . . . . . . .   2
   2.   Syntax of XML Stanzas  . . . . . . . . . . . . . . . . . . .   4
   3.   Session Establishment  . . . . . . . . . . . . . . . . . . .  10
   4.   Exchanging Messages  . . . . . . . . . . . . . . . . . . . .  13
   5.   Exchanging Presence Information  . . . . . . . . . . . . . .  16
   6.   Managing Subscriptions . . . . . . . . . . . . . . . . . . .  26
   7.   Roster Management  . . . . . . . . . . . . . . . . . . . . .  27
   8.   Integration of Roster Items and Presence Subscriptions . . .  32
   9.   Subscription States  . . . . . . . . . . . . . . . . . . . .  56
   10.  Blocking Communication . . . . . . . . . . . . . . . . . . .  62
   11.  Server Rules for Handling XML Stanzas  . . . . . . . . . . .  85
   12.  IM and Presence Compliance Requirements  . . . . . . . . . .  88
   13.  Internationalization Considerations  . . . . . . . . . . . .  89
   14.  Security Considerations  . . . . . . . . . . . . . . . . . .  89
   15.  IANA Considerations  . . . . . . . . . . . . . . . . . . . .  90
   16.  References . . . . . . . . . . . . . . . . . . . . . . . . .  91
   A.   vCards . . . . . . . . . . . . . . . . . . . . . . . . . . .  93
   B.   XML Schemas. . . . . . . . . . . . . . . . . . . . . . . . .  93
   C.   Differences Between Jabber IM/Presence Protocols and XMPP. . 105
   Contributors . . . . . . . . . . . . . . . . . . . . . . . . . .  106
   Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . .  106
   Author's Address. . . . . . . . . . . . . . . . . . . . . . . . . 106
   Full Copyright Statement. . . . . . . . . . . . . . . . . . . . . 107
        
1. Introduction
1. 介绍
1.1. Overview
1.1. 概述

The Extensible Messaging and Presence Protocol (XMPP) is a protocol for streaming XML [XML] elements in order to exchange messages and presence information in close to real time. The core features of XMPP are defined in Extensible Messaging and Presence Protocol (XMPP): Core [XMPP-CORE]. These features -- mainly XML streams, use of TLS and SASL, and the <message/>, <presence/>, and <iq/> children of the stream root -- provide the building blocks for many types of near-real-time applications, which may be layered on top of the core by sending application-specific data qualified by particular XML namespaces [XML-NAMES]. This memo describes extensions to and applications of the core features of XMPP that provide the basic functionality expected of an instant messaging (IM) and presence application as defined in RFC 2779 [IMP-REQS].

可扩展消息和状态协议(Extensible Messaging and Presence Protocol,XMPP)是一种用于流式传输XML[XML]元素的协议,用于近实时地交换消息和状态信息。XMPP的核心功能在可扩展消息和状态协议(XMPP)中定义:core[XMPP-core]。这些特性——主要是XML流、TLS和SASL的使用,以及流根的<message/>、<presence/>和<iq/>子项——为许多类型的近实时应用程序提供了构建块,这些应用程序可以通过发送特定XML名称空间[XML-NAMES]限定的特定于应用程序的数据来分层到核心之上。本备忘录描述了XMPP核心功能的扩展和应用,这些功能提供了RFC 2779[IMP-REQS]中定义的即时消息(IM)和状态应用程序的基本功能。

1.2. Requirements
1.2. 要求

For the purposes of this memo, the requirements of a basic instant messaging and presence application are defined by [IMP-REQS], which at a high level stipulates that a user must be able to complete the following use cases:

在本备忘录中,[IMP-REQS]定义了基本即时消息和状态应用程序的要求,该要求在较高级别上规定用户必须能够完成以下用例:

o Exchange messages with other users o Exchange presence information with other users o Manage subscriptions to and from other users o Manage items in a contact list (in XMPP this is called a "roster") o Block communications to or from specific other users

o 与其他用户交换消息o与其他用户交换状态信息o管理与其他用户之间的订阅o管理联系人列表中的项目(在XMPP中,这称为“花名册”)o阻止与特定其他用户之间的通信

Detailed definitions of these functionality areas are contained in [IMP-REQS], and the interested reader is directed to that document regarding the requirements addressed herein.

这些功能领域的详细定义包含在[IMP-REQS]中,感兴趣的读者可参考该文件中所述要求。

[IMP-REQS] also stipulates that presence services must be separable from instant messaging services; i.e., it must be possible to use the protocol to provide a presence service, an instant messaging service, or both. Although the text of this memo assumes that implementations and deployments will want to offer a unified instant messaging and presence service, there is no requirement that a service must offer both a presence service and an instant messaging service, and the protocol makes it possible to offer separate and distinct services for presence and for instant messaging.

[IMP-REQS]还规定状态服务必须与即时消息服务分开;i、 例如,必须能够使用该协议提供状态服务、即时消息服务或两者。尽管本备忘录的正文假定实施和部署将提供统一的即时消息和状态服务,但不要求服务必须同时提供状态服务和即时消息服务,该协议使得为状态和即时消息提供独立和独特的服务成为可能。

Note: While XMPP-based instant messaging and presence meets the requirements of [IMP-REQS], it was not designed explicitly with that specification in mind, since the base protocol evolved through an open development process within the Jabber open-source community before RFC 2779 was written. Note also that although protocols addressing many other functionality areas have been defined in the Jabber community, such protocols are not included in this memo because they are not required by [IMP-REQS].

注:尽管基于XMPP的即时消息和状态满足[IMP-REQS]的要求,但它的设计并未明确考虑到该规范,因为在编写RFC 2779之前,基本协议是通过Jabber开源社区内的开放开发过程演变而来的。还要注意的是,尽管Jabber社区已经定义了解决许多其他功能领域的协议,但此类协议并未包含在本备忘录中,因为[IMP-REQS]不需要这些协议。

1.3. Terminology
1.3. 术语

This memo inherits the terminology defined in [XMPP-CORE].

本备忘录继承了[XMPP-CORE]中定义的术语。

The capitalized key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, RFC 2119 [TERMS].

本文件中大写的关键词“必须”、“不得”、“必需”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照BCP 14、RFC 2119[条款]的规定进行解释。

2. Syntax of XML Stanzas
2. XML节的语法

The basic semantics and common attributes of XML stanzas qualified by the 'jabber:client' and 'jabber:server' namespaces are defined in [XMPP-CORE]. However, these namespaces also define various child elements, as well as values for the common 'type' attribute, that are specific to instant messaging and presence applications. Thus, before addressing particular "use cases" for such applications, we here further describe the syntax of XML stanzas, thereby supplementing the discussion in [XMPP-CORE].

[XMPP-CORE]中定义了由“jabber:client”和“jabber:server”名称空间限定的XML节的基本语义和公共属性。但是,这些名称空间还定义了各种子元素,以及特定于即时消息和状态应用程序的公共“type”属性的值。因此,在处理此类应用程序的特定“用例”之前,我们在此进一步描述XML节的语法,从而补充[XMPP-CORE]中的讨论。

2.1. Message Syntax
2.1. 消息语法

Message stanzas qualified by the 'jabber:client' or 'jabber:server' namespace are used to "push" information to another entity. Common uses in instant messaging applications include single messages, messages sent in the context of a chat conversation, messages sent in the context of a multi-user chat room, headlines and other alerts, and errors.

由“jabber:client”或“jabber:server”命名空间限定的消息节用于将信息“推送”到另一个实体。即时消息应用程序中的常见用途包括单个消息、在聊天对话上下文中发送的消息、在多用户聊天室上下文中发送的消息、标题和其他警报以及错误。

2.1.1. Types of Message
2.1.1. 信息类型

The 'type' attribute of a message stanza is RECOMMENDED; if included, it specifies the conversational context of the message, thus providing a hint regarding presentation (e.g., in a GUI). If included, the 'type' attribute MUST have one of the following values:

建议使用消息节的“type”属性;如果包含,它将指定消息的对话上下文,从而提供有关表示的提示(例如,在GUI中)。如果包含,则“type”属性必须具有以下值之一:

o chat -- The message is sent in the context of a one-to-one chat conversation. A compliant client SHOULD present the message in an interface enabling one-to-one chat between the two parties, including an appropriate conversation history.

o chat——消息在一对一的聊天对话中发送。合规客户机应在接口中显示消息,以实现双方之间的一对一聊天,包括适当的对话历史记录。

o error -- An error has occurred related to a previous message sent by the sender (for details regarding stanza error syntax, refer to [XMPP-CORE]). A compliant client SHOULD present an appropriate interface informing the sender of the nature of the error.

o 错误——发生了与发送方发送的上一条消息相关的错误(有关节错误语法的详细信息,请参阅[XMPP-CORE])。合规客户机应提供适当的接口,告知发送方错误的性质。

o groupchat -- The message is sent in the context of a multi-user chat environment (similar to that of [IRC]). A compliant client SHOULD present the message in an interface enabling many-to-many chat between the parties, including a roster of parties in the chatroom and an appropriate conversation history. Full definition of XMPP-based groupchat protocols is out of scope for this memo.

o groupchat——消息是在多用户聊天环境中发送的(类似于[IRC])。合规客户机应在一个界面中显示消息,该界面允许各方之间进行多对多聊天,包括聊天室中的各方名册和适当的对话历史记录。基于XMPP的groupchat协议的完整定义超出了本备忘录的范围。

o headline -- The message is probably generated by an automated service that delivers or broadcasts content (news, sports, market information, RSS feeds, etc.). No reply to the message is expected, and a compliant client SHOULD present the message in an

o 标题——消息可能是由提供或广播内容(新闻、体育、市场信息、RSS提要等)的自动化服务生成的。不需要回复消息,符合要求的客户端应以

interface that appropriately differentiates the message from standalone messages, chat sessions, or groupchat sessions (e.g., by not providing the recipient with the ability to reply).

将邮件与独立邮件、聊天会话或群组聊天会话进行适当区分的界面(例如,不向收件人提供回复功能)。

o normal -- The message is a single message that is sent outside the context of a one-to-one conversation or groupchat, and to which it is expected that the recipient will reply. A compliant client SHOULD present the message in an interface enabling the recipient to reply, but without a conversation history.

o 正常--消息是在一对一对话或groupchat上下文之外发送的单个消息,预期收件人将回复该消息。兼容客户端应在接口中显示消息,使收件人能够回复,但没有会话历史记录。

An IM application SHOULD support all of the foregoing message types; if an application receives a message with no 'type' attribute or the application does not understand the value of the 'type' attribute provided, it MUST consider the message to be of type "normal" (i.e., "normal" is the default). The "error" type MUST be generated only in response to an error related to a message received from another entity.

IM应用程序应支持上述所有消息类型;如果应用程序接收到没有“type”属性的消息,或者应用程序不理解所提供的“类型”属性的值,则必须将消息视为“正常”类型(即“正常”)为默认值。“错误”类型只能在响应与从另一个实体接收的消息相关的错误时生成。

Although the 'type' attribute is OPTIONAL, it is considered polite to mirror the type in any replies to a message; furthermore, some specialized applications (e.g., a multi-user chat service) MAY at their discretion enforce the use of a particular message type (e.g., type='groupchat').

虽然“type”属性是可选的,但在对消息的任何回复中镜像该类型被认为是礼貌的;此外,一些专用应用程序(例如,多用户聊天服务)可以自行决定强制使用特定的消息类型(例如,type='groupchat')。

2.1.2. Child Elements
2.1.2. 子元素

As described under extended namespaces (Section 2.4), a message stanza MAY contain any properly-namespaced child element.

如扩展名称空间(第2.4节)所述,消息节可以包含任何正确命名的子元素。

In accordance with the default namespace declaration, by default a message stanza is qualified by the 'jabber:client' or 'jabber:server' namespace, which defines certain allowable children of message stanzas. If the message stanza is of type "error", it MUST include an <error/> child; for details, see [XMPP-CORE]. Otherwise, the message stanza MAY contain any of the following child elements without an explicit namespace declaration:

根据缺省名称空间声明,缺省情况下,消息节由“jabber:client”或“jabber:server”名称空间限定,后者定义消息节的某些允许子级。如果消息节类型为“error”,则它必须包含<error/>子节;有关详细信息,请参阅[XMPP-CORE]。否则,message节可能包含以下任何子元素,而无显式命名空间声明:

   1.  <subject/>
   2.  <body/>
   3.  <thread/>
        
   1.  <subject/>
   2.  <body/>
   3.  <thread/>
        
2.1.2.1. Subject
2.1.2.1. 主题
   The <subject/> element contains human-readable XML character data
   that specifies the topic of the message.  The <subject/> element MUST
   NOT possess any attributes, with the exception of the 'xml:lang'
   attribute.  Multiple instances of the <subject/> element MAY be
   included for the purpose of providing alternate versions of the same
        
   The <subject/> element contains human-readable XML character data
   that specifies the topic of the message.  The <subject/> element MUST
   NOT possess any attributes, with the exception of the 'xml:lang'
   attribute.  Multiple instances of the <subject/> element MAY be
   included for the purpose of providing alternate versions of the same
        

subject, but only if each instance possesses an 'xml:lang' attribute with a distinct language value. The <subject/> element MUST NOT contain mixed content (as defined in Section 3.2.2 of [XML]).

主题,但前提是每个实例都拥有具有不同语言值的“xml:lang”属性。<subject/>元素不得包含混合内容(如[XML]第3.2.2节所定义)。

2.1.2.2. Body
2.1.2.2. 身体

The <body/> element contains human-readable XML character data that specifies the textual contents of the message; this child element is normally included but is OPTIONAL. The <body/> element MUST NOT possess any attributes, with the exception of the 'xml:lang' attribute. Multiple instances of the <body/> element MAY be included but only if each instance possesses an 'xml:lang' attribute with a distinct language value. The <body/> element MUST NOT contain mixed content (as defined in Section 3.2.2 of [XML]).

<body/>元素包含人类可读的XML字符数据,用于指定消息的文本内容;此子元素通常包括在内,但是可选的。<body/>元素不能拥有任何属性,但“xml:lang”属性除外。可以包含<body/>元素的多个实例,但前提是每个实例都具有具有不同语言值的“xml:lang”属性。<body/>元素不得包含混合内容(如[XML]第3.2.2节所定义)。

2.1.2.3. Thread
2.1.2.3. 线

The <thread/> element contains non-human-readable XML character data specifying an identifier that is used for tracking a conversation thread (sometimes referred to as an "instant messaging session") between two entities. The value of the <thread/> element is generated by the sender and SHOULD be copied back in any replies. If used, it MUST be unique to that conversation thread within the stream and MUST be consistent throughout that conversation (a client that receives a message from the same full JID but with a different thread ID MUST assume that the message in question exists outside the context of the existing conversation thread). The use of the <thread/> element is OPTIONAL and is not used to identify individual messages, only conversations. A message stanza MUST NOT contain more than one <thread/> element. The <thread/> element MUST NOT possess any attributes. The value of the <thread/> element MUST be treated as opaque by entities; no semantic meaning may be derived from it, and only exact comparisons may be made against it. The <thread/> element MUST NOT contain mixed content (as defined in Section 3.2.2 of [XML]).

<thread/>元素包含非人类可读的XML字符数据,指定用于跟踪两个实体之间的对话线程(有时称为“即时消息会话”)的标识符。<thread/>元素的值由发送方生成,并应在任何回复中复制回来。如果使用,它必须是流中该对话线程所独有的,并且必须在整个对话过程中保持一致(从同一完整JID接收消息但具有不同线程ID的客户端必须假定所讨论的消息存在于现有对话线程的上下文之外)。<thread/>元素的使用是可选的,不用于标识单个消息,仅用于标识会话。消息节不能包含多个<thread/>元素。<thread/>元素不能具有任何属性。<thread/>元素的值必须被实体视为不透明;它不可能产生任何语义,只能与之进行精确的比较。<thread/>元素不得包含混合内容(如[XML]第3.2.2节所定义)。

2.2. Presence Syntax
2.2. 存在语法

Presence stanzas are used qualified by the 'jabber:client' or 'jabber:server' namespace to express an entity's current network availability (offline or online, along with various sub-states of the latter and optional user-defined descriptive text), and to notify other entities of that availability. Presence stanzas are also used to negotiate and manage subscriptions to the presence of other entities.

状态节由“jabber:client”或“jabber:server”命名空间限定,用于表示实体的当前网络可用性(离线或在线,以及后者的各种子状态和可选的用户定义的描述性文本),并通知其他实体该可用性。状态节还用于协商和管理对其他实体状态的订阅。

2.2.1. Types of Presence
2.2.1. 存在类型

The 'type' attribute of a presence stanza is OPTIONAL. A presence stanza that does not possess a 'type' attribute is used to signal to the server that the sender is online and available for communication. If included, the 'type' attribute specifies a lack of availability, a request to manage a subscription to another entity's presence, a request for another entity's current presence, or an error related to a previously-sent presence stanza. If included, the 'type' attribute MUST have one of the following values:

状态节的“type”属性是可选的。不具有“type”属性的状态节用于向服务器发出信号,表明发送者已联机并可用于通信。如果包含,则“type”属性指定缺乏可用性、管理对另一实体存在的订阅的请求、对另一实体当前存在的请求或与先前发送的存在节相关的错误。如果包含,则“type”属性必须具有以下值之一:

o unavailable -- Signals that the entity is no longer available for communication.

o 不可用--表示实体不再可用于通信。

o subscribe -- The sender wishes to subscribe to the recipient's presence.

o subscribe——发送者希望订阅接收者的状态。

o subscribed -- The sender has allowed the recipient to receive their presence.

o 已订阅--发件人已允许收件人接收他们的状态。

o unsubscribe -- The sender is unsubscribing from another entity's presence.

o 取消订阅--发件人正在取消订阅另一个实体的状态。

o unsubscribed -- The subscription request has been denied or a previously-granted subscription has been cancelled.

o unsubscribed--订阅请求已被拒绝或先前授予的订阅已被取消。

o probe -- A request for an entity's current presence; SHOULD be generated only by a server on behalf of a user.

o 探测——对实体当前存在的请求;应仅由服务器代表用户生成。

o error -- An error has occurred regarding processing or delivery of a previously-sent presence stanza.

o 错误--处理或传递以前发送的状态节时出错。

For detailed information regarding presence semantics and the subscription model used in the context of XMPP-based instant messaging and presence applications, refer to Exchanging Presence Information (Section 5) and Managing Subscriptions (Section 6).

有关基于XMPP的即时消息和状态应用程序上下文中使用的状态语义和订阅模型的详细信息,请参阅交换状态信息(第5节)和管理订阅(第6节)。

2.2.2. Child Elements
2.2.2. 子元素

As described under extended namespaces (Section 2.4), a presence stanza MAY contain any properly-namespaced child element.

如扩展名称空间(第2.4节)所述,状态节可以包含任何正确命名的子元素。

In accordance with the default namespace declaration, by default a presence stanza is qualified by the 'jabber:client' or 'jabber:server' namespace, which defines certain allowable children of presence stanzas. If the presence stanza is of type "error", it MUST include an <error/> child; for details, see [XMPP-CORE]. If the presence stanza possesses no 'type' attribute, it MAY contain any of

根据默认名称空间声明,默认情况下,状态节由“jabber:client”或“jabber:server”名称空间限定,该名称空间定义了状态节的某些允许子级。如果存在节的类型为“error”,则必须包含<error/>子节;有关详细信息,请参阅[XMPP-CORE]。如果presence节不具有“type”属性,则它可以包含以下任何属性:

the following child elements (note that the <status/> child MAY be sent in a presence stanza of type "unavailable" or, for historical reasons, "subscribe"):

以下子元素(注意,<status/>子元素可以以“不可用”类型的存在节发送,或者出于历史原因,“订阅”):

   1.  <show/>
   2.  <status/>
   3.  <priority/>
        
   1.  <show/>
   2.  <status/>
   3.  <priority/>
        
2.2.2.1. Show
2.2.2.1. 显示

The OPTIONAL <show/> element contains non-human-readable XML character data that specifies the particular availability status of an entity or specific resource. A presence stanza MUST NOT contain more than one <show/> element. The <show/> element MUST NOT possess any attributes. If provided, the XML character data value MUST be one of the following (additional availability types could be defined through a properly-namespaced child element of the presence stanza):

可选的<show/>元素包含非人类可读的XML字符数据,用于指定实体或特定资源的特定可用性状态。状态节不能包含多个<show/>元素。<show/>元素不能具有任何属性。如果提供了XML字符数据值,则该值必须是以下值之一(可以通过presence节的正确命名空间子元素定义其他可用性类型):

o away -- The entity or resource is temporarily away.

o 离开——实体或资源暂时离开。

o chat -- The entity or resource is actively interested in chatting.

o 聊天——实体或资源对聊天非常感兴趣。

o dnd -- The entity or resource is busy (dnd = "Do Not Disturb").

o dnd——实体或资源正忙(dnd=“请勿打扰”)。

o xa -- The entity or resource is away for an extended period (xa = "eXtended Away").

o xa——实体或资源离开一段较长的时间(xa=“extended away”)。

If no <show/> element is provided, the entity is assumed to be online and available.

如果未提供<show/>元素,则假定实体在线且可用。

2.2.2.2. Status
2.2.2.2. 地位

The OPTIONAL <status/> element contains XML character data specifying a natural-language description of availability status. It is normally used in conjunction with the show element to provide a detailed description of an availability state (e.g., "In a meeting"). The <status/> element MUST NOT possess any attributes, with the exception of the 'xml:lang' attribute. Multiple instances of the <status/> element MAY be included but only if each instance possesses an 'xml:lang' attribute with a distinct language value.

可选的<status/>元素包含指定可用性状态的自然语言描述的XML字符数据。它通常与show元素结合使用,以提供可用性状态的详细描述(例如,“在会议中”)。<status/>元素不能拥有任何属性,但“xml:lang”属性除外。可以包含<status/>元素的多个实例,但前提是每个实例都具有具有不同语言值的“xml:lang”属性。

2.2.2.3. Priority
2.2.2.3. 优先事项

The OPTIONAL <priority/> element contains non-human-readable XML character data that specifies the priority level of the resource. The value MUST be an integer between -128 and +127. A presence stanza MUST NOT contain more than one <priority/> element. The <priority/> element MUST NOT possess any attributes. If no priority is provided,

可选的<priority/>元素包含非人类可读的XML字符数据,用于指定资源的优先级。该值必须是介于-128和+127之间的整数。状态节不能包含多个<priority/>元素。<priority/>元素不能具有任何属性。如果没有提供优先权,

a server SHOULD consider the priority to be zero. For information regarding the semantics of priority values in stanza routing within instant messaging and presence applications, refer to Server Rules for Handling XML Stanzas (Section 11).

服务器应该考虑优先级为零。有关即时消息和状态应用程序中节路由中优先级值语义的信息,请参阅处理XML节的服务器规则(第11节)。

2.3. IQ Syntax
2.3. IQ语法

IQ stanzas provide a structured request-response mechanism. The basic semantics of that mechanism (e.g., that the 'id' attribute is REQUIRED) are defined in [XMPP-CORE], whereas the specific semantics required to complete particular use cases are defined in all cases by an extended namespace (Section 2.4) (note that the 'jabber:client' and 'jabber:server' namespaces do not define any children of IQ stanzas other than the common <error/>). This memo defines two such extended namespaces, one for Roster Management (Section 7) and the other for Blocking Communication (Section 10); however, an IQ stanza MAY contain structured information qualified by any extended namespace.

IQ节提供了一种结构化的请求-响应机制。该机制的基本语义(例如,“id”属性是必需的)在[XMPP-CORE]中定义,而完成特定用例所需的特定语义在所有情况下都由扩展名称空间定义(第2.4节)(请注意,'jabber:client'和'jabber:server'名称空间未定义IQ节的任何子项,除了常见的<error/>)。本备忘录定义了两个此类扩展名称空间,一个用于名册管理(第7节),另一个用于阻止通信(第10节);但是,IQ节可能包含任何扩展名称空间限定的结构化信息。

2.4. Extended Namespaces
2.4. 扩展名称空间

While the three XML stanza kinds defined in the "jabber:client" or "jabber:server" namespace (along with their attributes and child elements) provide a basic level of functionality for messaging and presence, XMPP uses XML namespaces to extend the stanzas for the purpose of providing additional functionality. Thus a message or presence stanza MAY contain one or more optional child elements specifying content that extends the meaning of the message (e.g., an XHTML-formatted version of the message body), and an IQ stanza MAY contain one such child element. This child element MAY have any name and MUST possess an 'xmlns' namespace declaration (other than "jabber:client", "jabber:server", or "http://etherx.jabber.org/streams") that defines all data contained within the child element.

虽然在“jabber:client”或“jabber:server”名称空间中定义的三种XML节类型(以及它们的属性和子元素)为消息传递和状态提供了基本级别的功能,但XMPP使用XML名称空间扩展节以提供附加功能。因此,消息或存在节可以包含一个或多个可选子元素,指定扩展消息含义的内容(例如,消息正文的XHTML格式版本),并且IQ节可以包含一个这样的子元素。此子元素可以有任何名称,并且必须具有“xmlns”命名空间声明(除了“jabber:client”、“jabber:server”或http://etherx.jabber.org/streams)定义子元素中包含的所有数据。

Support for any given extended namespace is OPTIONAL on the part of any implementation (aside from the extended namespaces defined herein). If an entity does not understand such a namespace, the entity's expected behavior depends on whether the entity is (1) the recipient or (2) an entity that is routing the stanza to the recipient:

对任何给定扩展名称空间的支持在任何实现中都是可选的(本文定义的扩展名称空间除外)。如果实体不理解这样的名称空间,则该实体的预期行为取决于该实体是(1)收件人还是(2)将节路由到收件人的实体:

Recipient: If a recipient receives a stanza that contains a child element it does not understand, it SHOULD ignore that specific XML data, i.e., it SHOULD not process it or present it to a user or associated application (if any). In particular:

接收者:如果接收者接收到包含其不理解的子元素的节,则应忽略该特定XML数据,即,不应处理该数据或将其呈现给用户或关联应用程序(如果有)。特别地:

* If an entity receives a message or presence stanza that contains XML data qualified by a namespace it does not understand, the portion of the stanza that is in the unknown namespace SHOULD be ignored.

* 如果实体接收到包含由其不理解的命名空间限定的XML数据的消息或状态节,则应忽略未知命名空间中的节部分。

* If an entity receives a message stanza whose only child element is qualified by a namespace it does not understand, it MUST ignore the entire stanza.

* 如果一个实体接收到一个消息节,其唯一的子元素由它不理解的名称空间限定,那么它必须忽略整个节。

* If an entity receives an IQ stanza of type "get" or "set" containing a child element qualified by a namespace it does not understand, the entity SHOULD return an IQ stanza of type "error" with an error condition of <service-unavailable/>.

* 如果实体接收到类型为“get”或“set”的IQ节,其中包含由其不理解的命名空间限定的子元素,则该实体应返回类型为“error”的IQ节,错误条件为<service unavailable/>。

Router: If a routing entity (usually a server) handles a stanza that contains a child element it does not understand, it SHOULD ignore the associated XML data by passing it on untouched to the recipient.

路由器:如果路由实体(通常是服务器)处理包含它不理解的子元素的节,它应该忽略关联的XML数据,将其原封不动地传递给收件人。

3. Session Establishment
3. 会议设立

Most instant messaging and presence applications based on XMPP are implemented via a client-server architecture that requires a client to establish a session on a server in order to engage in the expected instant messaging and presence activities. However, there are several pre-conditions that MUST be met before a client can establish an instant messaging and presence session. These are:

大多数基于XMPP的即时消息和状态应用程序都是通过客户机-服务器体系结构实现的,该体系结构要求客户机在服务器上建立会话,以便参与预期的即时消息和状态活动。但是,在客户端可以建立即时消息和状态会话之前,必须满足几个先决条件。这些是:

1. Stream Authentication -- a client MUST complete stream authentication as documented in [XMPP-CORE] before attempting to establish a session or send any XML stanzas. 2. Resource Binding -- after completing stream authentication, a client MUST bind a resource to the stream so that the client's address is of the form <user@domain/resource>, after which the entity is now said to be a "connected resource" in the terminology of [XMPP-CORE].

1. 流身份验证——在尝试建立会话或发送任何XML节之前,客户端必须完成[XMPP-CORE]中记录的流身份验证。2.资源绑定——完成流身份验证后,客户机必须将资源绑定到流,以便客户机的地址为<user@domain/resource>,之后该实体现在被称为[XMPP-CORE]术语中的“连接资源”。

If a server supports sessions, it MUST include a <session/> element qualified by the 'urn:ietf:params:xml:ns:xmpp-session' namespace in the stream features it advertises to a client after the completion of stream authentication as defined in [XMPP-CORE]:

如果服务器支持会话,则必须在完成[xmpp-CORE]中定义的流身份验证后,在向客户端播发的流功能中包含一个由“urn:ietf:params:xml:ns:xmpp session”命名空间限定的<session/>元素:

Server advertises session establishment feature to client:

服务器向客户端播发会话建立功能:

   <stream:stream
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       id='c2s_345'
       from='example.com'
       version='1.0'>
   <stream:features>
     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
   </stream:features>
        
   <stream:stream
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       id='c2s_345'
       from='example.com'
       version='1.0'>
   <stream:features>
     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
   </stream:features>
        

Upon being so informed that session establishment is required (and after completing resource binding), the client MUST establish a session if it desires to engage in instant messaging and presence functionality; it completes this step by sending to the server an IQ stanza of type "set" containing an empty <session/> child element qualified by the 'urn:ietf:params:xml:ns:xmpp-session' namespace:

在被告知需要建立会话后(以及在完成资源绑定后),如果客户端希望参与即时消息和状态功能,则必须建立会话;它通过向服务器发送一个类型为“set”的IQ节来完成此步骤,该IQ节包含一个由“urn:ietf:params:xml:ns:xmpp session”命名空间限定的空<session/>子元素:

Step 1: Client requests session with server:

步骤1:客户端请求与服务器的会话:

   <iq to='example.com'
       type='set'
       id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
   </iq>
        
   <iq to='example.com'
       type='set'
       id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
   </iq>
        

Step 2: Server informs client that session has been created:

步骤2:服务器通知客户端已创建会话:

   <iq from='example.com'
       type='result'
       id='sess_1'/>
        
   <iq from='example.com'
       type='result'
       id='sess_1'/>
        

Upon establishing a session, a connected resource (in the terminology of [XMPP-CORE]) is said to be an "active resource".

在建立会话时,连接的资源(用[XMPP-CORE]术语)被称为“活动资源”。

Several error conditions are possible. For example, the server may encounter an internal condition that prevents it from creating the session, the username or authorization identity may lack permissions to create a session, or there may already be an active resource associated with a resource identifier of the same name.

可能存在几种错误情况。例如,服务器可能遇到阻止其创建会话的内部条件,用户名或授权标识可能缺少创建会话的权限,或者可能已经存在与同名资源标识符关联的活动资源。

If the server encounters an internal condition that prevents it from creating the session, it MUST return an error.

如果服务器遇到阻止其创建会话的内部条件,则必须返回错误。

Step 2 (alt): Server responds with error (internal server error):

步骤2(alt):服务器响应错误(内部服务器错误):

   <iq from='example.com' type='error' id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
     <error type='wait'>
       <internal-server-error
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq from='example.com' type='error' id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
     <error type='wait'>
       <internal-server-error
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        

If the username or resource is not allowed to create a session, the server MUST return an error (e.g., forbidden).

如果不允许用户名或资源创建会话,服务器必须返回错误(例如,禁止)。

Step 2 (alt): Server responds with error (username or resource not allowed to create session):

步骤2(alt):服务器响应错误(不允许用户名或资源创建会话):

   <iq from='example.com' type='error' id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
     <error type='auth'>
       <forbidden
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq from='example.com' type='error' id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
     <error type='auth'>
       <forbidden
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        

If there is already an active resource of the same name, the server MUST either (1) terminate the active resource and allow the newly-requested session, or (2) disallow the newly-requested session and maintain the active resource. Which of these the server does is up to the implementation, although it is RECOMMENDED to implement case #1. In case #1, the server SHOULD send a <conflict/> stream error to the active resource, terminate the XML stream and underlying TCP connection for the active resource, and return a IQ stanza of type "result" (indicating success) to the newly-requested session. In case #2, the server SHOULD send a <conflict/> stanza error to the newly-requested session but maintain the XML stream for that connection so that the newly-requested session has an opportunity to negotiate a non-conflicting resource identifier before sending another request for session establishment.

如果已经存在同名的活动资源,服务器必须(1)终止活动资源并允许新请求的会话,或(2)禁止新请求的会话并维护活动资源。服务器执行哪种操作取决于实现,尽管建议实现案例1。在案例#1中,服务器应向活动资源发送<conflict/>流错误,终止活动资源的XML流和底层TCP连接,并向新请求的会话返回类型为“result”(表示成功)的IQ节。在第2种情况下,服务器应向新请求的会话发送<conflict/>节错误,但应维护该连接的XML流,以便新请求的会话在发送另一个会话建立请求之前有机会协商非冲突的资源标识符。

Step 2 (alt): Server informs existing active resource of resource conflict (case #1):

步骤2(alt):服务器将资源冲突通知现有活动资源(案例1):

   <stream:error>
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
   </stream:error>
   </stream:stream>
        
   <stream:error>
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
   </stream:error>
   </stream:stream>
        

Step 2 (alt): Server informs newly-requested session of resource conflict (case #2):

步骤2(alt):服务器通知新请求的会话资源冲突(案例2):

   <iq from='example.com' type='error' id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
     <error type='cancel'>
       <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq from='example.com' type='error' id='sess_1'>
     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
     <error type='cancel'>
       <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        

After establishing a session, a client SHOULD send initial presence and request its roster as described below, although these actions are OPTIONAL.

建立会话后,客户机应发送初始状态并请求其名册,如下所述,尽管这些操作是可选的。

Note: Before allowing the creation of instant messaging and presence sessions, a server MAY require prior account provisioning. Possible methods for account provisioning include account creation by a server administrator as well as in-band account registration using the 'jabber:iq:register' namespace; the latter method is out of scope for this memo, but is documented in [JEP-0077], published by the Jabber Software Foundation [JSF].

注意:在允许创建即时消息和状态会话之前,服务器可能需要事先设置帐户。帐户设置的可能方法包括由服务器管理员创建帐户以及使用“jabber:iq:register”命名空间进行带内帐户注册;后一种方法超出了该备忘录的范围,但在JabbFieldFrase[JSF]发布的[JEP-0777 ]中有记载。

4. Exchanging Messages
4. 交换信息

Exchanging messages is a basic use of XMPP and is brought about when a user generates a message stanza that is addressed to another entity. As defined under Server Rules for Handling XML Stanzas (Section 11), the sender's server is responsible for delivering the message to the intended recipient (if the recipient is on the same server) or for routing the message to the recipient's server (if the recipient is on a different server).

交换消息是XMPP的一个基本用途,当用户生成一个发往另一个实体的消息节时,就会产生交换消息。根据处理XML节的服务器规则(第11节)的定义,发送方服务器负责将消息传递给预期的收件人(如果收件人在同一台服务器上)或将消息路由到收件人服务器(如果收件人在不同的服务器上)。

For information regarding the syntax of message stanzas as well as their defined attributes and child elements, refer to Message Syntax (Section 2.1).

有关消息节的语法及其定义的属性和子元素的信息,请参阅消息语法(第2.1节)。

4.1. Specifying an Intended Recipient
4.1. 指定预期收件人
   An instant messaging client SHOULD specify an intended recipient for
   a message by providing the JID of an entity other than the sender in
   the 'to' attribute of the <message/> stanza.  If the message is being
   sent in reply to a message previously received from an address of the
   form <user@domain/resource> (e.g., within the context of a chat
   session), the value of the 'to' address SHOULD be of the form
   <user@domain/resource> rather than of the form <user@domain> unless
   the sender has knowledge (via presence) that the intended recipient's
   resource is no longer available.  If the message is being sent
        
   An instant messaging client SHOULD specify an intended recipient for
   a message by providing the JID of an entity other than the sender in
   the 'to' attribute of the <message/> stanza.  If the message is being
   sent in reply to a message previously received from an address of the
   form <user@domain/resource> (e.g., within the context of a chat
   session), the value of the 'to' address SHOULD be of the form
   <user@domain/resource> rather than of the form <user@domain> unless
   the sender has knowledge (via presence) that the intended recipient's
   resource is no longer available.  If the message is being sent
        

outside the context of any existing chat session or received message, the value of the 'to' address SHOULD be of the form <user@domain> rather than of the form <user@domain/resource>.

在任何现有聊天会话或接收到的消息的上下文之外,“收件人”地址的值应为以下形式<user@domain>而不是形式<user@domain/资源>。

4.2. Specifying a Message Type
4.2. 指定消息类型

As noted, it is RECOMMENDED for a message stanza to possess a 'type' attribute whose value captures the conversational context (if any) of the message (see Type (Section 2.1.1)).

如前所述,建议消息节具有一个“type”属性,该属性的值捕获消息的会话上下文(如果有)(参见type(第2.1.1节))。

The following example shows a valid value of the 'type' attribute:

以下示例显示了“type”属性的有效值:

Example: A message of a defined type:

示例:定义类型的消息:

   <message
       to='romeo@example.net'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>Wherefore art thou, Romeo?</body>
   </message>
        
   <message
       to='romeo@example.net'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>Wherefore art thou, Romeo?</body>
   </message>
        
4.3. Specifying a Message Body
4.3. 指定消息正文

A message stanza MAY (and often will) contain a child <body/> element whose XML character data specifies the primary meaning of the message (see Body (Section 2.1.2.2)).

消息节可能(并且通常会)包含一个子<body/>元素,其XML字符数据指定消息的主要含义(参见body(第2.1.2.2节))。

Example: A message with a body:

示例:带有正文的消息:

   <message
       to='romeo@example.net'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>Wherefore art thou, Romeo?</body>
     <body xml:lang='cz'>Pro&#x010D;e&#x017D; jsi ty, Romeo?</body>
   </message>
        
   <message
       to='romeo@example.net'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>Wherefore art thou, Romeo?</body>
     <body xml:lang='cz'>Pro&#x010D;e&#x017D; jsi ty, Romeo?</body>
   </message>
        
4.4. Specifying a Message Subject
4.4. 指定消息主题

A message stanza MAY contain one or more child <subject/> elements specifying the topic of the message (see Subject (Section 2.1.2.1)).

消息节可能包含一个或多个子<subject/>元素,用于指定消息的主题(参见主题(第2.1.2.1节))。

Example: A message with a subject:

示例:带有主题的消息:

   <message
       to='romeo@example.net'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <subject>I implore you!</subject>
     <subject
         xml:lang='cz'>&#x00DA;p&#x011B;nliv&#x011B; prosim!</subject>
     <body>Wherefore art thou, Romeo?</body>
     <body xml:lang='cz'>Pro&#x010D;e&#x017D; jsi ty, Romeo?</body>
   </message>
        
   <message
       to='romeo@example.net'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <subject>I implore you!</subject>
     <subject
         xml:lang='cz'>&#x00DA;p&#x011B;nliv&#x011B; prosim!</subject>
     <body>Wherefore art thou, Romeo?</body>
     <body xml:lang='cz'>Pro&#x010D;e&#x017D; jsi ty, Romeo?</body>
   </message>
        
4.5. Specifying a Conversation Thread
4.5. 指定对话线程

A message stanza MAY contain a child <thread/> element specifying the conversation thread in which the message is situated, for the purpose of tracking the conversation (see Thread (Section 2.1.2.3)).

消息节可能包含一个子<thread/>元素,用于指定消息所在的对话线程,以便跟踪对话(参见线程(第2.1.2.3节))。

Example: A threaded conversation:

示例:线程化对话:

   <message
       to='romeo@example.net/orchard'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>Art thou not Romeo, and a Montague?</body>
     <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
   </message>
        
   <message
       to='romeo@example.net/orchard'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>Art thou not Romeo, and a Montague?</body>
     <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
   </message>
        
   <message
       to='juliet@example.com/balcony'
       from='romeo@example.net/orchard'
       type='chat'
       xml:lang='en'>
     <body>Neither, fair saint, if either thee dislike.</body>
     <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
   </message>
        
   <message
       to='juliet@example.com/balcony'
       from='romeo@example.net/orchard'
       type='chat'
       xml:lang='en'>
     <body>Neither, fair saint, if either thee dislike.</body>
     <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
   </message>
        
   <message
       to='romeo@example.net/orchard'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>How cam'st thou hither, tell me, and wherefore?</body>
     <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
   </message>
        
   <message
       to='romeo@example.net/orchard'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>How cam'st thou hither, tell me, and wherefore?</body>
     <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
   </message>
        
5. Exchanging Presence Information
5. 交换状态信息

Exchanging presence information is made relatively straightforward within XMPP by using presence stanzas. However, we see here a contrast to the handling of messages: although a client MAY send directed presence information to another entity by including a 'to' address, normally presence notifications (i.e., presence stanzas with no 'type' or of type "unavailable" and with no 'to' address) are sent from a client to its server and then broadcasted by the server to any entities that are subscribed to the presence of the sending entity (in the terminology of RFC 2778 [IMP-MODEL], these entities are subscribers). This broadcast model does not apply to subscription-related presence stanzas or presence stanzas of type "error", but to presence notifications only as defined above. (Note: While presence information MAY be provided on a user's behalf by an automated service, normally it is provided by the user's client.)

通过使用状态节,XMPP中的状态信息交换变得相对简单。然而,我们在这里看到了与消息处理的对比:尽管客户端可以通过包括“到”地址向另一个实体发送定向状态信息,但通常是状态通知(即,没有“类型”或“不可用”类型且没有“到”地址的状态节)从客户端发送到其服务器,然后由服务器广播到订阅发送实体存在的任何实体(在RFC 2778[IMP-MODEL]术语中,这些实体是订阅者)。此广播模型不适用于订阅相关的状态节或“错误”类型的状态节,但仅适用于如上定义的状态通知。(注意:虽然状态信息可以由自动服务代表用户提供,但通常由用户的客户端提供。)

For information regarding the syntax of presence stanzas as well as their defined attributes and child elements, refer to [XMPP-CORE].

有关状态节的语法及其定义的属性和子元素的信息,请参阅[XMPP-CORE]。

5.1. Client and Server Presence Responsibilities
5.1. 客户机和服务器存在责任
5.1.1. Initial Presence
5.1.1. 初始存在

After establishing a session, a client SHOULD send initial presence to the server in order to signal its availability for communications. As defined herein, the initial presence stanza (1) MUST possess no 'to' address (signalling that it is meant to be broadcasted by the server on behalf of the client) and (2) MUST possess no 'type' attribute (signalling the user's availability). After sending initial presence, an active resource is said to be an "available resource".

建立会话后,客户机应向服务器发送初始状态,以表明其可用于通信。如本文所定义的,初始存在节(1)必须不具有“到”地址(表示它将由服务器代表客户端广播),并且(2)必须不具有“类型”属性(表示用户的可用性)。发送初始状态后,活动资源称为“可用资源”。

Upon receiving initial presence from a client, the user's server MUST do the following if there is not already one or more available resources for the user (if there is already one or more available resources for the user, the server obviously does not need to send the presence probes, since it already possesses the requisite information):

在从客户端接收到初始状态时,如果用户还没有一个或多个可用资源,则用户的服务器必须执行以下操作(如果用户已经有一个或多个可用资源,服务器显然不需要发送状态探测,因为它已经拥有必要的信息):

1. Send presence probes (i.e., presence stanzas whose 'type' attribute is set to a value of "probe") from the full JID (e.g., <user@example.com/resource>) of the user to all contacts to which the user is subscribed in order to determine if they are available; such contacts are those for which a JID is present in the user's roster with the 'subscription' attribute set to a value of "to" or "both". (Note: The user's server MUST NOT send presence probes to contacts from which the user is blocking

1. 从完整JID发送状态探测(即,“type”属性设置为“probe”值的状态节)(例如<user@example.com/资源>),以确定用户订阅的所有联系人是否可用;此类联系人是指用户名册中存在JID且“订阅”属性设置为“到”或“两者”的联系人。(注意:用户的服务器不得向用户阻止的联系人发送状态探测。)

inbound presence notifications, as described under Blocking Inbound Presence Notifications (Section 10.10).)

入站状态通知,如阻止入站状态通知(第10.10节)中所述

2. Broadcast initial presence from the full JID (e.g., <user@example.com/resource>) of the user to all contacts that are subscribed to the user's presence information; such contacts are those for which a JID is present in the user's roster with the 'subscription' attribute set to a value of "from" or "both". (Note: The user's server MUST NOT broadcast initial presence to contacts to which the user is blocking outbound presence notifications, as described under Blocking Outbound Presence Notifications (Section 10.11).)

2. 从完整JID广播初始存在(例如<user@example.com/用户的状态信息订阅的所有联系人;此类联系人是指用户名册中存在JID且“订阅”属性设置为“自”或“两者”的联系人。(注意:用户服务器不得向用户阻止出站状态通知的联系人广播初始状态,如阻止出站状态通知(第10.11节)所述。)

In addition, the user's server MUST broadcast initial presence from the user's new available resource to any of the user's existing available resources (if any).

此外,用户的服务器必须将初始状态从用户的新可用资源广播到用户的任何现有可用资源(如果有)。

Upon receiving initial presence from the user, the contact's server MUST deliver the user's presence stanza to the full JIDs (<contact@example.org/resource>) associated with all of the contact's available resources, but only if the user is in the contact's roster with a subscription state of "to" or "both" and the contact has not blocked inbound presence notifications from the user's bare or full JID (as defined under Blocking Inbound Presence Notifications (Section 10.10)).

收到用户的初始状态后,联系人的服务器必须将用户的状态节传递给完整的JID(<contact@example.org/资源>)与联系人的所有可用资源关联,但仅当用户在联系人的花名册中且订阅状态为“到”或“两者”时并且联系人未阻止来自用户的裸JID或完整JID的入站状态通知(定义见阻止入站状态通知(第10.10节))。

If the user's server receives a presence stanza of type "error" in response to the initial presence that it sent to a contact on behalf of the user, it SHOULD NOT send further presence updates to that contact (until and unless it receives a presence stanza from the contact).

如果用户的服务器接收到类型为“error”的状态节,以响应其代表用户发送给联系人的初始状态,则不应向该联系人发送进一步的状态更新(直到并除非收到联系人的状态节)。

5.1.2. Presence Broadcast
5.1.2. 状态广播

After sending initial presence, the user MAY update its presence information for broadcasting at any time during its session by sending a presence stanza with no 'to' address and either no 'type' attribute or a 'type' attribute with a value of "unavailable". (Note: A user's client SHOULD NOT send a presence update to broadcast information that changes independently of the user's presence and availability.)

在发送初始存在之后,用户可以在其会话期间的任何时间通过发送没有“to”地址且没有“type”属性或值为“unavailable”的“type”属性的存在节来更新其存在信息以进行广播。(注意:用户的客户端不应发送状态更新以广播独立于用户的状态和可用性而改变的信息。)

If the presence stanza lacks a 'type' attribute (i.e., expresses availability), the user's server MUST broadcast the full XML of that presence stanza to all contacts (1) that are in the user's roster with a subscription type of "from" or "both", (2) to whom the user

如果状态节缺少“类型”属性(即表示可用性),则用户服务器必须将该状态节的完整XML广播给用户名册中订阅类型为“发件人”或“双方”的所有联系人(1)(2)

has not blocked outbound presence notifications, and (3) from whom the server has not received a presence error during the user's session (as well as to any of the user's other available resources).

未阻止出站状态通知,以及(3)服务器在用户会话期间未从其接收到状态错误(以及用户的任何其他可用资源)。

If the presence stanza has a 'type' attribute set to a value of "unavailable", the user's server MUST broadcast the full XML of that presence stanza to all entities that fit the above description, as well as to any entities to which the user has sent directed available presence during the user's session (if the user has not yet sent directed unavailable presence to that entity).

如果状态节的“type”属性设置为“unavailable”,则用户服务器必须将该状态节的完整XML广播给符合上述描述的所有实体,以及用户在会话期间向其发送定向可用状态的任何实体(如果用户尚未向该实体发送定向不可用状态)。

5.1.3. Presence Probes
5.1.3. 存在探测

Upon receiving a presence probe from the user, the contact's server SHOULD reply as follows:

收到用户的状态探测后,联系人的服务器应回复如下:

1. If the user is not in the contact's roster with a subscription state of "From", "From + Pending Out", or "Both" (as defined under Subscription States (Section 9)), the contact's server MUST return a presence stanza of type "error" in response to the presence probe (however, if a server receives a presence probe from a subdomain of the server's hostname or another such trusted service, it MAY provide presence information about the user to that entity). Specifically:

1. 如果用户不在订阅状态为“自”、“自+待决”或“两者”(如订阅状态(第9节)中所定义)的联系人名册中,则联系人的服务器必须返回类型为“错误”的状态节,以响应状态探测(但是,如果服务器从服务器主机名的子域或其他此类受信任服务接收到状态探测,则可能会向该实体提供有关用户的状态信息)。具体而言:

* if the user is in the contact's roster with a subscription state of "None", "None + Pending Out", or "To" (or is not in the contact's roster at all), the contact's server MUST return a <forbidden/> stanza error in response to the presence probe.

* 如果用户在联系人名册中的订阅状态为“无”、“无+挂起”或“至”(或根本不在联系人名册中),则联系人的服务器必须返回<forbidden/>节错误以响应状态探测。

* if the user is in the contact's roster with a subscription state of "None + Pending In", "None + Pending Out/In", or "To + Pending In", the contact's server MUST return a <not-authorized/> stanza error in response to the presence probe.

* 如果用户在联系人名册中的订阅状态为“无+待决进入”、“无+待决外出/进入”或“至+待决进入”,则联系人的服务器必须返回<not authorized/>节错误以响应状态探测。

2. Else, if the contact is blocking presence notifications to the user's bare JID or full JID (using either a default list or active list as defined under Blocking Outbound Presence Notifications (Section 10.11)), the server MUST NOT reply to the presence probe.

2. 否则,如果联系人正在阻止向用户的裸JID或完整JID发送状态通知(使用“阻止出站状态通知”(第10.11节)中定义的默认列表或活动列表),则服务器不得回复状态探测。

3. Else, if the contact has no available resources, the server MUST either (1) reply to the presence probe by sending to the user the full XML of the last presence stanza of type "unavailable" received by the server from the contact, or (2) not reply at all.

3. 否则,如果联系人没有可用资源,则服务器必须(1)通过向用户发送服务器从联系人处接收的“不可用”类型的最后一个状态节的完整XML来回复状态探测,或者(2)根本不回复。

4. Else, if the contact has at least one available resource, the server MUST reply to the presence probe by sending to the user the full XML of the last presence stanza with no 'to' attribute received by the server from each of the contact's available resources (again, subject to privacy lists in force for each session).

4. 否则,如果联系人至少有一个可用资源,则服务器必须通过向用户发送服务器从联系人的每个可用资源(同样,根据每个会话有效的隐私列表)接收到的最后一个状态节的完整XML(没有“to”属性)来回复状态探测。

5.1.4. Directed Presence
5.1.4. 直接在场

A user MAY send directed presence to another entity (i.e., a presence stanza with a 'to' attribute whose value is the JID of the other entity and with either no 'type' attribute or a 'type' attribute whose value is "unavailable"). There are three possible cases:

用户可以向另一实体发送定向状态(即,具有“to”属性的状态节,其值为另一实体的JID,并且没有“type”属性或具有“type”属性,其值为“unavailable”)。有三种可能的情况:

1. If the user sends directed presence to a contact that is in the user's roster with a subscription type of "from" or "both" after having sent initial presence and before sending unavailable presence broadcast, the user's server MUST route or deliver the full XML of that presence stanza (subject to privacy lists) but SHOULD NOT otherwise modify the contact's status regarding presence broadcast (i.e., it SHOULD include the contact's JID in any subsequent presence broadcasts initiated by the user).

1. 如果在发送初始状态后和发送不可用状态广播之前,用户向用户名册中订阅类型为“发件人”或“两者”的联系人发送定向状态,则用户服务器必须路由或交付该状态节的完整XML(根据隐私列表)但不应以其他方式修改联系人关于状态广播的状态(即,在用户发起的任何后续状态广播中应包括联系人的JID)。

2. If the user sends directed presence to an entity that is not in the user's roster with a subscription type of "from" or "both" after having sent initial presence and before sending unavailable presence broadcast, the user's server MUST route or deliver the full XML of that presence stanza to the entity but MUST NOT modify the contact's status regarding available presence broadcast (i.e., it MUST NOT include the entity's JID in any subsequent broadcasts of available presence initiated by the user); however, if the available resource from which the user sent the directed presence become unavailable, the user's server MUST broadcast that unavailable presence to the entity (if the user has not yet sent directed unavailable presence to that entity).

2. 如果用户在发送初始状态之后和发送不可用状态广播之前,以订阅类型“来自”或“两者”向不在用户名册中的实体发送定向状态,用户服务器必须将该状态节的完整XML路由或交付给实体,但不得修改联系人关于可用状态广播的状态(即,不得在用户发起的任何后续可用状态广播中包括实体的JID);但是,如果用户发送定向存在的可用资源变得不可用,则用户的服务器必须向实体广播该不可用存在(如果用户尚未向该实体发送定向不可用存在)。

3. If the user sends directed presence without first sending initial presence or after having sent unavailable presence broadcast (i.e., the resource is active but not available), the user's server MUST treat the entities to which the user sends directed presence in the same way that it treats the entities listed in case #2 above.

3. 如果用户未首先发送初始状态或在发送不可用状态广播(即,资源处于活动状态但不可用)后发送定向状态,则用户服务器必须以处理上述情况#2中所列实体的相同方式处理用户向其发送定向状态的实体。

5.1.5. Unavailable Presence
5.1.5. 不可用的存在

Before ending its session with a server, a client SHOULD gracefully become unavailable by sending a final presence stanza that possesses no 'to' attribute and that possesses a 'type' attribute whose value is "unavailable" (optionally, the final presence stanza MAY contain one or more <status/> elements specifying the reason why the user is no longer available). However, the user's server MUST NOT depend on receiving final presence from an available resource, since the resource may become unavailable unexpectedly or may be timed out by the server. If one of the user's resources becomes unavailable for any reason (either gracefully or ungracefully), the user's server MUST broadcast unavailable presence to all contacts (1) that are in the user's roster with a subscription type of "from" or "both", (2) to whom the user has not blocked outbound presence, and (3) from whom the server has not received a presence error during the user's session; the user's server MUST also send that unavailable presence stanza to any of the user's other available resources, as well as to any entities to which the user has sent directed presence during the user's session for that resource (if the user has not yet sent directed unavailable presence to that entity). Any presence stanza with no 'type' attribute and no 'to' attribute that is sent after sending directed unavailable presence or broadcasted unavailable presence MUST be broadcasted by the server to all subscribers.

在结束与服务器的会话之前,客户端应该通过发送不具有“to”属性且具有值为“unavailable”的“type”属性的“final presence”节来正常地变得不可用(可选地,最终状态节可能包含一个或多个<status/>元素,指定用户不再可用的原因)。但是,用户的服务器不能依赖于从可用资源接收最终状态,因为该资源可能会意外不可用,或者可能被服务器超时。如果用户的某个资源因任何原因(正常或不正常)不可用,用户服务器必须向用户名册中订阅类型为“发件人”或“双方”的所有联系人(1)广播不可用状态,(2)用户未阻止其出站状态,以及(3)服务器在用户会话期间未从其接收到状态错误;用户服务器还必须将该不可用状态节发送到用户的任何其他可用资源,以及用户在该资源的用户会话期间向其发送定向状态的任何实体(如果用户尚未向该实体发送定向不可用状态)。服务器必须将发送定向不可用状态或广播不可用状态后发送的任何不带“type”属性和“to”属性的状态节广播给所有订阅者。

5.1.6. Presence Subscriptions
5.1.6. 状态订阅

A subscription request is a presence stanza whose 'type' attribute has a value of "subscribe". If the subscription request is being sent to an instant messaging contact, the JID supplied in the 'to' attribute SHOULD be of the form <contact@example.org> rather than <contact@example.org/resource>, since the desired result is normally for the user to receive presence from all of the contact's resources, not merely the particular resource specified in the 'to' attribute.

订阅请求是一个状态节,其“type”属性的值为“subscribe”。如果订阅请求被发送到即时消息联系人,则“to”属性中提供的JID应为以下格式<contact@example.org>而不是<contact@example.org/resource>,因为期望的结果通常是用户从联系人的所有资源接收状态,不仅仅是“to”属性中指定的特定资源。

A user's server MUST NOT automatically approve subscription requests on the user's behalf. All subscription requests MUST be directed to the user's client, specifically to one or more available resources associated with the user. If there is no available resource associated with the user when the subscription request is received by the user's server, the user's server MUST keep a record of the subscription request and deliver the request when the user next creates an available resource, until the user either approves or denies the request. If there is more than one available resource associated with the user when the subscription request is received by the user's server, the user's server MUST broadcast that subscription request to all available resources in accordance with Server Rules for Handling XML Stanzas (Section 11). (Note: If an active resource

用户的服务器不得代表用户自动批准订阅请求。所有订阅请求都必须定向到用户的客户端,特别是与用户关联的一个或多个可用资源。如果在用户服务器收到订阅请求时没有与用户关联的可用资源,则用户服务器必须保留订阅请求的记录,并在用户下次创建可用资源时传递请求,直到用户批准或拒绝该请求。当用户服务器接收到订阅请求时,如果有多个可用资源与用户关联,则用户服务器必须根据处理XML节的服务器规则(第11节)向所有可用资源广播该订阅请求。(注意:如果是活动资源

has not provided initial presence, the server MUST NOT consider it to be available and therefore MUST NOT send subscription requests to it.) However, if the user receives a presence stanza of type "subscribe" from a contact to whom the user has already granted permission to see the user's presence information (e.g., in cases when the contact is seeking to resynchronize subscription states), the user's server SHOULD auto-reply on behalf of the user. In addition, the user's server MAY choose to re-send an unapproved pending subscription request to the contact based on an implementation-specific algorithm (e.g., whenever a new resource becomes available for the user, or after a certain amount of time has elapsed); this helps to recover from transient, silent errors that may have occurred in relation to the original subscription request.

但是,如果用户从一个联系人那里接收到“订阅”类型的存在节,用户就已经允许它查看用户的存在信息。(例如,在联系人试图重新同步订阅状态的情况下),用户服务器应代表用户自动回复。此外,用户服务器可选择根据特定于实现的算法向联系人重新发送未经批准的挂起订阅请求(例如,每当新资源可供用户使用时,或经过一定时间后);这有助于从与原始订阅请求相关的短暂、无声错误中恢复。

5.2. Specifying Availability Status
5.2. 指定可用性状态

A client MAY provide further information about its availability status by using the <show/> element (see Show (Section 2.2.2.1)).

客户可以使用<show/>元素提供关于其可用性状态的进一步信息(见show(第2.2.2.1节))。

Example: Availability status:

示例:可用性状态:

   <presence>
     <show>dnd</show>
   </presence>
        
   <presence>
     <show>dnd</show>
   </presence>
        
5.3. Specifying Detailed Status Information
5.3. 指定详细的状态信息

In conjunction with the <show/> element, a client MAY provide detailed status information by using the <status/> element (see Status (Section 2.2.2.2)).

结合<show/>元素,客户可以使用<status/>元素提供详细的状态信息(参见状态(第2.2.2.2节))。

Example: Detailed status information:

示例:详细状态信息:

   <presence xml:lang='en'>
     <show>dnd</show>
     <status>Wooing Juliet</status>
     <status xml:lang='cz'>Ja dvo&#x0159;&#x00ED;m Juliet</status>
   </presence>
        
   <presence xml:lang='en'>
     <show>dnd</show>
     <status>Wooing Juliet</status>
     <status xml:lang='cz'>Ja dvo&#x0159;&#x00ED;m Juliet</status>
   </presence>
        
5.4. Specifying Presence Priority
5.4. 指定状态优先级

A client MAY provide a priority for its resource by using the <priority/> element (see Priority (Section 2.2.2.3)).

客户可以使用<priority/>元素为其资源提供优先级(参见优先级(第2.2.2.3节))。

Example: Presence priority:

示例:状态优先级:

   <presence xml:lang='en'>
     <show>dnd</show>
     <status>Wooing Juliet</status>
     <status xml:lang='cz'>Ja dvo&#x0159;&#x00ED;m Juliet</status>
     <priority>1</priority>
   </presence>
        
   <presence xml:lang='en'>
     <show>dnd</show>
     <status>Wooing Juliet</status>
     <status xml:lang='cz'>Ja dvo&#x0159;&#x00ED;m Juliet</status>
     <priority>1</priority>
   </presence>
        
5.5. Presence Examples
5.5. 在场示例

The examples in this section illustrate the presence-related protocols described above. The user is romeo@example.net, he has an available resource whose resource identifier is "orchard", and he has the following individuals in his roster:

本节中的示例说明了上述与存在相关的协议。用户是romeo@example.net,他有一个资源标识符为“orchard”的可用资源,他的名册中有以下人员:

o juliet@example.com (subscription="both" and she has two available resources, one whose resource is "chamber" and another whose resource is "balcony")

o juliet@example.com(subscription=“both”和她有两个可用资源,一个资源是“chamber”,另一个资源是“阳台”)

o benvolio@example.org (subscription="to")

o benvolio@example.org(subscription=“to”)

o mercutio@example.org (subscription="from")

o mercutio@example.org(subscription=“from”)

Example 1: User sends initial presence:

示例1:用户发送初始状态:

   <presence/>
        
   <presence/>
        

Example 2: User's server sends presence probes to contacts with subscription="to" and subscription="both" on behalf of the user's available resource:

示例2:用户的服务器代表用户的可用资源向具有subscription=“to”和subscription=“both”的联系人发送状态探测:

   <presence
       type='probe'
       from='romeo@example.net/orchard'
       to='juliet@example.com'/>
        
   <presence
       type='probe'
       from='romeo@example.net/orchard'
       to='juliet@example.com'/>
        
   <presence
       type='probe'
       from='romeo@example.net/orchard'
       to='benvolio@example.org'/>
        
   <presence
       type='probe'
       from='romeo@example.net/orchard'
       to='benvolio@example.org'/>
        

Example 3: User's server sends initial presence to contacts with subscription="from" and subscription="both" on behalf of the user's available resource:

示例3:用户的服务器代表用户的可用资源向具有subscription=“from”和subscription=“both”的联系人发送初始状态:

   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'/>
        
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'/>
        
   <presence
       from='romeo@example.net/orchard'
       to='mercutio@example.org'/>
        
   <presence
       from='romeo@example.net/orchard'
       to='mercutio@example.org'/>
        

Example 4: Contacts' servers reply to presence probe on behalf of all available resources:

示例4:联系人服务器代表所有可用资源回复状态探测:

   <presence
       from='juliet@example.com/balcony'
       to='romeo@example.net/orchard'
       xml:lang='en'>
     <show>away</show>
     <status>be right back</status>
     <priority>0</priority>
   </presence>
        
   <presence
       from='juliet@example.com/balcony'
       to='romeo@example.net/orchard'
       xml:lang='en'>
     <show>away</show>
     <status>be right back</status>
     <priority>0</priority>
   </presence>
        
   <presence
       from='juliet@example.com/chamber'
       to='romeo@example.net/orchard'>
     <priority>1</priority>
   </presence>
        
   <presence
       from='juliet@example.com/chamber'
       to='romeo@example.net/orchard'>
     <priority>1</priority>
   </presence>
        
   <presence
       from='benvolio@example.org/pda'
       to='romeo@example.net/orchard'
       xml:lang='en'>
     <show>dnd</show>
     <status>gallivanting</status>
   </presence>
        
   <presence
       from='benvolio@example.org/pda'
       to='romeo@example.net/orchard'
       xml:lang='en'>
     <show>dnd</show>
     <status>gallivanting</status>
   </presence>
        

Example 5: Contacts' servers deliver user's initial presence to all available resources or return error to user:

示例5:联系人服务器将用户的初始状态传递给所有可用资源,或将错误返回给用户:

   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com/chamber'/>
        
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com/chamber'/>
        
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com/balcony'/>
        
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com/balcony'/>
        
   <presence
       type='error'
       from='mercutio@example.org'
       to='romeo@example.net/orchard'>
     <error type='cancel'>
       <gone xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </presence>
        
   <presence
       type='error'
       from='mercutio@example.org'
       to='romeo@example.net/orchard'>
     <error type='cancel'>
       <gone xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </presence>
        

Example 6: User sends directed presence to another user not in his roster:

示例6:用户向不在其花名册中的另一个用户发送直接到场:

   <presence
       from='romeo@example.net/orchard'
       to='nurse@example.com'
       xml:lang='en'>
     <show>dnd</show>
     <status>courting Juliet</status>
     <priority>0</priority>
   </presence>
        
   <presence
       from='romeo@example.net/orchard'
       to='nurse@example.com'
       xml:lang='en'>
     <show>dnd</show>
     <status>courting Juliet</status>
     <priority>0</priority>
   </presence>
        

Example 7: User sends updated available presence information for broadcasting:

示例7:用户发送更新的可用状态信息进行广播:

   <presence xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        
   <presence xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        

Example 8: User's server broadcasts updated presence information only to one contact (not those from whom an error was received or to whom the user sent directed presence):

示例8:用户的服务器仅向一个联系人广播更新的状态信息(而不是从其接收错误或向其发送定向状态的联系人):

   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        

Example 9: Contact's server delivers updated presence information to all of the contact's available resources:

示例9:联系人的服务器向联系人的所有可用资源提供更新的状态信息:

   [to "balcony" resource...]
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        
   [to "balcony" resource...]
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        
   [to "chamber" resource...]
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        
   [to "chamber" resource...]
   <presence
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <show>away</show>
     <status>I shall return!</status>
     <priority>1</priority>
   </presence>
        

Example 10: One of the contact's resources broadcasts final presence:

示例10:联系人的一个资源广播最终状态:

   <presence from='juliet@example.com/balcony' type='unavailable'/>
        
   <presence from='juliet@example.com/balcony' type='unavailable'/>
        

Example 11: Contact's server sends unavailable presence information to user:

示例11:联系人的服务器向用户发送不可用的状态信息:

   <presence
       type='unavailable'
       from='juliet@example.com/balcony'
       to='romeo@example.net/orchard'/>
        
   <presence
       type='unavailable'
       from='juliet@example.com/balcony'
       to='romeo@example.net/orchard'/>
        

Example 12: User sends final presence:

示例12:用户发送最终状态:

   <presence from='romeo@example.net/orchard'
             type='unavailable'
             xml:lang='en'>
     <status>gone home</status>
   </presence>
        
   <presence from='romeo@example.net/orchard'
             type='unavailable'
             xml:lang='en'>
     <status>gone home</status>
   </presence>
        

Example 13: User's server broadcasts unavailable presence information to contact as well as to the person to whom the user sent directed presence:

示例13:用户的服务器将不可用的状态信息广播给联系人以及用户向其发送定向状态的人:

   <presence
       type='unavailable'
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <status>gone home</status>
   </presence>
        
   <presence
       type='unavailable'
       from='romeo@example.net/orchard'
       to='juliet@example.com'
       xml:lang='en'>
     <status>gone home</status>
   </presence>
        
   <presence
       from='romeo@example.net/orchard'
       to='nurse@example.com'
       xml:lang='en'>
     <status>gone home</status>
   </presence>
        
   <presence
       from='romeo@example.net/orchard'
       to='nurse@example.com'
       xml:lang='en'>
     <status>gone home</status>
   </presence>
        
6. Managing Subscriptions
6. 管理订阅

In order to protect the privacy of instant messaging users and any other entities, presence and availability information is disclosed only to other entities that the user has approved. When a user has agreed that another entity may view its presence, the entity is said to have a subscription to the user's presence information. A subscription lasts across sessions; indeed, it lasts until the subscriber unsubscribes or the subscribee cancels the previously-granted subscription. Subscriptions are managed within XMPP by sending presence stanzas containing specially-defined attributes.

为了保护即时消息用户和任何其他实体的隐私,状态和可用性信息仅披露给用户已批准的其他实体。当用户同意另一实体可以查看其存在时,该实体被称为订阅了该用户的存在信息。订阅将持续整个会话;实际上,它一直持续到订户取消订阅或订户取消先前授予的订阅。通过发送包含特殊定义属性的状态节,可以在XMPP中管理订阅。

Note: There are important interactions between subscriptions and rosters; these are defined under Integration of Roster Items and Presence Subscriptions (Section 8), and the reader must refer to that section for a complete understanding of presence subscriptions.

注意:订阅和名册之间有重要的交互作用;这些是在“花名册项目和状态订阅集成”(第8节)中定义的,读者必须参考该节以全面了解状态订阅。

6.1. Requesting a Subscription
6.1. 请求订阅

A request to subscribe to another entity's presence is made by sending a presence stanza of type "subscribe".

通过发送类型为“subscribe”的状态节来请求订阅另一个实体的状态。

Example: Sending a subscription request:

示例:发送订阅请求:

   <presence to='juliet@example.com' type='subscribe'/>
        
   <presence to='juliet@example.com' type='subscribe'/>
        

For client and server responsibilities regarding presence subscription requests, refer to Presence Subscriptions (Section 5.1.6).

有关状态订阅请求的客户端和服务器责任,请参阅状态订阅(第5.1.6节)。

6.2. Handling a Subscription Request
6.2. 处理订阅请求

When a client receives a subscription request from another entity, it MUST either approve the request by sending a presence stanza of type "subscribed" or refuse the request by sending a presence stanza of type "unsubscribed".

当客户机收到来自另一实体的订阅请求时,它必须通过发送“subscribed”类型的状态节批准该请求,或通过发送“unsubscribed”类型的状态节拒绝该请求。

Example: Approving a subscription request:

示例:批准订阅请求:

   <presence to='romeo@example.net' type='subscribed'/>
        
   <presence to='romeo@example.net' type='subscribed'/>
        

Example: Refusing a presence subscription request:

示例:拒绝状态订阅请求:

   <presence to='romeo@example.net' type='unsubscribed'/>
        
   <presence to='romeo@example.net' type='unsubscribed'/>
        
6.3. Cancelling a Subscription from Another Entity
6.3. 取消另一实体的订阅

If a user would like to cancel a previously-granted subscription request, it sends a presence stanza of type "unsubscribed".

如果用户想要取消先前授予的订阅请求,它会发送一个类型为“unsubscribed”的状态节。

Example: Cancelling a previously granted subscription request:

示例:取消以前授予的订阅请求:

   <presence to='romeo@example.net' type='unsubscribed'/>
        
   <presence to='romeo@example.net' type='unsubscribed'/>
        
6.4. Unsubscribing from Another Entity's Presence
6.4. 取消订阅另一实体的存在

If a user would like to unsubscribe from the presence of another entity, it sends a presence stanza of type "unsubscribe".

如果用户想要取消订阅另一实体的状态,它会发送一个类型为“unsubscribe”的状态节。

Example: Unsubscribing from an entity's presence:

示例:从实体的状态取消订阅:

   <presence to='juliet@example.com' type='unsubscribe'/>
        
   <presence to='juliet@example.com' type='unsubscribe'/>
        
7. Roster Management
7. 名册管理

In XMPP, one's contact list is called a roster, which consists of any number of specific roster items, each roster item being identified by a unique JID (usually of the form <contact@domain>). A user's roster is stored by the user's server on the user's behalf so that the user may access roster information from any resource.

在XMPP中,一个人的联系人列表称为花名册,它由任意数量的特定花名册项目组成,每个花名册项目由一个唯一的JID(通常为<contact@domain>). 用户的花名册由用户服务器代表用户存储,以便用户可以从任何资源访问花名册信息。

Note: There are important interactions between rosters and subscriptions; these are defined under Integration of Roster Items and Presence Subscriptions (Section 8), and the reader must refer to that section for a complete understanding of roster management.

注意:名册和订阅之间有重要的交互作用;这些是在花名册项目和状态订阅集成(第8节)下定义的,读者必须参考该节以全面了解花名册管理。

7.1. Syntax and Semantics
7.1. 语法和语义

Rosters are managed using IQ stanzas, specifically by means of a <query/> child element qualified by the 'jabber:iq:roster' namespace. The <query/> element MAY contain one or more <item/> children, each describing a unique roster item or "contact".

名册使用IQ节进行管理,特别是通过由“jabber:IQ:花名册”命名空间限定的<query/>子元素进行管理。<query/>元素可以包含一个或多个<item/>子元素,每个子元素描述一个唯一的花名册项目或“联系人”。

The "key" or unique identifier for each roster item is a JID, encapsulated in the 'jid' attribute of the <item/> element (which is REQUIRED). The value of the 'jid' attribute SHOULD be of the form <user@domain> if the item is associated with another (human) instant messaging user.

每个花名册项目的“键”或唯一标识符是一个JID,封装在<item/>元素(这是必需的)的“JID”属性中。“jid”属性的值应为<user@domain>如果项目与另一个(人工)即时消息用户关联。

The state of the presence subscription in relation to a roster item is captured in the 'subscription' attribute of the <item/> element. Allowable values for this attribute are:

与花名册项目相关的状态订阅在<item/>元素的“subscription”属性中捕获。此属性的允许值为:

o "none" -- the user does not have a subscription to the contact's presence information, and the contact does not have a subscription to the user's presence information

o “无”-用户没有订阅联系人的状态信息,联系人也没有订阅用户的状态信息

o "to" -- the user has a subscription to the contact's presence information, but the contact does not have a subscription to the user's presence information

o “to”--用户订阅了联系人的状态信息,但联系人没有订阅用户的状态信息

o "from" -- the contact has a subscription to the user's presence information, but the user does not have a subscription to the contact's presence information

o “发件人”--联系人订阅了用户的状态信息,但用户没有订阅联系人的状态信息

o "both" -- both the user and the contact have subscriptions to each other's presence information

o “两者”--用户和联系人都订阅了对方的状态信息

Each <item/> element MAY contain a 'name' attribute, which sets the "nickname" to be associated with the JID, as determined by the user (not the contact). The value of the 'name' attribute is opaque.

每个<item/>元素可能包含一个“name”属性,该属性设置由用户(而不是联系人)确定的与JID关联的“昵称”。“name”属性的值是不透明的。

Each <item/> element MAY contain one or more <group/> child elements, for use in collecting roster items into various categories. The XML character data of the <group/> element is opaque.

每个<item/>元素可以包含一个或多个<group/>子元素,用于将花名册项目收集到各种类别中。<group/>元素的XML字符数据是不透明的。

7.2. Business Rules
7.2. 商业规则

A server MUST ignore any 'to' address on a roster "set", and MUST treat any roster "set" as applying to the sender. For added safety, a client SHOULD check the "from" address of a "roster push" (incoming IQ of type "set" containing a roster item) to ensure that it is from a trusted source; specifically, the stanza MUST either have no 'from' attribute (i.e., implicitly from the server) or have a 'from' attribute whose value matches the user's bare JID (of the form <user@domain>) or full JID (of the form <user@domain/resource>); otherwise, the client SHOULD ignore the "roster push".

服务器必须忽略花名册“集合”上的任何“收件人”地址,并且必须将任何花名册“集合”视为应用于发件人。为了增加安全性,客户应检查“花名册推送”(包含花名册项目的“set”类型的传入IQ)的“发件人”地址,以确保它来自可信来源;具体来说,节必须没有“from”属性(即,隐式地来自服务器),或者具有一个“from”属性,其值与用户的裸JID(表单)匹配<user@domain>)或完整的JID(形式)<user@domain/资源>);否则,客户应忽略“排班推送”。

7.3. Retrieving One's Roster on Login
7.3. 登录时检索花名册

Upon connecting to the server and becoming an active resource, a client SHOULD request the roster before sending initial presence (however, because receiving the roster may not be desirable for all resources, e.g., a connection with limited bandwidth, the client's request for the roster is OPTIONAL). If an available resource does not request the roster during a session, the server MUST NOT send it presence subscriptions and associated roster updates.

连接到服务器并成为活动资源后,客户端应在发送初始状态之前请求花名册(但是,由于并非所有资源都需要接收花名册,例如,带宽有限的连接,客户端对花名册的请求是可选的)。如果可用资源在会话期间未请求花名册,则服务器不得向其发送状态订阅和相关花名册更新。

Example: Client requests current roster from server:

示例:客户端从服务器请求当前花名册:

   <iq from='juliet@example.com/balcony' type='get' id='roster_1'>
     <query xmlns='jabber:iq:roster'/>
   </iq>
        
   <iq from='juliet@example.com/balcony' type='get' id='roster_1'>
     <query xmlns='jabber:iq:roster'/>
   </iq>
        

Example: Client receives roster from server:

示例:客户端从服务器接收花名册:

   <iq to='juliet@example.com/balcony' type='result' id='roster_1'>
     <query xmlns='jabber:iq:roster'>
       <item jid='romeo@example.net'
             name='Romeo'
             subscription='both'>
         <group>Friends</group>
       </item>
       <item jid='mercutio@example.org'
             name='Mercutio'
             subscription='from'>
         <group>Friends</group>
       </item>
       <item jid='benvolio@example.org'
             name='Benvolio'
             subscription='both'>
         <group>Friends</group>
       </item>
     </query>
        
   <iq to='juliet@example.com/balcony' type='result' id='roster_1'>
     <query xmlns='jabber:iq:roster'>
       <item jid='romeo@example.net'
             name='Romeo'
             subscription='both'>
         <group>Friends</group>
       </item>
       <item jid='mercutio@example.org'
             name='Mercutio'
             subscription='from'>
         <group>Friends</group>
       </item>
       <item jid='benvolio@example.org'
             name='Benvolio'
             subscription='both'>
         <group>Friends</group>
       </item>
     </query>
        
   </iq>
        
   </iq>
        
7.4. Adding a Roster Item
7.4. 添加花名册项目

At any time, a user MAY add an item to his or her roster.

用户可以随时将项目添加到其花名册中。

Example: Client adds a new item:

示例:客户端添加新项目:

   <iq from='juliet@example.com/balcony' type='set' id='roster_2'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com'
             name='Nurse'>
         <group>Servants</group>
       </item>
     </query>
   </iq>
        
   <iq from='juliet@example.com/balcony' type='set' id='roster_2'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com'
             name='Nurse'>
         <group>Servants</group>
       </item>
     </query>
   </iq>
        

The server MUST update the roster information in persistent storage, and also push the change out to all of the user's available resources that have requested the roster. This "roster push" consists of an IQ stanza of type "set" from the server to the client and enables all available resources to remain in sync with the server-based roster information.

服务器必须更新持久存储中的花名册信息,并将更改推送到请求花名册的所有用户可用资源。此“花名册推送”包括从服务器到客户端的“set”类型的IQ节,使所有可用资源与基于服务器的花名册信息保持同步。

Example: Server (1) pushes the updated roster information to all available resources that have requested the roster and (2) replies with an IQ result to the sending resource:

示例:服务器(1)将更新的花名册信息推送到已请求花名册的所有可用资源,并(2)向发送资源回复IQ结果:

   <iq to='juliet@example.com/balcony'
       type='set'
       id='a78b4q6ha463'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com'
             name='Nurse'
             subscription='none'>
         <group>Servants</group>
       </item>
     </query>
   </iq>
        
   <iq to='juliet@example.com/balcony'
       type='set'
       id='a78b4q6ha463'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com'
             name='Nurse'
             subscription='none'>
         <group>Servants</group>
       </item>
     </query>
   </iq>
        
   <iq to='juliet@example.com/chamber'
       type='set'
       id='a78b4q6ha464'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com'
             name='Nurse'
             subscription='none'>
         <group>Servants</group>
        
   <iq to='juliet@example.com/chamber'
       type='set'
       id='a78b4q6ha464'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com'
             name='Nurse'
             subscription='none'>
         <group>Servants</group>
        
       </item>
     </query>
   </iq>
        
       </item>
     </query>
   </iq>
        
   <iq to='juliet@example.com/balcony' type='result' id='roster_2'/>
        
   <iq to='juliet@example.com/balcony' type='result' id='roster_2'/>
        

As required by the semantics of the IQ stanza kind as defined in [XMPP-CORE], each resource that received the roster push MUST reply with an IQ stanza of type "result" (or "error").

根据[XMPP-CORE]中定义的IQ节类型的语义要求,接收到花名册推送的每个资源都必须使用类型为“result”(或“error”)的IQ节进行回复。

Example: Resources reply with an IQ result to the server:

示例:资源向服务器回复IQ结果:

   <iq from='juliet@example.com/balcony'
       to='example.com'
       type='result'
       id='a78b4q6ha463'/>
   <iq from='juliet@example.com/chamber'
       to='example.com'
       type='result'
       id='a78b4q6ha464'/>
        
   <iq from='juliet@example.com/balcony'
       to='example.com'
       type='result'
       id='a78b4q6ha463'/>
   <iq from='juliet@example.com/chamber'
       to='example.com'
       type='result'
       id='a78b4q6ha464'/>
        
7.5. Updating a Roster Item
7.5. 更新名册项目

Updating an existing roster item (e.g., changing the group) is done in the same way as adding a new roster item, i.e., by sending the roster item in an IQ set to the server.

更新现有花名册项目(例如,更改组)的方式与添加新花名册项目的方式相同,即通过将IQ集中的花名册项目发送到服务器。

Example: User updates roster item (added group):

示例:用户更新花名册项目(添加的组):

   <iq from='juliet@example.com/chamber' type='set' id='roster_3'>
     <query xmlns='jabber:iq:roster'>
       <item jid='romeo@example.net'
             name='Romeo'
             subscription='both'>
         <group>Friends</group>
         <group>Lovers</group>
       </item>
     </query>
   </iq>
        
   <iq from='juliet@example.com/chamber' type='set' id='roster_3'>
     <query xmlns='jabber:iq:roster'>
       <item jid='romeo@example.net'
             name='Romeo'
             subscription='both'>
         <group>Friends</group>
         <group>Lovers</group>
       </item>
     </query>
   </iq>
        

As with adding a roster item, when updating a roster item the server MUST update the roster information in persistent storage, and also initiate a roster push to all of the user's available resources that have requested the roster.

与添加花名册项目一样,在更新花名册项目时,服务器必须更新持久存储中的花名册信息,并启动花名册推送,将其推送到请求花名册的所有用户可用资源。

7.6. Deleting a Roster Item
7.6. 删除花名册项目

At any time, a user MAY delete an item from his or her roster by sending an IQ set to the server and making sure that the value of the 'subscription' attribute is "remove" (a compliant server MUST ignore any other values of the 'subscription' attribute when received from a client).

在任何时候,用户都可以通过向服务器发送IQ集并确保“订阅”属性的值为“删除”(从客户端接收时,符合要求的服务器必须忽略“订阅”属性的任何其他值),从其名册中删除项目。

Example: Client removes an item:

示例:客户端删除一个项目:

   <iq from='juliet@example.com/balcony' type='set' id='roster_4'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com' subscription='remove'/>
     </query>
   </iq>
        
   <iq from='juliet@example.com/balcony' type='set' id='roster_4'>
     <query xmlns='jabber:iq:roster'>
       <item jid='nurse@example.com' subscription='remove'/>
     </query>
   </iq>
        

As with adding a roster item, when deleting a roster item the server MUST update the roster information in persistent storage, initiate a roster push to all of the user's available resources that have requested the roster (with the 'subscription' attribute set to a value of "remove"), and send an IQ result to the initiating resource.

与添加花名册项目一样,删除花名册项目时,服务器必须更新持久存储中的花名册信息,启动花名册推送到请求花名册的所有用户可用资源(将“订阅”属性设置为“删除”)并将IQ结果发送到发起资源。

For further information about the implications of this command, see Removing a Roster Item and Cancelling All Subscriptions (Section 8.6).

有关此命令含义的更多信息,请参阅删除花名册项目和取消所有订阅(第8.6节)。

8. Integration of Roster Items and Presence Subscriptions
8. 名册项目和存在订阅的集成
8.1. Overview
8.1. 概述

Some level of integration between roster items and presence subscriptions is normally expected by an instant messaging user regarding the user's subscriptions to and from other contacts. This section describes the level of integration that MUST be supported within XMPP instant messaging applications.

即时消息用户通常期望在名册项目和状态订阅之间进行某种程度的集成,以了解用户对其他联系人的订阅和来自其他联系人的订阅。本节介绍XMPP即时消息应用程序中必须支持的集成级别。

There are four primary subscription states:

有四种主要订阅状态:

o None -- the user does not have a subscription to the contact's presence information, and the contact does not have a subscription to the user's presence information

o 无--用户没有订阅联系人的状态信息,联系人也没有订阅用户的状态信息

o To -- the user has a subscription to the contact's presence information, but the contact does not have a subscription to the user's presence information

o To——用户订阅了联系人的状态信息,但联系人没有订阅用户的状态信息

o From -- the contact has a subscription to the user's presence information, but the user does not have a subscription to the contact's presence information

o From——联系人订阅了用户的状态信息,但用户没有订阅联系人的状态信息

o Both -- both the user and the contact have subscriptions to each other's presence information (i.e., the union of 'from' and 'to')

o 两者——用户和联系人都订阅了对方的状态信息(即“from”和“to”的联合)

Each of these states is reflected in the roster of both the user and the contact, thus resulting in durable subscription states.

这些状态中的每一个都反映在用户和联系人的名册中,从而产生持久的订阅状态。

Narrative explanations of how these subscription states interact with roster items in order to complete certain defined use cases are provided in the following sub-sections. Full details regarding server and client handling of all subscription states (including pending states between the primary states listed above) is provided in Subscription States (Section 9).

以下小节提供了关于这些订阅状态如何与花名册项目交互以完成某些已定义用例的叙述性解释。有关服务器和客户端处理所有订阅状态(包括上面列出的主要状态之间的挂起状态)的完整详细信息,请参见订阅状态(第9节)。

The server MUST NOT send presence subscription requests or roster pushes to unavailable resources, nor to available resources that have not requested the roster.

服务器不得向不可用资源或未请求花名册的可用资源发送状态订阅请求或花名册推送。

The 'from' and 'to' addresses are OPTIONAL in roster pushes; if included, their values SHOULD be the full JID of the resource for that session. A client MUST acknowledge each roster push with an IQ stanza of type "result" (for the sake of brevity, these stanzas are not shown in the following examples but are required by the IQ semantics defined in [XMPP-CORE]).

“发件人”和“收件人”地址在列表中是可选的;如果包含,则它们的值应该是该会话资源的完整JID。客户机必须使用类型为“result”的IQ节确认每个花名册推送(为简洁起见,以下示例中未显示这些节,但[XMPP-CORE]中定义的IQ语义需要这些节)。

8.2. User Subscribes to Contact
8.2. 用户订阅联系人

The process by which a user subscribes to a contact, including the interaction between roster items and subscription states, is described below.

下面描述用户订阅联系人的过程,包括花名册项目和订阅状态之间的交互。

1. In preparation for being able to render the contact in the user's client interface and for the server to keep track of the subscription, the user's client SHOULD perform a "roster set" for the new roster item. This request consists of sending an IQ stanza of type='set' containing a <query/> element qualified by the 'jabber:iq:roster' namespace, which in turn contains an <item/> element that defines the new roster item; the <item/> element MUST possess a 'jid' attribute, MAY possess a 'name' attribute, MUST NOT possess a 'subscription' attribute, and MAY contain one or more <group/> child elements:

1. 为了能够在用户的客户端界面中呈现联系人,并让服务器跟踪订阅,用户的客户端应该为新的花名册项目执行“花名册设置”。此请求包括发送一个class='set'类型的IQ节,该节包含一个由'jabber:IQ:花名册'名称空间限定的<query/>元素,该名称空间又包含一个定义新花名册项目的<item/>元素;<item/>元素必须具有“jid”属性,可以具有“name”属性,不能具有“subscription”属性,并且可以包含一个或多个<group/>子元素:

   <iq type='set' id='set1'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set' id='set1'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        

2. As a result, the user's server (1) MUST initiate a roster push for the new roster item to all available resources associated with this user that have requested the roster, setting the 'subscription' attribute to a value of "none"; and (2) MUST reply to the sending resource with an IQ result indicating the success of the roster set:

2. 因此,用户的服务器(1)必须启动一次花名册推送,将新花名册项目推送到与请求花名册的该用户关联的所有可用资源,将“订阅”属性设置为“无”;和(2)必须使用IQ结果回复发送资源,该IQ结果指示花名册集的成功:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='result' id='set1'/>
        
   <iq type='result' id='set1'/>
        

3. If the user wants to request a subscription to the contact's presence information, the user's client MUST send a presence stanza of type='subscribe' to the contact:

3. 如果用户希望请求订阅联系人的状态信息,则用户的客户端必须向联系人发送class='subscribe'类型的状态节:

   <presence to='contact@example.org' type='subscribe'/>
        
   <presence to='contact@example.org' type='subscribe'/>
        

4. As a result, the user's server MUST initiate a second roster push to all of the user's available resources that have requested the roster, setting the contact to the pending sub-state of the 'none' subscription state; this pending sub-state is denoted by the inclusion of the ask='subscribe' attribute in the roster item:

4. 因此,用户的服务器必须启动第二次花名册推送,将联系人设置为“无”订阅状态的挂起子状态,推送到已请求花名册的用户的所有可用资源;此挂起子状态通过在花名册项目中包含ask='subscribe'属性来表示:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           ask='subscribe'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           ask='subscribe'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        

Note: If the user did not create a roster item before sending the subscription request, the server MUST now create one on behalf of the user, then send a roster push to all of the user's available resources that have requested the roster, absent the 'name' attribute and the <group/> child shown above.

注意:如果用户在发送订阅请求之前没有创建花名册项目,那么服务器现在必须代表用户创建一个花名册项目,然后向请求花名册的所有用户可用资源发送花名册推送,而不包括“name”属性和上面显示的<group/>子项。

5. The user's server MUST also stamp the presence stanza of type "subscribe" with the user's bare JID (i.e., <user@example.com>) as the 'from' address (if the user provided a 'from' address set to the user's full JID, the server SHOULD remove the resource identifier). If the contact is served by a different host than the user, the user's server MUST route the presence stanza to the contact's server for delivery to the contact (this case is assumed throughout; however, if the contact is served by the same host, then the server can simply deliver the presence stanza directly):

5. 用户服务器还必须使用用户的裸JID(即<user@example.com>)作为“发件人”地址(如果用户提供了设置为用户完整JID的“发件人”地址,则服务器应删除资源标识符)。如果联系人由不同于用户的主机提供服务,则用户的服务器必须将状态节路由到联系人的服务器,以便将状态节传递给联系人(这种情况自始至终都是假设的;但是,如果联系人由同一主机提供服务,则服务器可以直接传递状态节):

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='subscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='subscribe'/>
        

Note: If the user's server receives a presence stanza of type "error" from the contact's server, it MUST deliver the error stanza to the user, whose client MAY determine that the error is in response to the outgoing presence stanza of type "subscribe" it sent previously (e.g., by tracking an 'id' attribute) and then choose to resend the "subscribe" request or revert the roster to its previous state by sending a presence stanza of type "unsubscribe" to the contact.

注意:如果用户服务器从联系人服务器接收到类型为“error”的状态节,则必须将该错误节发送给用户,用户的客户端可能会确定该错误是对其先前发送的类型为“subscribe”的传出状态节的响应(例如,通过跟踪“id”属性),然后选择重新发送“subscribe”通过向联系人发送类型为“unsubscribe”的状态节,请求或将花名册恢复到以前的状态。

6. Upon receiving the presence stanza of type "subscribe" addressed to the contact, the contact's server MUST determine if there is at least one available resource from which the contact has requested the roster. If so, it MUST deliver the subscription request to the contact (if not, the contact's server MUST store the subscription request offline for delivery when this condition

6. 在收到发送给联系人的类型为“订阅”的状态节后,联系人的服务器必须确定是否至少有一个可用资源可供联系人请求花名册。如果是,则必须将订阅请求传递给联系人(如果不是,则联系人的服务器必须脱机存储订阅请求,以便在出现此情况时进行传递)

is next met; normally this is done by adding a roster item for the contact to the user's roster, with a state of "None + Pending In" as defined under Subscription States (Section 9), however a server SHOULD NOT push or deliver roster items in that state to the contact). No matter when the subscription request is delivered, the contact must decide whether or not to approve it (subject to the contact's configured preferences, the contact's client MAY approve or refuse the subscription request without presenting it to the contact). Here we assume the "happy path" that the contact approves the subscription request (the alternate flow of declining the subscription request is defined in Section 8.2.1). In this case, the contact's client (1) SHOULD perform a roster set specifying the desired nickname and group for the user (if any); and (2) MUST send a presence stanza of type "subscribed" to the user in order to approve the subscription request.

是下一次见面;通常,这是通过将联系人的花名册项目添加到用户的花名册中来实现的,其状态为“无+待定”,如订阅状态(第9节)所定义,但是服务器不应将处于该状态的花名册项目推送或交付给联系人)。无论何时提交订阅请求,联系人都必须决定是否批准订阅请求(根据联系人配置的首选项,联系人的客户可以批准或拒绝订阅请求,而无需向联系人出示)。在此,我们假设联系人批准订阅请求的“快乐路径”(第8.2.1节定义了拒绝订阅请求的备选流程)。在这种情况下,联系人的客户端(1)应该执行一个花名册集,为用户指定所需的昵称和组(如果有);和(2)必须向用户发送类型为“subscribed”的状态节,以便批准订阅请求。

   <iq type='set' id='set2'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set' id='set2'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence to='user@example.com' type='subscribed'/>
        
   <presence to='user@example.com' type='subscribed'/>
        

7. As a result, the contact's server (1) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, containing a roster item for the user with the subscription state set to 'from' (the server MUST send this even if the contact did not perform a roster set); (2) MUST return an IQ result to the sending resource indicating the success of the roster set; (3) MUST route the presence stanza of type "subscribed" to the user, first stamping the 'from' address as the bare JID (<contact@example.org>) of the contact; and (4) MUST send available presence from all of the contact's available resources to the user:

7. 因此,联系人的服务器(1)必须启动与请求名册的联系人相关联的所有可用资源的名册推送,其中包含用户的名册项目,订阅状态设置为“发件人”(即使联系人未执行名册设置,服务器也必须发送此项);(2) 必须向发送资源返回一个IQ结果,表明花名册设置成功;(3) 必须将类型为“subscribed”的状态节发送给用户,首先将“from”地址标记为裸JID(<contact@example.org>)联系方式;和(4)必须从联系人的所有可用资源向用户发送可用状态:

   <iq type='set' to='contact@example.org/resource'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='from'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set' to='contact@example.org/resource'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='from'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='result' to='contact@example.org/resource' id='set2'/>
        
   <iq type='result' to='contact@example.org/resource' id='set2'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='subscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='subscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'/>
        

Note: If the contact's server receives a presence stanza of type "error" from the user's server, it MUST deliver the error stanza to the contact, whose client MAY determine that the error is in response to the outgoing presence stanza of type "subscribed" it sent previously (e.g., by tracking an 'id' attribute) and then choose to resend the "subscribed" notification or revert the roster to its previous state by sending a presence stanza of type "unsubscribed" to the user.

注意:如果联系人的服务器从用户的服务器接收到类型为“error”的状态节,则必须将错误节传递给联系人,其客户端可能会确定错误是对其先前发送的类型为“subscribed”的传出状态节的响应(例如,通过跟踪“id”属性),然后选择重新发送错误“已订阅”通知,或通过向用户发送类型为“未订阅”的状态节,将花名册恢复到以前的状态。

8. Upon receiving the presence stanza of type "subscribed" addressed to the user, the user's server MUST first verify that the contact is in the user's roster with either of the following states: (a) subscription='none' and ask='subscribe' or (b) subscription='from' and ask='subscribe'. If the contact is not in the user's roster with either of those states, the user's server MUST silently ignore the presence stanza of type "subscribed" (i.e., it MUST NOT route it to the user, modify the user's roster, or generate a roster push to the user's available resources). If the contact is in the user's roster with either of those states, the user's server (1) MUST deliver the presence stanza of type "subscribed" from the contact to the user; (2) MUST initiate a roster push to all of the user's available resources that have requested the roster, containing an updated roster item for the contact with the 'subscription' attribute set

8. 在收到发送给用户的类型为“subscribed”的状态节后,用户服务器必须首先验证联系人是否在用户名册中,且状态为:(a)subscription='none'和ask='subscribe'或(b)subscription='from'和ask='subscribe'。如果联系人不在用户的花名册中,且处于上述任何一种状态,则用户服务器必须默默地忽略类型为“subscribed”的状态节(即,它不得将其路由到用户、修改用户花名册或生成花名册推送到用户的可用资源)。如果联系人在用户名册中,且处于上述任一状态,则用户服务器(1)必须将联系人的“已订阅”类型的状态节发送给用户;(2) 必须启动花名册推送,推送到已请求花名册的用户的所有可用资源,其中包含“订阅”属性集联系人的更新花名册项目

to a value of "to"; and (3) MUST deliver the available presence stanza received from each of the contact's available resources to each of the user's available resources:

至“至”值;和(3)必须将从每个联系人的可用资源收到的可用状态节传递给每个用户的可用资源:

   <presence
       to='user@example.com'
       from='contact@example.org'
       type='subscribed'/>
        
   <presence
       to='user@example.com'
       from='contact@example.org'
       type='subscribed'/>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='to'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='to'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com/resource'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com/resource'/>
        

9. Upon receiving the presence stanza of type "subscribed", the user SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "subscribe" to the contact or "denying" it by sending a presence stanza of type "unsubscribe" to the contact; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the user's server know that it MUST no longer send notification of the subscription state change to the user (see Section 9.4).

9. 在收到类型为“订阅”的状态节时,用户应通过向联系人发送类型为“订阅”的状态节来“确认”该状态通知,或通过向联系人发送类型为“取消订阅”的状态节来“拒绝”该状态通知,以确认收到该订阅状态通知;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让用户的服务器知道它不能再向用户发送订阅状态更改的通知(请参阅第9.4节)。

From the perspective of the user, there now exists a subscription to the contact's presence information; from the perspective of the contact, there now exists a subscription from the user.

从用户的角度来看,现在存在对联系人的状态信息的订阅;从联系人的角度来看,现在存在来自用户的订阅。

8.2.1. Alternate Flow: Contact Declines Subscription Request
8.2.1. 备选流程:联系人拒绝订阅请求

The above activity flow represents the "happy path" regarding the user's subscription request to the contact. The main alternate flow occurs if the contact refuses the user's subscription request, as described below.

上面的活动流表示关于用户对联系人的订阅请求的“快乐路径”。如果联系人拒绝用户的订阅请求,则会出现主备用流,如下所述。

1. If the contact wants to refuse the request, the contact's client MUST send a presence stanza of type "unsubscribed" to the user (instead of the presence stanza of type "subscribed" sent in Step 6 of Section 8.2):

1. 如果联系人想要拒绝请求,联系人的客户端必须向用户发送类型为“unsubscribed”的状态节(而不是在第8.2节的步骤6中发送类型为“subscribed”的状态节):

   <presence to='user@example.com' type='unsubscribed'/>
        
   <presence to='user@example.com' type='unsubscribed'/>
        

2. As a result, the contact's server MUST route the presence stanza of type "unsubscribed" to the user, first stamping the 'from' address as the bare JID (<contact@example.org>) of the contact:

2. 因此,联系人的服务器必须将类型为“unsubscribed”的状态节路由给用户,首先将“from”地址标记为裸JID(<contact@example.org>)联系人姓名:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        

Note: If the contact's server previously added the user to the contact's roster for tracking purposes, it MUST remove the relevant item at this time.

注意:如果联系人的服务器先前出于跟踪目的将用户添加到联系人的花名册中,则此时必须删除相关项目。

3. Upon receiving the presence stanza of type "unsubscribed" addressed to the user, the user's server (1) MUST deliver that presence stanza to the user and (2) MUST initiate a roster push to all of the user's available resources that have requested the roster, containing an updated roster item for the contact with the 'subscription' attribute set to a value of "none" and with no 'ask' attribute:

3. 在接收到发送给用户的类型为“unsubscribed”的状态节后,用户服务器(1)必须将该状态节交付给用户,并且(2)必须启动对请求该花名册的用户的所有可用资源的花名册推送,包含“订阅”属性设置为“无”且没有“询问”属性的联系人的更新花名册项目:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        

4. Upon receiving the presence stanza of type "unsubscribed", the user SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribe" to the contact or "denying" it by

4. 在收到类型为“unsubscribed”的状态节后,用户应通过向联系人发送类型为“unsubscribe”的状态节来“确认”该状态通知,或通过发送类型为“unsubscribe”的状态节来“拒绝”该状态通知来确认收到该状态通知

sending a presence stanza of type "subscribe" to the contact; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the user's server know that it MUST no longer send notification of the subscription state change to the user (see Section 9.4).

向联系人发送类型为“订阅”的状态节;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让用户的服务器知道它不能再向用户发送订阅状态更改的通知(请参阅第9.4节)。

As a result of this activity, the contact is now in the user's roster with a subscription state of "none", whereas the user is not in the contact's roster at all.

此活动的结果是,联系人现在在用户的名册中,订阅状态为“无”,而用户根本不在联系人的名册中。

8.3. Creating a Mutual Subscription
8.3. 创建相互订阅

The user and contact can build on the "happy path" described above to create a mutual subscription (i.e., a subscription of type "both"). The process is described below.

用户和联系人可以基于上述“快乐路径”创建相互订阅(即,类型为“两者”的订阅)。该过程描述如下。

1. If the contact wants to create a mutual subscription, the contact MUST send a subscription request to the user (subject to the contact's configured preferences, the contact's client MAY send this automatically):

1. 如果联系人希望创建相互订阅,则联系人必须向用户发送订阅请求(根据联系人配置的首选项,联系人的客户端可能会自动发送):

   <presence to='user@example.com' type='subscribe'/>
        
   <presence to='user@example.com' type='subscribe'/>
        

2. As a result, the contact's server (1) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, with the user still in the 'from' subscription state but with a pending 'to' subscription denoted by the inclusion of the ask='subscribe' attribute in the roster item; and (2) MUST route the presence stanza of type "subscribe" to the user, first stamping the 'from' address as the bare JID (<contact@example.org>) of the contact:

2. 因此,联系人的服务器(1)必须启动与请求名册的联系人相关联的所有可用资源的名册推送,用户仍处于“from”订阅状态,但通过在名册项目中包含ask='subscribe'属性来表示待定的“to”订阅;和(2)必须将类型为“subscribe”的状态节路由给用户,首先将“from”地址标记为裸JID(<contact@example.org>)联系人姓名:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='from'
           ask='subscribe'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='from'
           ask='subscribe'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='subscribe'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='subscribe'/>
        

Note: If the contact's server receives a presence stanza of type "error" from the user's server, it MUST deliver the error stanza to the contact, whose client MAY determine that the error is in response to the outgoing presence stanza of type "subscribe" it sent previously (e.g., by tracking an 'id' attribute) and then choose to resend the "subscribe" request or revert the roster to its previous state by sending a presence stanza of type "unsubscribe" to the user.

注意:如果联系人的服务器从用户服务器接收到类型为“error”的状态节,则必须将该错误节发送给联系人,其客户端可能会确定该错误是对其先前发送的类型为“subscribe”的传出状态节的响应(例如,通过跟踪“id”属性),然后选择重新发送“订阅”请求或通过向用户发送类型为“取消订阅”的状态节,将花名册恢复到以前的状态。

3. Upon receiving the presence stanza of type "subscribe" addressed to the user, the user's server must determine if there is at least one available resource for which the user has requested the roster. If so, the user's server MUST deliver the subscription request to the user (if not, it MUST store the subscription request offline for delivery when this condition is next met). No matter when the subscription request is delivered, the user must then decide whether or not to approve it (subject to the user's configured preferences, the user's client MAY approve or refuse the subscription request without presenting it to the user). Here we assume the "happy path" that the user approves the subscription request (the alternate flow of declining the subscription request is defined in Section 8.3.1). In this case, the user's client MUST send a presence stanza of type "subscribed" to the contact in order to approve the subscription request.

3. 在收到发送给用户的“subscribe”类型的presence节后,用户的服务器必须确定用户是否至少有一个可用资源请求了花名册。如果是,则用户的服务器必须将订阅请求传递给用户(如果不是,则必须脱机存储订阅请求,以便下次满足此条件时进行传递)。无论何时提交订阅请求,用户都必须决定是否批准(根据用户配置的首选项,用户的客户端可以批准或拒绝订阅请求,而无需向用户出示)。在此,我们假设用户批准订阅请求的“快乐路径”(第8.3.1节定义了拒绝订阅请求的备选流程)。在这种情况下,用户的客户端必须向联系人发送类型为“subscribed”的状态节,以便批准订阅请求。

   <presence to='contact@example.org' type='subscribed'/>
        
   <presence to='contact@example.org' type='subscribed'/>
        

4. As a result, the user's server (1) MUST initiate a roster push to all of the user's available resources that have requested the roster, containing a roster item for the contact with the 'subscription' attribute set to a value of "both"; (2) MUST route the presence stanza of type "subscribed" to the contact, first stamping the 'from' address as the bare JID (<user@example.com>) of the user; and (3) MUST send to the contact the full XML of the last presence stanza with no 'to' attribute received by the server from each of the user's available resources (subject to privacy lists in force for each session):

4. 因此,用户的服务器(1)必须启动花名册推送,将花名册推送至已请求花名册的用户的所有可用资源,其中包含联系人的花名册项目,且“订阅”属性的值设置为“两者”;(2) 必须将“subscribed”类型的状态节发送给联系人,首先在“from”地址上加盖裸JID印章(<user@example.com>)用户的身份;和(3)必须向联系人发送服务器从每个用户的可用资源(根据每个会话有效的隐私列表)接收到的最后一个状态节的完整XML,该状态节没有“to”属性:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='both'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='both'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='subscribed'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='subscribed'/>
        
   <presence
       from='user@example.com/resource'
       to='contact@example.org'/>
        
   <presence
       from='user@example.com/resource'
       to='contact@example.org'/>
        

Note: If the user's server receives a presence stanza of type "error" from the contact's server, it MUST deliver the error stanza to the user, whose client MAY determine that the error is in response to the outgoing presence stanza of type "subscribed" it sent previously (e.g., by tracking an 'id' attribute) and then choose to resend the subscription request or revert the roster to its previous state by sending a presence stanza of type "unsubscribed" to the contact.

注意:如果用户的服务器从联系人的服务器接收到类型为“error”的状态节,则必须将该错误节传递给用户,用户的客户端可能会确定该错误是对其先前发送的类型为“subscribed”的传出状态节的响应(例如,通过跟踪“id”属性)然后选择重新发送订阅请求,或通过向联系人发送类型为“unsubscribed”的状态节,将花名册恢复到以前的状态。

5. Upon receiving the presence stanza of type "subscribed" addressed to the contact, the contact's server MUST first verify that the user is in the contact's roster with either of the following states: (a) subscription='none' and ask='subscribe' or (b) subscription='from' and ask='subscribe'. If the user is not in the contact's roster with either of those states, the contact's server MUST silently ignore the presence stanza of type "subscribed" (i.e., it MUST NOT route it to the contact, modify the contact's roster, or generate a roster push to the contact's available resources). If the user is in the contact's roster with either of those states, the contact's server (1) MUST deliver the presence stanza of type "subscribed" from the user to the contact; (2) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "both"; and (3) MUST deliver the available presence stanza received from each of the user's available resources to each of the contact's available resources:

5. 收到发送给联系人的类型为“subscribed”的状态节后,联系人的服务器必须首先验证该用户是否在联系人的名册中,并具有以下状态之一:(a)subscription='none'和ask='subscribe'或(b)subscription='from'和ask='subscribe'。如果用户不在联系人的花名册中,则联系人的服务器必须悄悄忽略类型为“subscribed”的状态节(即,它不得将其路由到联系人、修改联系人花名册或生成花名册推送到联系人的可用资源)。如果用户在联系人的名册中,且处于上述任一状态,则联系人的服务器(1)必须将“已订阅”类型的状态节从用户发送给联系人;(2) 必须启动与请求花名册的联系人相关联的所有可用资源的花名册推送,其中包含用户的更新花名册项目,且“订阅”属性的值设置为“两者”;和(3)必须将从每个用户的可用资源接收到的可用状态节传递给每个联系人的可用资源:

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='subscribed'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='subscribed'/>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='both'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='both'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com/resource'
       to='contact@example.org/resource'/>
        
   <presence
       from='user@example.com/resource'
       to='contact@example.org/resource'/>
        

6. Upon receiving the presence stanza of type "subscribed", the contact SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "subscribe" to the user or "denying" it by sending a presence stanza of type "unsubscribe" to the user; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the contact's server know that it MUST no longer send notification of the subscription state change to the contact (see Section 9.4).

6. 收到“订阅”类型的状态节后,联系人应通过向用户发送“订阅”类型的状态节来“确认”该状态通知,或通过向用户发送“取消订阅”类型的状态节来“拒绝”该状态通知,以确认收到该订阅状态通知;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让联系人的服务器知道它不能再向联系人发送订阅状态更改的通知(请参阅第9.4节)。

The user and the contact now have a mutual subscription to each other's presence -- i.e., the subscription is of type "both".

用户和联系人现在相互订阅对方的状态,即订阅类型为“两者”。

8.3.1. Alternate Flow: User Declines Subscription Request
8.3.1. 备用流:用户拒绝订阅请求

The above activity flow represents the "happy path" regarding the contact's subscription request to the user. The main alternate flow occurs if the user refuses the contact's subscription request, as described below.

上述活动流表示联系人向用户提出订阅请求的“快乐路径”。如果用户拒绝联系人的订阅请求,则会出现主备用流,如下所述。

1. If the user wants to refuse the request, the user's client MUST send a presence stanza of type "unsubscribed" to the contact (instead of the presence stanza of type "subscribed" sent in Step 3 of Section 8.3):

1. 如果用户想要拒绝请求,用户的客户端必须向联系人发送类型为“unsubscribed”的状态节(而不是在第8.3节的步骤3中发送类型为“subscribed”的状态节):

   <presence to='contact@example.org' type='unsubscribed'/>
        
   <presence to='contact@example.org' type='unsubscribed'/>
        

2. As a result, the user's server MUST route the presence stanza of type "unsubscribed" to the contact, first stamping the 'from' address as the bare JID (<user@example.com>) of the user:

2. 因此,用户服务器必须将类型为“unsubscribed”的状态节路由到联系人,首先将“from”地址标记为裸JID(<user@example.com>)用户名称:

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        

3. Upon receiving the presence stanza of type "unsubscribed" addressed to the contact, the contact's server (1) MUST deliver that presence stanza to the contact; and (2) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "from" and with no 'ask' attribute:

3. 收到发送给联系人的类型为“unsubscribed”的状态节后,联系人的服务器(1)必须将该状态节发送给联系人;和(2)必须启动与请求花名册的联系人相关的所有可用资源的花名册推送,其中包含用户的更新花名册项目,其“订阅”属性设置为值“自”,且没有“询问”属性:

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='from'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='from'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        

4. Upon receiving the presence stanza of type "unsubscribed", the contact SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribe" to the user or "denying" it by sending a presence stanza of type "subscribe" to the user; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the contact's server know that it MUST no longer send notification of the subscription state change to the contact (see Section 9.4).

4. 收到类型为“unsubscribed”的状态节后,联系人应通过向用户发送类型为“unsubscribe”的状态节来“确认”该状态通知,或通过向用户发送类型为“subscribe”的状态节来“拒绝”该状态通知,以确认收到该订阅状态通知;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让联系人的服务器知道它不能再向联系人发送订阅状态更改的通知(请参阅第9.4节)。

As a result of this activity, there has been no change in the subscription state; i.e., the contact is in the user's roster with a subscription state of "to" and the user is in the contact's roster with a subscription state of "from".

由于此活动,订阅状态没有任何变化;i、 例如,联系人在用户名册中,订阅状态为“至”,用户在联系人名册中,订阅状态为“自”。

8.4. Unsubscribing
8.4. 退订

At any time after subscribing to a contact's presence information, a user MAY unsubscribe. While the XML that the user sends to make this happen is the same in all instances, the subsequent subscription state is different depending on the subscription state obtaining when the unsubscribe "command" is sent. Both possible scenarios are described below.

在订阅联系人的状态信息后的任何时候,用户都可以取消订阅。虽然用户为实现这一点而发送的XML在所有实例中都是相同的,但随后的订阅状态会有所不同,这取决于发送取消订阅“命令”时获得的订阅状态。下面描述了两种可能的情况。

8.4.1. Case #1: Unsubscribing When Subscription is Not Mutual
8.4.1. 案例#1:非共同订阅时取消订阅

In the first case, the user has a subscription to the contact's presence information but the contact does not have a subscription to the user's presence information (i.e., the subscription is not yet mutual).

在第一种情况下,用户具有对联系人的存在信息的订阅,但是联系人没有对用户的存在信息的订阅(即,订阅还不是相互的)。

1. If the user wants to unsubscribe from the contact's presence information, the user MUST send a presence stanza of type "unsubscribe" to the contact:

1. 如果用户想要取消订阅联系人的状态信息,则用户必须向联系人发送类型为“unsubscribe”的状态节:

   <presence to='contact@example.org' type='unsubscribe'/>
        
   <presence to='contact@example.org' type='unsubscribe'/>
        

2. As a result, the user's server (1) MUST send a roster push to all of the user's available resources that have requested the roster, containing an updated roster item for the contact with the 'subscription' attribute set to a value of "none"; and (2) MUST route the presence stanza of type "unsubscribe" to the contact, first stamping the 'from' address as the bare JID (<user@example.com>) of the user:

2. 因此,用户服务器(1)必须向请求花名册的所有用户可用资源发送花名册推送,其中包含联系人的更新花名册项目,且“订阅”属性设置为“无”;和(2)必须将“取消订阅”类型的“出席”节发送给联系人,首先在“发件人”地址上加盖裸JID印章(<user@example.com>)用户名称:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        

3. Upon receiving the presence stanza of type "unsubscribe" addressed to the contact, the contact's server (1) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "none" (if the contact is unavailable or has not requested the roster, the contact's server MUST modify the roster item and send that modified item the next time the contact requests the roster); and (2) MUST deliver the "unsubscribe" state change notification to the contact:

3. 收到发送给联系人的类型为“unsubscribe”的状态节后,联系人的服务器(1)必须启动花名册推送,推送到与请求花名册的联系人相关联的所有可用资源,其中包含用户的更新花名册项,且“subscription”属性设置为“none”(如果联系人不可用或未请求花名册,则联系人的服务器必须修改花名册项目,并在联系人下次请求花名册时发送修改后的项目);以及(2)必须向联系人发送“取消订阅”状态更改通知:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        

4. Upon receiving the presence stanza of type "unsubscribe", the contact SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribed" to the user or "denying" it by sending a presence stanza of type "subscribed" to the user; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the contact's server know that it MUST no longer send notification of the subscription state change to the contact (see Section 9.4).

4. 收到类型为“取消订阅”的状态节后,联系人应通过向用户发送类型为“取消订阅”的状态节来“确认”该状态通知,或通过向用户发送类型为“已订阅”的状态节来“拒绝”该状态通知;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让联系人的服务器知道它不能再向联系人发送订阅状态更改的通知(请参阅第9.4节)。

5. The contact's server then (1) MUST send a presence stanza of type "unsubscribed" to the user; and (2) SHOULD send unavailable presence from all of the contact's available resources to the user:

5. 联系人的服务器(1)必须向用户发送类型为“unsubscribed”的状态节;和(2)应将联系人所有可用资源中的不可用状态发送给用户:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

6. When the user's server receives the presence stanzas of type "unsubscribed" and "unavailable", it MUST deliver them to the user:

6. 当用户的服务器收到类型为“未订阅”和“不可用”的状态节时,它必须将它们发送给用户:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

7. Upon receiving the presence stanza of type "unsubscribed", the user SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribe" to the contact or "denying" it by sending a presence stanza of type "subscribe" to the contact; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the user's server know that it MUST no longer send notification of the subscription state change to the user (see Section 9.4).

7. 在收到类型为“unsubscribed”的状态节后,用户应通过向联系人发送类型为“unsubscribe”的状态节来“确认”该状态通知,或通过向联系人发送类型为“subscribe”的状态节来“拒绝”该状态通知,以确认收到该订阅状态通知;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让用户的服务器知道它不能再向用户发送订阅状态更改的通知(请参阅第9.4节)。

8.4.2. Case #2: Unsubscribing When Subscription is Mutual
8.4.2. 案例#2:双方共同订阅时取消订阅

In the second case, the user has a subscription to the contact's presence information and the contact also has a subscription to the user's presence information (i.e., the subscription is mutual).

在第二种情况下,用户具有对联系人的存在信息的订阅,并且联系人还具有对用户的存在信息的订阅(即,订阅是相互的)。

1. If the user wants to unsubscribe from the contact's presence information, the user MUST send a presence stanza of type "unsubscribe" to the contact:

1. 如果用户想要取消订阅联系人的状态信息,则用户必须向联系人发送类型为“unsubscribe”的状态节:

   <presence to='contact@example.org' type='unsubscribe'/>
        
   <presence to='contact@example.org' type='unsubscribe'/>
        

2. As a result, the user's server (1) MUST send a roster push to all of the user's available resources that have requested the roster, containing an updated roster item for the contact with the 'subscription' attribute set to a value of "from"; and (2) MUST route the presence stanza of type "unsubscribe" to the contact, first stamping the 'from' address as the bare JID (<user@example.com>) of the user:

2. 因此,用户的服务器(1)必须向请求花名册的用户的所有可用资源发送花名册推送,其中包含联系人的更新花名册项目,且“订阅”属性设置为“发件人”;和(2)必须将“取消订阅”类型的“出席”节发送给联系人,首先在“发件人”地址上加盖裸JID印章(<user@example.com>)用户名称:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='from'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='from'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        

3. Upon receiving the presence stanza of type "unsubscribe" addressed to the contact, the contact's server (1) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "to" (if the contact is unavailable or has not requested the roster, the contact's server MUST modify the roster item and send that modified item the next time the contact requests the roster); and (2) MUST deliver the "unsubscribe" state change notification to the contact:

3. 收到发送给联系人的类型为“unsubscribe”的状态节后,联系人的服务器(1)必须启动花名册推送,推送到与请求花名册的联系人相关联的所有可用资源,其中包含用户的更新花名册项,且“subscription”属性设置为“to”(如果联系人不可用或未请求花名册,则联系人的服务器必须修改花名册项目,并在联系人下次请求花名册时发送修改后的项目);以及(2)必须向联系人发送“取消订阅”状态更改通知:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        

4. Upon receiving the presence stanza of type "unsubscribe", the contact SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribed" to the user or "denying" it by sending a presence stanza of type "subscribed" to the user; this

4. 收到类型为“取消订阅”的状态节后,联系人应通过向用户发送类型为“取消订阅”的状态节来“确认”该状态通知,或通过向用户发送类型为“已订阅”的状态节来“拒绝”该状态通知;这

step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the contact's server know that it MUST no longer send notification of the subscription state change to the contact (see Section 9.4).

步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让联系人的服务器知道它不能再向联系人发送订阅状态更改的通知(请参阅第9.4节)。

5. The contact's server then (1) MUST send a presence stanza of type "unsubscribed" to the user; and (2) SHOULD send unavailable presence from all of the contact's available resources to the user:

5. 联系人的服务器(1)必须向用户发送类型为“unsubscribed”的状态节;和(2)应将联系人所有可用资源中的不可用状态发送给用户:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

6. When the user's server receives the presence stanzas of type "unsubscribed" and "unavailable", it MUST deliver them to the user:

6. 当用户的服务器收到类型为“未订阅”和“不可用”的状态节时,它必须将它们发送给用户:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

7. Upon receiving the presence stanza of type "unsubscribed", the user SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribe" to the contact or "denying" it by sending a presence stanza of type "subscribe" to the contact; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the user's server know that it MUST no longer send notification of the subscription state change to the user (see Section 9.4).

7. 在收到类型为“unsubscribed”的状态节后,用户应通过向联系人发送类型为“unsubscribe”的状态节来“确认”该状态通知,或通过向联系人发送类型为“subscribe”的状态节来“拒绝”该状态通知,以确认收到该订阅状态通知;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让用户的服务器知道它不能再向用户发送订阅状态更改的通知(请参阅第9.4节)。

Note: Obviously this does not result in removal of the roster item from the user's roster, and the contact still has a subscription to the user's presence information. In order to both completely cancel

注意:显然,这不会导致从用户的花名册中删除花名册项目,并且联系人仍然订阅了用户的状态信息。为了两者都完全取消

a mutual subscription and fully remove the roster item from the user's roster, the user SHOULD update the roster item with subscription='remove' as defined under Removing a Roster Item and Cancelling All Subscriptions (Section 8.6).

相互订阅并从用户的花名册中完全删除花名册项目时,用户应按照删除花名册项目和取消所有订阅(第8.6节)中的定义,使用subscription='remove'更新花名册项目。

8.5. Cancelling a Subscription
8.5. 取消订阅

At any time after approving a subscription request from a user, a contact MAY cancel that subscription. While the XML that the contact sends to make this happen is the same in all instances, the subsequent subscription state is different depending on the subscription state obtaining when the cancellation was sent. Both possible scenarios are described below.

在批准用户的订阅请求后的任何时候,联系人都可以取消该订阅。虽然联系人为实现此目的而发送的XML在所有实例中都是相同的,但随后的订阅状态会有所不同,具体取决于发送取消时获得的订阅状态。下面描述了两种可能的情况。

8.5.1. Case #1: Cancelling When Subscription is Not Mutual
8.5.1. 案例#1:当订阅不是相互的时取消

In the first case, the user has a subscription to the contact's presence information but the contact does not have a subscription to the user's presence information (i.e., the subscription is not yet mutual).

在第一种情况下,用户具有对联系人的存在信息的订阅,但是联系人没有对用户的存在信息的订阅(即,订阅还不是相互的)。

1. If the contact wants to cancel the user's subscription, the contact MUST send a presence stanza of type "unsubscribed" to the user:

1. 如果联系人想要取消用户的订阅,则联系人必须向用户发送类型为“unsubscribed”的状态节:

   <presence to='user@example.com' type='unsubscribed'/>
        
   <presence to='user@example.com' type='unsubscribed'/>
        

2. As a result, the contact's server (1) MUST send a roster push to all of the contact's available resources that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "none"; (2) MUST route the presence stanza of type "unsubscribed" to the user, first stamping the 'from' address as the bare JID (<contact@example.org>) of the contact; and (3) SHOULD send unavailable presence from all of the contact's available resources to the user:

2. 因此,联系人的服务器(1)必须向请求名册的联系人的所有可用资源发送名册推送,其中包含用户的更新名册项目,且“订阅”属性设置为“无”;(2) 必须将类型为“unsubscribed”的状态节发送给用户,首先将“from”地址标记为裸JID(<contact@example.org>)联系方式;和(3)应将联系人所有可用资源中的不可用状态发送给用户:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

3. Upon receiving the presence stanza of type "unsubscribed" addressed to the user, the user's server (1) MUST initiate a roster push to all of the user's available resources that have requested the roster, containing an updated roster item for the contact with the 'subscription' attribute set to a value of "none" (if the user is unavailable or has not requested the roster, the user's server MUST modify the roster item and send that modified item the next time the user requests the roster); (2) MUST deliver the "unsubscribed" state change notification to all of the user's available resources; and (3) MUST deliver the unavailable presence to all of the user's available resources:

3. 在收到发送给用户的类型为“unsubscribed”的状态节后,用户服务器(1)必须启动花名册推送,推送到请求花名册的用户的所有可用资源,其中包含联系人的更新花名册项目,且“subscription”属性设置为“none”(如果用户不可用或未请求花名册,则用户服务器必须修改花名册项目,并在用户下次请求花名册时发送修改后的项目);(2)必须向用户的所有可用资源发送“未订阅”状态更改通知;以及(3)必须将不可用状态传递给用户的所有可用资源:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

4. Upon receiving the presence stanza of type "unsubscribed", the user SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribe" to the contact or "denying" it by sending a presence stanza of type "subscribe" to the contact;

4. 在收到类型为“unsubscribed”的状态节后,用户应通过向联系人发送类型为“unsubscribe”的状态节来“确认”该状态通知,或通过向联系人发送类型为“subscribe”的状态节来“拒绝”该状态通知,以确认收到该订阅状态通知;

this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the user's server know that it MUST no longer send notification of the subscription state change to the user (see Section 9.4).

此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让用户的服务器知道它不能再向用户发送订阅状态更改的通知(请参阅第9.4节)。

8.5.2. Case #2: Cancelling When Subscription is Mutual
8.5.2. 案例2:当订阅是相互的时取消

In the second case, the user has a subscription to the contact's presence information and the contact also has a subscription to the user's presence information (i.e., the subscription is mutual).

在第二种情况下,用户具有对联系人的存在信息的订阅,并且联系人还具有对用户的存在信息的订阅(即,订阅是相互的)。

1. If the contact wants to cancel the user's subscription, the contact MUST send a presence stanza of type "unsubscribed" to the user:

1. 如果联系人想要取消用户的订阅,则联系人必须向用户发送类型为“unsubscribed”的状态节:

   <presence to='user@example.com' type='unsubscribed'/>
        
   <presence to='user@example.com' type='unsubscribed'/>
        

2. As a result, the contact's server (1) MUST send a roster push to all of the contact's available resources that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "to"; (2) MUST route the presence stanza of type "unsubscribed" to the user, first stamping the 'from' address as the bare JID (<contact@example.org>) of the contact; and (3) SHOULD send unavailable presence from all of the contact's available resources to all of the user's available resources:

2. 因此,联系人的服务器(1)必须向请求名册的联系人的所有可用资源发送名册推送,其中包含用户的更新名册项目,其“订阅”属性设置为“到”;(2) 必须将类型为“unsubscribed”的状态节发送给用户,首先将“from”地址标记为裸JID(<contact@example.org>)联系方式;和(3)应将不可用状态从联系人的所有可用资源发送到用户的所有可用资源:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

3. Upon receiving the presence stanza of type "unsubscribed" addressed to the user, the user's server (1) MUST initiate a roster push to all of the user's available resources that have requested the roster, containing an updated roster item for the contact with the 'subscription' attribute set to a value of "from" (if the user is unavailable or has not requested the roster, the user's server MUST modify the roster item and send that modified item the next time the user requests the roster); and (2) MUST deliver the "unsubscribed" state change notification to all of the user's available resources; and (3) MUST deliver the unavailable presence to all of the user's available resources:

3. 在收到发送给用户的类型为“unsubscribed”的状态节后,用户服务器(1)必须启动花名册推送,推送到请求花名册的用户的所有可用资源,其中包含联系人的更新花名册项目,且“subscription”属性设置为“from”(如果用户不可用或未请求花名册,则用户服务器必须修改花名册项目,并在用户下次请求花名册时发送修改后的项目);以及(2)必须向用户的所有可用资源发送“未订阅”状态更改通知;以及(3)必须将不可用状态传递给用户的所有可用资源:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='from'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='from'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>
        

4. Upon receiving the presence stanza of type "unsubscribed", the user SHOULD acknowledge receipt of that subscription state notification through either "affirming" it by sending a presence stanza of type "unsubscribe" to the contact or "denying" it by sending a presence stanza of type "subscribe" to the contact; this step does not necessarily affect the subscription state (see Subscription States (Section 9) for details), but instead lets the user's server know that it MUST no longer send notification of the subscription state change to the user (see Section 9.4).

4. 在收到类型为“unsubscribed”的状态节后,用户应通过向联系人发送类型为“unsubscribe”的状态节来“确认”该状态通知,或通过向联系人发送类型为“subscribe”的状态节来“拒绝”该状态通知,以确认收到该订阅状态通知;此步骤不一定会影响订阅状态(有关详细信息,请参阅订阅状态(第9节)),而是让用户的服务器知道它不能再向用户发送订阅状态更改的通知(请参阅第9.4节)。

Note: Obviously this does not result in removal of the roster item from the contact's roster, and the contact still has a subscription to the user's presence information. In order to both completely cancel a mutual subscription and fully remove the roster item from

注意:显然这不会导致从联系人的花名册中删除花名册项目,并且联系人仍然订阅了用户的状态信息。为了完全取消相互订阅并从中完全删除花名册项目

the contact's roster, the contact should update the roster item with subscription='remove' as defined under Removing a Roster Item and Cancelling All Subscriptions (Section 8.6).

联系人的花名册,联系人应使用subscription='remove'更新花名册项目,如删除花名册项目和取消所有订阅(第8.6节)中所定义。

8.6. Removing a Roster Item and Cancelling All Subscriptions
8.6. 删除花名册项目并取消所有订阅

Because there may be many steps involved in completely removing a roster item and cancelling subscriptions in both directions, the roster management protocol includes a "shortcut" method for doing so. The process may be initiated no matter what the current subscription state is by sending a roster set containing an item for the contact with the 'subscription' attribute set to a value of "remove":

由于完全删除花名册项目和取消双向订阅可能涉及许多步骤,因此花名册管理协议包括一种“快捷方式”方法。无论当前订阅状态如何,都可以通过将包含联系人项目的花名册集与“订阅”属性集的值“删除”来启动该过程:

   <iq type='set' id='remove1'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='remove'/>
     </query>
   </iq>
        
   <iq type='set' id='remove1'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='remove'/>
     </query>
   </iq>
        

When the user removes a contact from his or her roster by setting the 'subscription' attribute to a value of "remove", the user's server (1) MUST automatically cancel any existing presence subscription between the user and the contact (both 'to' and 'from' as appropriate); (2) MUST remove the roster item from the user's roster and inform all of the user's available resources that have requested the roster of the roster item removal; (3) MUST inform the resource that initiated the removal of success; and (4) SHOULD send unavailable presence from all of the user's available resources to the contact:

当用户通过将“订阅”属性设置为“删除”值从其名册中删除联系人时,用户服务器(1)必须自动取消用户与联系人之间的任何现有状态订阅(视情况而定,包括“至”和“自”);(2) 必须将花名册项目从用户花名册中删除,并通知所有请求删除花名册项目的用户可用资源;(3) 必须通知发起移除成功的资源;和(4)应将用户所有可用资源中的不可用状态发送给联系人:

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='remove'/>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='remove'/>
     </query>
   </iq>
        
   <iq type='result' id='remove1'/>
        
   <iq type='result' id='remove1'/>
        
   <presence
       from='user@example.com/resource'
       to='contact@example.org'
       type='unavailable'/>
        
   <presence
       from='user@example.com/resource'
       to='contact@example.org'
       type='unavailable'/>
        

Upon receiving the presence stanza of type "unsubscribe", the contact's server (1) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "to" (if the contact is unavailable or has not requested the roster, the contact's server MUST modify the roster item and send that modified item the next time the contact requests the roster); and (2) MUST also deliver the "unsubscribe" state change notification to all of the contact's available resources:

收到类型为“unsubscribe”的状态节后,联系人的服务器(1)必须启动与请求名册的联系人相关联的所有可用资源的名册推送,其中包含用户的更新名册项目,其“订阅”属性设置为“to”(如果联系人不可用或未请求花名册,则联系人的服务器必须修改花名册项目,并在联系人下次请求花名册时发送修改后的项目);以及(2)还必须向联系人的所有可用资源发送“取消订阅”状态更改通知:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>
        

Upon receiving the presence stanza of type "unsubscribed", the contact's server (1) MUST initiate a roster push to all available resources associated with the contact that have requested the roster, containing an updated roster item for the user with the 'subscription' attribute set to a value of "none" (if the contact is unavailable or has not requested the roster, the contact's server

收到类型为“unsubscribed”的状态节后,联系人的服务器(1)必须启动与请求名册的联系人相关联的所有可用资源的名册推送,其中包含用户的更新名册项目,且“subscription”属性设置为“none”(如果联系人不可用或未请求花名册,则该联系人的服务器

MUST modify the roster item and send that modified item the next time the contact requests the roster); and (2) MUST also deliver the "unsubscribe" state change notification to all of the contact's available resources:

必须修改花名册项目,并在联系人下次请求花名册时发送修改后的项目);和(2)还必须向联系人的所有可用资源发送“取消订阅”状态更改通知:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        
   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>
        

Upon receiving the presence stanza of type "unavailable" addressed to the contact, the contact's server MUST deliver the unavailable presence to all of the user's available resources:

收到发送给联系人的类型为“不可用”的状态节后,联系人的服务器必须将不可用状态发送给用户的所有可用资源:

   <presence
       from='user@example.com/resource'
       to='contact@example.org'
       type='unavailable'/>
        
   <presence
       from='user@example.com/resource'
       to='contact@example.org'
       type='unavailable'/>
        

Note: When the user removes the contact from the user's roster, the end state of the contact's roster is that the user is still in the contact's roster with a subscription state of "none"; in order to completely remove the roster item for the user, the contact needs to also send a roster removal request.

注意:当用户从用户名册中删除联系人时,联系人名册的结束状态为用户仍在联系人名册中,订阅状态为“无”;为了完全删除用户的花名册项目,联系人还需要发送花名册删除请求。

9. Subscription States
9. 订阅国

This section provides detailed information about subscription states and server handling of subscription-related presence stanzas (i.e., presence stanzas of type "subscribe", "subscribed", "unsubscribe", and "unsubscribed").

本节提供有关订阅相关状态节(即“订阅”、“订阅”、“取消订阅”和“取消订阅”类型的状态节)的订阅状态和服务器处理的详细信息。

9.1. Defined States
9.1. 定义状态

There are nine possible subscription states, which are described here from the user's (not contact's) perspective:

这里从用户(非联系人)的角度描述了九种可能的订阅状态:

1. "None" = contact and user are not subscribed to each other, and neither has requested a subscription from the other

1. “None”=联系人和用户未相互订阅,也未向对方请求订阅

2. "None + Pending Out" = contact and user are not subscribed to each other, and user has sent contact a subscription request but contact has not replied yet

2. “None+Pending Out”=联系人和用户未相互订阅,用户已向联系人发送订阅请求,但联系人尚未回复

3. "None + Pending In" = contact and user are not subscribed to each other, and contact has sent user a subscription request but user has not replied yet (note: contact's server SHOULD NOT push or deliver roster items in this state, but instead SHOULD wait until contact has approved subscription request from user)

3. “None+Pending In”=联系人和用户未相互订阅,联系人已向用户发送订阅请求,但用户尚未回复(注意:联系人的服务器不应在此状态下推送或传递花名册项目,而应等待联系人批准用户的订阅请求)

4. "None + Pending Out/In" = contact and user are not subscribed to each other, contact has sent user a subscription request but user has not replied yet, and user has sent contact a subscription request but contact has not replied yet

4. “None+Pending Out/In”=联系人和用户未相互订阅,联系人已向用户发送订阅请求,但用户尚未回复,用户已向联系人发送订阅请求,但联系人尚未回复

5. "To" = user is subscribed to contact (one-way)

5. “To”=用户已订阅联系人(单向)

6. "To + Pending In" = user is subscribed to contact, and contact has sent user a subscription request but user has not replied yet

6. “To+Pending In”=用户已订阅联系人,联系人已向用户发送订阅请求,但用户尚未回复

7. "From" = contact is subscribed to user (one-way)

7. “发件人”=联系人已订阅给用户(单向)

8. "From + Pending Out" = contact is subscribed to user, and user has sent contact a subscription request but contact has not replied yet

8. “From+Pending Out”=联系人已向用户订阅,用户已向联系人发送订阅请求,但联系人尚未回复

9. "Both" = user and contact are subscribed to each other (two-way)

9. “两者”=用户和联系人相互订阅(双向)

9.2. Server Handling of Outbound Presence Subscription Stanzas
9.2. 出站状态订阅节的服务器处理

Outbound presence subscription stanzas enable the user to manage his or her subscription to the contact's presence information (via the "subscribe" and "unsubscribe" types), and to manage the contact's access to the user's presence information (via the "subscribed" and "unsubscribed" types).

出站状态订阅节使用户能够管理其对联系人状态信息的订阅(通过“订阅”和“取消订阅”类型),以及管理联系人对用户状态信息的访问(通过“订阅”和“取消订阅”类型)。

Because it is possible for the user's server and the contact's server to lose synchronization regarding subscription states, the user's server MUST without exception route all outbound presence stanzas of type "subscribe" or "unsubscribe" to the contact so that the user is able to resynchronize his or her subscription to the contact's presence information if needed.

由于用户服务器和联系人服务器可能会丢失有关订阅状态的同步,因此用户服务器必须毫无例外地路由所有“订阅”或“取消订阅”类型的出站状态节发送到联系人,以便用户能够在需要时重新同步其对联系人状态信息的订阅。

The user's server SHOULD NOT route a presence stanza of type "subscribed" or "unsubscribed" to the contact if the stanza does not result in a subscription state change from the user's perspective, and MUST NOT make a state change. If the stanza results in a subscription state change, the user's server MUST route the stanza to the contact and MUST make the appropriate state change. These rules are summarized in the following tables.

如果“已订阅”或“未订阅”类型的状态节不会从用户的角度导致订阅状态更改,则用户的服务器不应将该状态节路由到联系人,并且不得进行状态更改。如果节导致订阅状态更改,则用户的服务器必须将节路由到联系人,并且必须进行适当的状态更改。下表总结了这些规则。

Table 1: Recommended handling of outbound "subscribed" stanzas

表1:出站“订阅”节的建议处理

   +----------------------------------------------------------------+
   |  EXISTING STATE          |  ROUTE?  |  NEW STATE               |
   +----------------------------------------------------------------+
   |  "None"                  |  no      |  no state change         |
   |  "None + Pending Out"    |  no      |  no state change         |
   |  "None + Pending In"     |  yes     |  "From"                  |
   |  "None + Pending Out/In" |  yes     |  "From + Pending Out"    |
   |  "To"                    |  no      |  no state change         |
   |  "To + Pending In"       |  yes     |  "Both"                  |
   |  "From"                  |  no      |  no state change         |
   |  "From + Pending Out"    |  no      |  no state change         |
   |  "Both"                  |  no      |  no state change         |
   +----------------------------------------------------------------+
        
   +----------------------------------------------------------------+
   |  EXISTING STATE          |  ROUTE?  |  NEW STATE               |
   +----------------------------------------------------------------+
   |  "None"                  |  no      |  no state change         |
   |  "None + Pending Out"    |  no      |  no state change         |
   |  "None + Pending In"     |  yes     |  "From"                  |
   |  "None + Pending Out/In" |  yes     |  "From + Pending Out"    |
   |  "To"                    |  no      |  no state change         |
   |  "To + Pending In"       |  yes     |  "Both"                  |
   |  "From"                  |  no      |  no state change         |
   |  "From + Pending Out"    |  no      |  no state change         |
   |  "Both"                  |  no      |  no state change         |
   +----------------------------------------------------------------+
        

Table 2: Recommended handling of outbound "unsubscribed" stanzas

表2:出站“未预订”节的建议处理

   +----------------------------------------------------------------+
   |  EXISTING STATE          |  ROUTE?  |  NEW STATE               |
   +----------------------------------------------------------------+
   |  "None"                  |  no      |  no state change         |
   |  "None + Pending Out"    |  no      |  no state change         |
   |  "None + Pending In"     |  yes     |  "None"                  |
   |  "None + Pending Out/In" |  yes     |  "None + Pending Out"    |
   |  "To"                    |  no      |  no state change         |
   |  "To + Pending In"       |  yes     |  "To"                    |
   |  "From"                  |  yes     |  "None"                  |
   |  "From + Pending Out"    |  yes     |  "None + Pending Out"    |
   |  "Both"                  |  yes     |  "To"                    |
   +----------------------------------------------------------------+
        
   +----------------------------------------------------------------+
   |  EXISTING STATE          |  ROUTE?  |  NEW STATE               |
   +----------------------------------------------------------------+
   |  "None"                  |  no      |  no state change         |
   |  "None + Pending Out"    |  no      |  no state change         |
   |  "None + Pending In"     |  yes     |  "None"                  |
   |  "None + Pending Out/In" |  yes     |  "None + Pending Out"    |
   |  "To"                    |  no      |  no state change         |
   |  "To + Pending In"       |  yes     |  "To"                    |
   |  "From"                  |  yes     |  "None"                  |
   |  "From + Pending Out"    |  yes     |  "None + Pending Out"    |
   |  "Both"                  |  yes     |  "To"                    |
   +----------------------------------------------------------------+
        
9.3. Server Handling of Inbound Presence Subscription Stanzas
9.3. 入站状态订阅节的服务器处理

Inbound presence subscription stanzas request a subscription-related action from the user (via the "subscribe" type), inform the user of subscription-related actions taken by the contact (via the "unsubscribe" type), or enable the contact to manage the user's access to the contact's presence information (via the "subscribed" and "unsubscribed" types).

入站状态订阅节向用户请求与订阅相关的操作(通过“订阅”类型),通知用户联系人采取的与订阅相关的操作(通过“取消订阅”类型),或使联系人能够管理用户对联系人状态信息的访问(通过“订阅”和“取消订阅”类型)。

When the user's server receives a subscription request for the user from the contact (i.e., a presence stanza of type "subscribe"), it MUST deliver that request to the user for approval if the user has not already granted the contact access to the user's presence information and if there is no pending inbound subscription request; however, the user's server SHOULD NOT deliver the new request if there is a pending inbound subscription request, since the previous subscription request will have been recorded. If the user has already granted the contact access to the user's presence information, the user's server SHOULD auto-reply to an inbound presence stanza of type "subscribe" from the contact by sending a presence stanza of type "subscribed" to the contact on behalf of the user; this rule enables the contact to resynchronize the subscription state if needed. These rules are summarized in the following table.

当用户的服务器从联系人处接收到用户的订阅请求(即,类型为“订阅”的状态节)时,如果用户尚未授予联系人访问用户状态信息的权限,并且如果没有未决的入站订阅请求,则必须将该请求交付给用户以供批准;但是,如果存在挂起的入站订阅请求,则用户的服务器不应传递新请求,因为以前的订阅请求将被记录。如果用户已经授权联系人访问用户的状态信息,则用户服务器应通过代表用户向联系人发送类型为“subscribed”的状态节,自动回复来自联系人的类型为“subscribe”的入站状态节;此规则允许联系人在需要时重新同步订阅状态。下表总结了这些规则。

Table 3: Recommended handling of inbound "subscribe" stanzas

表3:入站“订阅”节的建议处理

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  yes       |  "None + Pending In"     |
   |  "None + Pending Out"    |  yes       |  "None + Pending Out/In" |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  no        |  no state change         |
   |  "To"                    |  yes       |  "To + Pending In"       |
   |  "To + Pending In"       |  no        |  no state change         |
   |  "From"                  |  no *      |  no state change         |
   |  "From + Pending Out"    |  no *      |  no state change         |
   |  "Both"                  |  no *      |  no state change         |
   +------------------------------------------------------------------+
        
   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  yes       |  "None + Pending In"     |
   |  "None + Pending Out"    |  yes       |  "None + Pending Out/In" |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  no        |  no state change         |
   |  "To"                    |  yes       |  "To + Pending In"       |
   |  "To + Pending In"       |  no        |  no state change         |
   |  "From"                  |  no *      |  no state change         |
   |  "From + Pending Out"    |  no *      |  no state change         |
   |  "Both"                  |  no *      |  no state change         |
   +------------------------------------------------------------------+
        

* Server SHOULD auto-reply with "subscribed" stanza

* 服务器应自动回复“已订阅”节

When the user's server receives a presence stanza of type "unsubscribe" for the user from the contact, if the stanza results in a subscription state change from the user's perspective then the user's server SHOULD auto-reply by sending a presence stanza of type "unsubscribed" to the contact on behalf of the user, MUST deliver the "unsubscribe" stanza to the user, and MUST change the state. If no subscription state change results, the user's server SHOULD NOT deliver the stanza and MUST NOT change the state. These rules are summarized in the following table.

当用户服务器从联系人处接收到用户的“unsubscribe”类型的状态节时,如果该节从用户角度导致订阅状态更改,则用户服务器应通过代表用户向联系人发送“unsubscribed”类型的状态节自动回复,并且必须发送“unsubscribe”节,并且必须更改状态。如果没有订阅状态更改结果,则用户的服务器不应传递节,并且不得更改状态。下表总结了这些规则。

Table 4: Recommended handling of inbound "unsubscribe" stanzas

表4:入站“取消订阅”节的建议处理

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  no        |  no state change         |
   |  "None + Pending In"     |  yes *     |  "None"                  |
   |  "None + Pending Out/In" |  yes *     |  "None + Pending Out"    |
   |  "To"                    |  no        |  no state change         |
   |  "To + Pending In"       |  yes *     |  "To"                    |
   |  "From"                  |  yes *     |  "None"                  |
   |  "From + Pending Out"    |  yes *     |  "None + Pending Out     |
   |  "Both"                  |  yes *     |  "To"                    |
   +------------------------------------------------------------------+
        
   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  no        |  no state change         |
   |  "None + Pending In"     |  yes *     |  "None"                  |
   |  "None + Pending Out/In" |  yes *     |  "None + Pending Out"    |
   |  "To"                    |  no        |  no state change         |
   |  "To + Pending In"       |  yes *     |  "To"                    |
   |  "From"                  |  yes *     |  "None"                  |
   |  "From + Pending Out"    |  yes *     |  "None + Pending Out     |
   |  "Both"                  |  yes *     |  "To"                    |
   +------------------------------------------------------------------+
        

* Server SHOULD auto-reply with "unsubscribed" stanza

* 服务器应自动回复“取消订阅”节

When the user's server receives a presence stanza of type "subscribed" for the user from the contact, it MUST NOT deliver the stanza to the user and MUST NOT change the subscription state if there is no pending outbound request for access to the contact's presence information. If there is a pending outbound request for access to the contact's presence information and the inbound presence stanza of type "subscribed" results in a subscription state change, the user's server MUST deliver the stanza to the user and MUST change the subscription state. If the user already has access to the contact's presence information, the inbound presence stanza of type "subscribed" does not result in a subscription state change; therefore the user's server SHOULD NOT deliver the stanza to the user and MUST NOT change the subscription state. These rules are summarized in the following table.

当用户的服务器从联系人处接收到用户类型为“subscribed”的状态节时,如果没有访问联系人状态信息的挂起出站请求,则不得将该节传递给用户,也不得更改订阅状态。如果存在访问联系人状态信息的挂起出站请求,并且“subscribed”类型的入站状态节导致订阅状态更改,则用户的服务器必须将该节交付给用户,并且必须更改订阅状态。如果用户已经可以访问联系人的状态信息,则类型为“subscribed”的入站状态节不会导致订阅状态更改;因此,用户的服务器不应将节传递给用户,也不得更改订阅状态。下表总结了这些规则。

Table 5: Recommended handling of inbound "subscribed" stanzas

表5:入站“订阅”节的建议处理

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  yes       |  "To"                    |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  yes       |  "To + Pending In"       |
   |  "To"                    |  no        |  no state change         |
   |  "To + Pending In"       |  no        |  no state change         |
   |  "From"                  |  no        |  no state change         |
   |  "From + Pending Out"    |  yes       |  "Both"                  |
   |  "Both"                  |  no        |  no state change         |
   +------------------------------------------------------------------+
        
   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  yes       |  "To"                    |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  yes       |  "To + Pending In"       |
   |  "To"                    |  no        |  no state change         |
   |  "To + Pending In"       |  no        |  no state change         |
   |  "From"                  |  no        |  no state change         |
   |  "From + Pending Out"    |  yes       |  "Both"                  |
   |  "Both"                  |  no        |  no state change         |
   +------------------------------------------------------------------+
        

When the user's server receives a presence stanza of type "unsubscribed" for the user from the contact, it MUST deliver the stanza to the user and MUST change the subscription state if there is a pending outbound request for access to the contact's presence information or if the user currently has access to the contact's presence information. Otherwise, the user's server SHOULD NOT deliver the stanza and MUST NOT change the subscription state. These rules are summarized in the following table.

当用户的服务器从联系人处接收到用户“unsubscribed”类型的状态节时,它必须将该节传递给用户,并且如果存在访问联系人状态信息的挂起出站请求,或者如果用户当前有权访问联系人的状态信息,则必须更改订阅状态。否则,用户的服务器不应传递节,并且不得更改订阅状态。下表总结了这些规则。

Table 6: Recommended handling of inbound "unsubscribed" stanzas

表6:入境“未预订”节的建议处理

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  yes       |  "None"                  |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  yes       |  "None + Pending In"     |
   |  "To"                    |  yes       |  "None"                  |
   |  "To + Pending In"       |  yes       |  "None + Pending In"     |
   |  "From"                  |  no        |  no state change         |
   |  "From + Pending Out"    |  yes       |  "From"                  |
   |  "Both"                  |  yes       |  "From"                  |
   +------------------------------------------------------------------+
        
   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  yes       |  "None"                  |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  yes       |  "None + Pending In"     |
   |  "To"                    |  yes       |  "None"                  |
   |  "To + Pending In"       |  yes       |  "None + Pending In"     |
   |  "From"                  |  no        |  no state change         |
   |  "From + Pending Out"    |  yes       |  "From"                  |
   |  "Both"                  |  yes       |  "From"                  |
   +------------------------------------------------------------------+
        

9.4. Server Delivery and Client Acknowledgement of Subscription Requests and State Change Notifications

9.4. 订阅请求和状态更改通知的服务器传递和客户端确认

When a server receives an inbound presence stanza of type "subscribe" (i.e., a subscription request) or of type "subscribed", "unsubscribe", or "unsubscribed" (i.e., a subscription state change notification), in addition to sending the appropriate roster push (or updated roster when the roster is next requested by an available resource), it MUST deliver the request or notification to the intended recipient at least once. A server MAY require the recipient to acknowledge receipt of all state change notifications (and MUST require acknowledgement in the case of subscription requests, i.e., presence stanzas of type "subscribe"). In order to require acknowledgement, a server SHOULD send the request or notification to the recipient each time the recipient logs in, until the recipient acknowledges receipt of the notification by "affirming" or "denying" the notification, as shown in the following table:

当服务器接收到类型为“订阅”(即订阅请求)或类型为“订阅”、“取消订阅”或“取消订阅”(即订阅状态更改通知)的入站状态节时,除了发送适当的花名册推送(或在可用资源下一次请求花名册时更新花名册)外,它必须至少向预期收件人发送一次请求或通知。服务器可能要求接收者确认收到所有状态更改通知(并且在订阅请求的情况下必须要求确认,即“订阅”类型的存在节)。为了要求确认,服务器应在收件人每次登录时向收件人发送请求或通知,直到收件人通过“确认”或“拒绝”通知确认收到通知,如下表所示:

Table 7: Acknowledgement of subscription state change notifications

表7:订阅状态更改通知的确认

   +--------------------------------------------------+
   |  STANZA TYPE   |  ACCEPT        |  DENY          |
   +--------------------------------------------------+
   |  subscribe     |  subscribed    |  unsubscribed  |
   |  subscribed    |  subscribe     |  unsubscribe   |
   |  unsubscribe   |  unsubscribed  |  subscribed    |
   |  unsubscribed  |  unsubscribe   |  subscribe     |
   +--------------------------------------------------+
        
   +--------------------------------------------------+
   |  STANZA TYPE   |  ACCEPT        |  DENY          |
   +--------------------------------------------------+
   |  subscribe     |  subscribed    |  unsubscribed  |
   |  subscribed    |  subscribe     |  unsubscribe   |
   |  unsubscribe   |  unsubscribed  |  subscribed    |
   |  unsubscribed  |  unsubscribe   |  subscribe     |
   +--------------------------------------------------+
        

Obviously, given the foregoing subscription state charts, some of the acknowledgement stanzas will be routed to the contact and result in subscription state changes, while others will not. However, any such stanzas MUST result in the server's no longer sending the subscription state notification to the user.

显然,考虑到前面的订阅状态图,一些确认节将被路由到联系人并导致订阅状态更改,而另一些则不会。但是,任何此类节都必须导致服务器不再向用户发送订阅状态通知。

Because a user's server MUST automatically generate outbound presence stanzas of type "unsubscribe" and "unsubscribed" upon receiving a roster set with the 'subscription' attribute set to a value of "remove" (see Removing a Roster Item and Cancelling All Subscriptions (Section 8.6)), the server MUST treat a roster remove request as equivalent to sending both of those presence stanzas for purposes of determining whether to continue sending subscription state change notifications of type "subscribe" or "subscribed" to the user.

因为用户的服务器在收到“订阅”属性设置为“删除”值的花名册集时,必须自动生成“取消订阅”和“取消订阅”类型的出站状态节(请参阅删除花名册项目和取消所有订阅(第8.6节)),为了确定是否继续向用户发送“订阅”或“订阅”类型的订阅状态更改通知,服务器必须将花名册删除请求视为等同于发送这两个状态节。

10. Blocking Communication
10. 阻塞通信

Most instant messaging systems have found it necessary to implement some method for users to block communications from particular other users (this is also required by sections 5.1.5, 5.1.15, 5.3.2, and 5.4.10 of [IMP-REQS]). In XMPP this is done by managing one's privacy lists using the 'jabber:iq:privacy' namespace.

大多数即时消息系统发现有必要为用户实施某种方法来阻止来自特定其他用户的通信(这也是[IMP-REQS]第5.1.5、5.1.15、5.3.2和5.4.10节的要求)。在XMPP中,这是通过使用“jabber:iq:privacy”名称空间管理个人隐私列表来实现的。

Server-side privacy lists enable successful completion of the following use cases:

服务器端隐私列表支持成功完成以下用例:

o Retrieving one's privacy lists.

o 检索某人的隐私列表。

o Adding, removing, and editing one's privacy lists.

o 添加、删除和编辑个人隐私列表。

o Setting, changing, or declining active lists.

o 设置、更改或拒绝活动列表。

o Setting, changing, or declining the default list (i.e., the list that is active by default).

o 设置、更改或拒绝默认列表(即默认情况下处于活动状态的列表)。

o Allowing or blocking messages based on JID, group, or subscription type (or globally).

o 允许或阻止基于JID、组或订阅类型(或全局)的消息。

o Allowing or blocking inbound presence notifications based on JID, group, or subscription type (or globally).

o 允许或阻止基于JID、组或订阅类型(或全局)的入站状态通知。

o Allowing or blocking outbound presence notifications based on JID, group, or subscription type (or globally).

o 允许或阻止基于JID、组或订阅类型(或全局)的出站状态通知。

o Allowing or blocking IQ stanzas based on JID, group, or subscription type (or globally).

o 允许或阻止基于JID、组或订阅类型(或全局)的IQ节。

o Allowing or blocking all communications based on JID, group, or subscription type (or globally).

o 允许或阻止基于JID、组或订阅类型(或全局)的所有通信。

Note: Presence notifications do not include presence subscriptions, only presence information that is broadcasted to entities that are subscribed to a user's presence information. Thus this includes presence stanzas with no 'type' attribute or of type='unavailable' only.

注意:状态通知不包括状态订阅,只包括向订阅用户状态信息的实体广播的状态信息。因此,这包括没有“type”属性或仅为class='unavailable'类型的状态节。

10.1. Syntax and Semantics
10.1. 语法和语义

A user MAY define one or more privacy lists, which are stored by the user's server. Each <list/> element contains one or more rules in the form of <item/> elements, and each <item/> element uses attributes to define a privacy rule type, a specific value to which the rule applies, the relevant action, and the place of the item in the processing order.

用户可以定义一个或多个隐私列表,这些列表由用户的服务器存储。每个<list/>元素包含一个或多个<item/>元素形式的规则,每个<item/>元素使用属性定义隐私规则类型、规则应用的特定值、相关操作以及项目在处理顺序中的位置。

The syntax is as follows:

语法如下:

   <iq>
     <query xmlns='jabber:iq:privacy'>
       <list name='foo'>
         <item
             type='[jid|group|subscription]'
             value='bar'
             action='[allow|deny]'
             order='unsignedInt'>
           [<message/>]
           [<presence-in/>]
           [<presence-out/>]
           [<iq/>]
         </item>
       </list>
     </query>
   </iq>
        
   <iq>
     <query xmlns='jabber:iq:privacy'>
       <list name='foo'>
         <item
             type='[jid|group|subscription]'
             value='bar'
             action='[allow|deny]'
             order='unsignedInt'>
           [<message/>]
           [<presence-in/>]
           [<presence-out/>]
           [<iq/>]
         </item>
       </list>
     </query>
   </iq>
        

If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID. JIDs SHOULD be matched in the following order:

如果类型为“jid”,则“value”属性必须包含有效的Jabber ID。jid应按以下顺序匹配:

   1.  <user@domain/resource> (only that resource matches)
        
   1.  <user@domain/resource> (only that resource matches)
        
   2.  <user@domain> (any resource matches)
        
   2.  <user@domain> (any resource matches)
        
   3.  <domain/resource> (only that resource matches)
        
   3.  <domain/resource> (only that resource matches)
        
   4.  <domain> (the domain itself matches, as does any user@domain,
       domain/resource, or address containing a subdomain)
        
   4.  <domain> (the domain itself matches, as does any user@domain,
       domain/resource, or address containing a subdomain)
        

If the type is "group", then the 'value' attribute SHOULD contain the name of a group in the user's roster. (If a client attempts to update, create, or delete a list item with a group that is not in the user's roster, the server SHOULD return to the client an <item-not-found/> stanza error.)

如果类型为“组”,则“值”属性应包含用户名册中组的名称。(如果客户端试图更新、创建或删除不在用户名册中的组的列表项,服务器应向客户端返回<item not found/>节错误。)

If the type is "subscription", then the 'value' attribute MUST be one of "both", "to", "from", or "none" as defined under Roster Syntax and Semantics (Section 7.1), where "none" includes entities that are totally unknown to the user and therefore not in the user's roster at all.

如果类型为“订阅”,则“值”属性必须是名册语法和语义(第7.1节)中定义的“两者”、“到”、“从”或“无”之一,其中“无”包括用户完全未知的实体,因此根本不在用户名册中。

If no 'type' attribute is included, the rule provides the "fall-through" case.

如果未包含“type”属性,则规则将提供“fall-through”案例。

The 'action' attribute MUST be included and its value MUST be either "allow" or "deny".

必须包括“action”属性,并且其值必须为“allow”或“deny”。

The 'order' attribute MUST be included and its value MUST be a non-negative integer that is unique among all items in the list. (If a client attempts to create or update a list with non-unique order values, the server MUST return to the client a <bad-request/> stanza error.)

必须包括“order”属性,并且其值必须是列表中所有项目中唯一的非负整数。(如果客户机试图创建或更新具有非唯一订单值的列表,服务器必须向客户机返回<bad request/>节错误。)

The <item/> element MAY contain one or more child elements that enable an entity to specify more granular control over which kinds of stanzas are to be blocked (i.e., rather than blocking all stanzas). The allowable child elements are:

<item/>元素可以包含一个或多个子元素,这些子元素使实体能够指定对要阻止的节类型(即,而不是阻止所有节)的更细粒度控制。允许的子元素包括:

   o  <message/> -- blocks incoming message stanzas
   o  <iq/> -- blocks incoming IQ stanzas
   o  <presence-in/> -- blocks incoming presence notifications
   o  <presence-out/> -- blocks outgoing presence notifications
        
   o  <message/> -- blocks incoming message stanzas
   o  <iq/> -- blocks incoming IQ stanzas
   o  <presence-in/> -- blocks incoming presence notifications
   o  <presence-out/> -- blocks outgoing presence notifications
        

Within the 'jabber:iq:privacy' namespace, the <query/> child of an IQ stanza of type "set" MUST NOT include more than one child element (i.e., the stanza MUST contain only one <active/> element, one <default/> element, or one <list/> element); if a sending entity violates this rule, the receiving entity MUST return a <bad-request/> stanza error.

在“jabber:iq:privacy”命名空间中,“set”类型的iq节的<query/>子元素不得包含多个子元素(即,该节只能包含一个<active/>元素、一个<default/>元素或一个<list/>元素);如果发送实体违反此规则,则接收实体必须返回<bad request/>节错误。

When a client adds or updates a privacy list, the <list/> element SHOULD contain at least one <item/> child element; when a client removes a privacy list, the <list/> element MUST NOT contain any <item/> child elements.

当客户端添加或更新隐私列表时,<list/>元素应至少包含一个子元素<item/>;当客户端删除隐私列表时,<list/>元素不得包含任何<item/>子元素。

When a client updates a privacy list, it must include all of the desired items (i.e., not a "delta").

当客户端更新隐私列表时,它必须包括所有所需的项目(即,不是“增量”)。

10.2. Business Rules
10.2. 商业规则

1. If there is an active list set for a session, it affects only the session(s) for which it is activated, and only for the duration of the session(s); the server MUST apply the active list only and MUST NOT apply the default list (i.e., there is no "layering" of lists).

1. 如果为某个会话设置了活动列表,则该列表仅影响激活该列表的会话,并且仅影响会话的持续时间;服务器必须仅应用活动列表,而不能应用默认列表(即,没有列表的“分层”)。

2. The default list applies to the user as a whole, and is processed if there is no active list set for the target session/resource to which a stanza is addressed, or if there are no current sessions for the user.

2. 默认列表作为一个整体应用于用户,如果没有为节寻址到的目标会话/资源设置活动列表,或者用户没有当前会话,则会对其进行处理。

3. If there is no active list set for a session (or there are no current sessions for the user), and there is no default list, then all stanzas SHOULD BE accepted or appropriately processed by the server on behalf of the user in accordance with the Server Rules for Handling XML Stanzas (Section 11).

3. 如果没有为会话设置活动列表(或用户没有当前会话),并且没有默认列表,则服务器应代表用户根据处理XML节的服务器规则(第11节)接受或适当处理所有节。

4. Privacy lists MUST be the first delivery rule applied by a server, superseding (1) the routing and delivery rules specified in Server Rules for Handling XML Stanzas (Section 11), and (2) the handling of subscription-related presence stanzas (and corresponding generation of roster pushes) specified in Integration of Roster Items and Presence Subscriptions (Section 8).

4. 隐私列表必须是服务器应用的第一个传递规则,取代(1)处理XML节的服务器规则(第11节)中指定的路由和传递规则,以及(2)处理订阅相关的状态节(以及相应的排班推送)在花名册项目和状态订阅集成(第8节)中指定。

5. The order in which privacy list items are processed by the server is important. List items MUST be processed in ascending order determined by the integer values of the 'order' attribute for each <item/>.

5. 服务器处理隐私列表项的顺序很重要。列表项必须按升序处理,升序由每个<item/>的“order”属性的整数值决定。

6. As soon as a stanza is matched against a privacy list rule, the server MUST appropriately handle the stanza in accordance with the rule and cease processing.

6. 一旦某个节与隐私列表规则匹配,服务器必须根据该规则适当地处理该节并停止处理。

7. If no fall-through item is provided in a list, the fall-through action is assumed to be "allow".

7. 如果列表中未提供直通项,则直通操作假定为“允许”。

8. If a user updates the definition for an active list, subsequent processing based on that active list MUST use the updated definition (for all resources to which that active list currently applies).

8. 如果用户更新活动列表的定义,则基于该活动列表的后续处理必须使用更新的定义(适用于该活动列表当前应用的所有资源)。

9. If a change to the subscription state or roster group of a roster item defined in an active or default list occurs during a user's session, subsequent processing based on that list MUST take into account the changed state or group (for all resources to which that list currently applies).

9. 如果在用户会话期间,活动或默认列表中定义的花名册项目的订阅状态或花名册组发生更改,则基于该列表的后续处理必须考虑更改的状态或组(对于该列表当前适用的所有资源)。

10. When the definition for a rule is modified, the server MUST send an IQ stanza of type "set" to all connected resources, containing a <query/> element with only one <list/> child element, where the 'name' attribute is set to the name of the modified privacy list. These "privacy list pushes" adhere to the same semantics as the "roster pushes" used in roster management, except that only the list name itself (not the full list definition or the "delta") is pushed to the connected resources. It is up to the receiving resource to determine whether to retrieve the modified list definition, although a connected resource SHOULD do so if the list currently applies to it.

10. 当规则的定义被修改时,服务器必须向所有连接的资源发送一个类型为“set”的IQ节,其中包含一个<query/>元素,只有一个子元素<list/>,其中“name”属性被设置为修改的隐私列表的名称。这些“隐私列表推送”遵循与花名册管理中使用的“花名册推送”相同的语义,只是只有列表名称本身(不是完整的列表定义或“增量”)被推送到连接的资源。由接收资源决定是否检索修改后的列表定义,尽管如果列表当前应用于已连接的资源,则该资源应该这样做。

11. When a resource attempts to remove a list or specify a new default list while that list applies to a connected resource other than the sending resource, the server MUST return a <conflict/> error to the sending resource and MUST NOT make the requested change.

11. 当资源试图删除列表或指定新的默认列表,而该列表应用于发送资源以外的连接资源时,服务器必须向发送资源返回<conflict/>错误,并且不得进行请求的更改。

10.3. Retrieving One's Privacy Lists
10.3. 检索个人隐私列表

Example: Client requests names of privacy lists from server:

示例:客户端从服务器请求隐私列表的名称:

   <iq from='romeo@example.net/orchard' type='get' id='getlist1'>
     <query xmlns='jabber:iq:privacy'/>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='get' id='getlist1'>
     <query xmlns='jabber:iq:privacy'/>
   </iq>
        

Example: Server sends names of privacy lists to client, preceded by active list and default list:

示例:服务器向客户端发送隐私列表的名称,前面是活动列表和默认列表:

   <iq type='result' id='getlist1' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <active name='private'/>
       <default name='public'/>
       <list name='public'/>
       <list name='private'/>
       <list name='special'/>
     </query>
   </iq>
        
   <iq type='result' id='getlist1' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <active name='private'/>
       <default name='public'/>
       <list name='public'/>
       <list name='private'/>
       <list name='special'/>
     </query>
   </iq>
        

Example: Client requests a privacy list from server:

示例:客户端从服务器请求隐私列表:

   <iq from='romeo@example.net/orchard' type='get' id='getlist2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='get' id='getlist2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>
        

Example: Server sends a privacy list to client:

示例:服务器向客户端发送隐私列表:

   <iq type='result' id='getlist2' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='1'/>
         <item action='allow' order='2'/>
       </list>
     </query>
   </iq>
        
   <iq type='result' id='getlist2' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='1'/>
         <item action='allow' order='2'/>
       </list>
     </query>
   </iq>
        

Example: Client requests another privacy list from server:

示例:客户端从服务器请求另一个隐私列表:

   <iq from='romeo@example.net/orchard' type='get' id='getlist3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='get' id='getlist3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'/>
     </query>
   </iq>
        

Example: Server sends another privacy list to client:

示例:服务器向客户端发送另一个隐私列表:

   <iq type='result' id='getlist3' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'>
         <item type='subscription'
               value='both'
               action='allow'
               order='10'/>
         <item action='deny' order='15'/>
       </list>
     </query>
   </iq>
        
   <iq type='result' id='getlist3' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'>
         <item type='subscription'
               value='both'
               action='allow'
               order='10'/>
         <item action='deny' order='15'/>
       </list>
     </query>
   </iq>
        

Example: Client requests yet another privacy list from server:

示例:客户端从服务器请求另一个隐私列表:

   <iq from='romeo@example.net/orchard' type='get' id='getlist4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='special'/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='get' id='getlist4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='special'/>
     </query>
   </iq>
        

Example: Server sends yet another privacy list to client:

示例:服务器向客户端发送另一个隐私列表:

   <iq type='result' id='getlist4' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='special'>
         <item type='jid'
               value='juliet@example.com'
               action='allow'
               order='6'/>
         <item type='jid'
               value='benvolio@example.org'
               action='allow'
               order='7'/>
         <item type='jid'
               value='mercutio@example.org'
               action='allow'
               order='42'/>
         <item action='deny' order='666'/>
       </list>
     </query>
   </iq>
        
   <iq type='result' id='getlist4' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='special'>
         <item type='jid'
               value='juliet@example.com'
               action='allow'
               order='6'/>
         <item type='jid'
               value='benvolio@example.org'
               action='allow'
               order='7'/>
         <item type='jid'
               value='mercutio@example.org'
               action='allow'
               order='42'/>
         <item action='deny' order='666'/>
       </list>
     </query>
   </iq>
        

In this example, the user has three lists: (1) 'public', which allows communications from everyone except one specific entity (this is the default list); (2) 'private', which allows communications only with

在本例中,用户有三个列表:(1)“public”,它允许除一个特定实体之外的所有人进行通信(这是默认列表);(2) “专用”,仅允许与

contacts who have a bidirectional subscription with the user (this is the active list); and (3) 'special', which allows communications only with three specific entities.

与用户双向订阅的联系人(这是活动列表);(3)“特殊”,仅允许与三个特定实体进行通信。

If the user attempts to retrieve a list but a list by that name does not exist, the server MUST return an <item-not-found/> stanza error to the user:

如果用户试图检索列表,但该名称的列表不存在,服务器必须向用户返回<item not found/>节错误:

Example: Client attempts to retrieve non-existent list:

示例:客户端尝试检索不存在的列表:

   <iq to='romeo@example.net/orchard' type='error' id='getlist5'>
     <query xmlns='jabber:iq:privacy'>
       <list name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq to='romeo@example.net/orchard' type='error' id='getlist5'>
     <query xmlns='jabber:iq:privacy'>
       <list name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        

The user is allowed to retrieve only one list at a time. If the user attempts to retrieve more than one list in the same request, the server MUST return a <bad request/> stanza error to the user:

用户一次只能检索一个列表。如果用户试图在同一请求中检索多个列表,服务器必须向用户返回<bad request/>节错误:

Example: Client attempts to retrieve more than one list:

示例:客户端尝试检索多个列表:

   <iq to='romeo@example.net/orchard' type='error' id='getlist6'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
       <list name='private'/>
       <list name='special'/>
     </query>
     <error type='modify'>
       <bad-request
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq to='romeo@example.net/orchard' type='error' id='getlist6'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
       <list name='private'/>
       <list name='special'/>
     </query>
     <error type='modify'>
       <bad-request
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
10.4. Managing Active Lists
10.4. 管理活动列表

In order to set or change the active list currently being applied by the server, the user MUST send an IQ stanza of type "set" with a <query/> element qualified by the 'jabber:iq:privacy' namespace that contains an empty <active/> child element possessing a 'name' attribute whose value is set to the desired list name.

为了设置或更改服务器当前应用的活动列表,用户必须发送一个类型为“set”的IQ节,其中包含一个由“jabber:IQ:privacy”命名空间限定的<query/>元素,该命名空间包含一个空的<active/>子元素,该子元素具有一个“name”属性,该属性的值设置为所需的列表名称。

Example: Client requests change of active list:

示例:客户端请求更改活动列表:

   <iq from='romeo@example.net/orchard' type='set' id='active1'>
     <query xmlns='jabber:iq:privacy'>
       <active name='special'/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='active1'>
     <query xmlns='jabber:iq:privacy'>
       <active name='special'/>
     </query>
   </iq>
        

The server MUST activate and apply the requested list before sending the result back to the client.

在将结果发送回客户端之前,服务器必须激活并应用请求的列表。

Example: Server acknowledges success of active list change:

示例:服务器确认活动列表更改成功:

   <iq type='result' id='active1' to='romeo@example.net/orchard'/>
        
   <iq type='result' id='active1' to='romeo@example.net/orchard'/>
        

If the user attempts to set an active list but a list by that name does not exist, the server MUST return an <item-not-found/> stanza error to the user:

如果用户试图设置活动列表,但该名称的列表不存在,服务器必须向用户返回<item not found/>节错误:

Example: Client attempts to set a non-existent list as active:

示例:客户端尝试将不存在的列表设置为活动:

   <iq to='romeo@example.net/orchard' type='error' id='active2'>
     <query xmlns='jabber:iq:privacy'>
       <active name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq to='romeo@example.net/orchard' type='error' id='active2'>
     <query xmlns='jabber:iq:privacy'>
       <active name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        

In order to decline the use of any active list, the connected resource MUST send an empty <active/> element with no 'name' attribute.

为了拒绝使用任何活动列表,连接的资源必须发送一个没有“name”属性的空<active/>元素。

Example: Client declines the use of active lists:

示例:客户端拒绝使用活动列表:

   <iq from='romeo@example.net/orchard' type='set' id='active3'>
     <query xmlns='jabber:iq:privacy'>
       <active/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='active3'>
     <query xmlns='jabber:iq:privacy'>
       <active/>
     </query>
   </iq>
        

Example: Server acknowledges success of declining any active list:

示例:服务器确认成功拒绝任何活动列表:

   <iq type='result' id='active3' to='romeo@example.net/orchard'/>
        
   <iq type='result' id='active3' to='romeo@example.net/orchard'/>
        
10.5. Managing the Default List
10.5. 管理默认列表

In order to change its default list (which applies to the user as a whole, not only the sending resource), the user MUST send an IQ stanza of type "set" with a <query/> element qualified by the 'jabber:iq:privacy' namespace that contains an empty <default/> child element possessing a 'name' attribute whose value is set to the desired list name.

为了更改其默认列表(适用于整个用户,而不仅仅是发送资源),用户必须发送一个类型为“set”的IQ节,其中包含一个由“jabber:IQ:privacy”命名空间限定的<query/>元素,该命名空间包含一个空的<default/>子元素,该子元素具有一个“name”属性,该属性的值设置为所需的列表名称。

Example: User requests change of default list:

示例:用户请求更改默认列表:

   <iq from='romeo@example.net/orchard' type='set' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='special'/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='special'/>
     </query>
   </iq>
        

Example: Server acknowledges success of default list change:

示例:服务器确认默认列表更改成功:

   <iq type='result' id='default1' to='romeo@example.net/orchard'/>
        
   <iq type='result' id='default1' to='romeo@example.net/orchard'/>
        

If the user attempts to change which list is the default list but the default list is in use by at least one connected resource other than the sending resource, the server MUST return a <conflict/> stanza error to the sending resource:

如果用户试图更改默认列表,但除发送资源外,至少有一个连接的资源正在使用默认列表,则服务器必须向发送资源返回<conflict/>节错误:

Example: Client attempts to change the default list but that list is in use by another resource:

示例:客户端尝试更改默认列表,但该列表正被其他资源使用:

   <iq to='romeo@example.net/orchard' type='error' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='special'/>
     </query>
     <error type='cancel'>
       <conflict
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq to='romeo@example.net/orchard' type='error' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='special'/>
     </query>
     <error type='cancel'>
       <conflict
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        

If the user attempts to set a default list but a list by that name does not exist, the server MUST return an <item-not-found/> stanza error to the user:

如果用户试图设置默认列表,但该名称的列表不存在,服务器必须向用户返回<item not found/>节错误:

Example: Client attempts to set a non-existent list as default:

示例:客户端尝试将不存在的列表设置为默认值:

   <iq to='romeo@example.net/orchard' type='error' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq to='romeo@example.net/orchard' type='error' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        

In order to decline the use of a default list (i.e., to use the domain's stanza routing rules at all times), the user MUST send an empty <default/> element with no 'name' attribute.

为了拒绝使用默认列表(即始终使用域的节路由规则),用户必须发送一个不带“name”属性的空<default/>元素。

Example: Client declines the use of the default list:

示例:客户端拒绝使用默认列表:

   <iq from='romeo@example.net/orchard' type='set' id='default2'>
     <query xmlns='jabber:iq:privacy'>
       <default/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='default2'>
     <query xmlns='jabber:iq:privacy'>
       <default/>
     </query>
   </iq>
        

Example: Server acknowledges success of declining any default list:

示例:服务器确认成功拒绝任何默认列表:

   <iq type='result' id='default2' to='romeo@example.net/orchard'/>
        
   <iq type='result' id='default2' to='romeo@example.net/orchard'/>
        

If one connected resource attempts to decline the use of a default list for the user as a whole but the default list currently applies to at least one other connected resource, the server MUST return a <conflict/> error to the sending resource:

如果一个连接的资源试图拒绝使用整个用户的默认列表,但默认列表当前至少适用于一个其他连接的资源,则服务器必须向发送资源返回<conflict/>错误:

Example: Client attempts to decline a default list but that list is in use by another resource:

示例:客户端尝试拒绝默认列表,但该列表正被其他资源使用:

   <iq to='romeo@example.net/orchard' type='error' id='default3'>
     <query xmlns='jabber:iq:privacy'>
       <default/>
     </query>
     <error type='cancel'>
       <conflict
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq to='romeo@example.net/orchard' type='error' id='default3'>
     <query xmlns='jabber:iq:privacy'>
       <default/>
     </query>
     <error type='cancel'>
       <conflict
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
10.6. Editing a Privacy List
10.6. 编辑隐私列表

In order to edit a privacy list, the user MUST send an IQ stanza of type "set" with a <query/> element qualified by the 'jabber:iq:privacy' namespace that contains one <list/> child element possessing a 'name' attribute whose value is set to the list name the user would like to edit. The <list/> element MUST contain one or more <item/> elements, which specify the user's desired changes to the list by including all elements in the list (not the "delta").

为了编辑隐私列表,用户必须发送一个类型为“set”的IQ节,其中包含由“jabber:IQ:privacy”命名空间限定的<query/>元素,该命名空间包含一个<list/>子元素,该子元素拥有一个“name”属性,该属性的值设置为用户想要编辑的列表名。<list/>元素必须包含一个或多个<item/>元素,这些元素通过包含列表中的所有元素(而不是“delta”)来指定用户对列表所需的更改。

Example: Client edits a privacy list:

示例:客户端编辑隐私列表:

   <iq from='romeo@example.net/orchard' type='set' id='edit1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='3'/>
         <item type='jid'
               value='paris@example.org'
               action='deny'
               order='5'/>
         <item action='allow' order='68'/>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='edit1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='3'/>
         <item type='jid'
               value='paris@example.org'
               action='deny'
               order='5'/>
         <item action='allow' order='68'/>
       </list>
     </query>
   </iq>
        

Example: Server acknowledges success of list edit:

示例:服务器确认列表编辑成功:

   <iq type='result' id='edit1' to='romeo@example.net/orchard'/>
        
   <iq type='result' id='edit1' to='romeo@example.net/orchard'/>
        

Note: The value of the 'order' attribute for any given item is not fixed. Thus in the foregoing example if the user would like to add 4 items between the "tybalt@example.com" item and the "paris@example.org" item, the user's client MUST renumber the relevant items before submitting the list to the server.

注意:任何给定项目的“订单”属性值都不是固定的。因此,在上述示例中,如果用户希望在tybalt@example.com“项目和项目”paris@example.org“项,用户的客户端必须在将列表提交到服务器之前对相关项重新编号。

The server MUST now send a "privacy list push" to all connected resources:

服务器现在必须向所有连接的资源发送“隐私列表推送”:

Example: Privacy list push on list edit:

示例:隐私列表推送列表编辑:

   <iq to='romeo@example.net/orchard' type='set' id='push1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>
        
   <iq to='romeo@example.net/orchard' type='set' id='push1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>
        
   <iq to='romeo@example.net/home' type='set' id='push2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>
        
   <iq to='romeo@example.net/home' type='set' id='push2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>
        

In accordance with the semantics of IQ stanzas defined in [XMPP-CORE], each connected resource MUST return an IQ result to the server as well:

根据[XMPP-CORE]中定义的IQ节的语义,每个连接的资源也必须向服务器返回一个IQ结果:

Example: Acknowledging receipt of privacy list pushes:

示例:确认收到隐私列表推送:

   <iq from='romeo@example.net/orchard'
       type='result'
       id='push1'/>
        
   <iq from='romeo@example.net/orchard'
       type='result'
       id='push1'/>
        
   <iq from='romeo@example.net/home'
       type='result'
       id='push2'/>
        
   <iq from='romeo@example.net/home'
       type='result'
       id='push2'/>
        
10.7. Adding a New Privacy List
10.7. 添加新的隐私列表

The same protocol used to edit an existing list is used to create a new list. If the list name matches that of an existing list, the request to add a new list will overwrite the old one. As with list edits, the server MUST also send a "privacy list push" to all connected resources.

用于编辑现有列表的协议用于创建新列表。如果列表名与现有列表名匹配,则添加新列表的请求将覆盖旧列表。与列表编辑一样,服务器还必须向所有连接的资源发送“隐私列表推送”。

10.8. Removing a Privacy List
10.8. 删除隐私列表

In order to remove a privacy list, the user MUST send an IQ stanza of type "set" with a <query/> element qualified by the 'jabber:iq:privacy' namespace that contains one empty <list/> child element possessing a 'name' attribute whose value is set to the list name the user would like to remove.

为了删除隐私列表,用户必须发送一个类型为“set”的IQ节,其中包含一个由“jabber:IQ:privacy”命名空间限定的<query/>元素,该命名空间包含一个空<list/>子元素,该子元素拥有一个“name”属性,该属性的值设置为用户要删除的列表名。

Example: Client removes a privacy list:

示例:客户端删除隐私列表:

   <iq from='romeo@example.net/orchard' type='set' id='remove1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'/>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='remove1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'/>
     </query>
   </iq>
        

Example: Server acknowledges success of list removal:

示例:服务器确认列表删除成功:

   <iq type='result' id='remove1' to='romeo@example.net/orchard'/>
        
   <iq type='result' id='remove1' to='romeo@example.net/orchard'/>
        

If a user attempts to remove a list that is currently being applied to at least one resource other than the sending resource, the server MUST return a <conflict/> stanza error to the user; i.e., the user MUST first set another list to active or default before attempting to remove it. If the user attempts to remove a list but a list by that name does not exist, the server MUST return an <item-not-found/> stanza error to the user. If the user attempts to remove more than one list in the same request, the server MUST return a <bad request/> stanza error to the user.

如果用户试图删除当前应用于发送资源以外的至少一个资源的列表,服务器必须向用户返回<conflict/>节错误;i、 例如,用户必须先将另一个列表设置为活动或默认,然后再尝试删除它。如果用户试图删除一个列表,但该名称的列表不存在,服务器必须向用户返回<item not found/>节错误。如果用户试图删除同一请求中的多个列表,服务器必须向用户返回<bad request/>节错误。

10.9. Blocking Messages
10.9. 阻止消息

Server-side privacy lists enable a user to block incoming messages from other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol. (Note: For the sake of brevity, IQ stanzas of type "result" are not shown in the following examples, nor are "privacy list pushes".)

服务器端隐私列表允许用户根据实体的JID、花名册组或订阅状态(或全局)阻止来自其他实体的传入消息。以下示例说明了该协议。(注:为简洁起见,以下示例中未显示“结果”类型的IQ节,也未显示“隐私列表”。)

Example: User blocks based on JID:

示例:基于JID的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='msg1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='3'>
           <message/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='msg1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='3'>
           <message/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive messages from the entity with the specified JID.

创建和应用上述列表后,用户将不会收到来自具有指定JID的实体的消息。

Example: User blocks based on roster group:

示例:基于花名册组的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='msg2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='4'>
           <message/>
         </item>
        
   <iq from='romeo@example.net/orchard' type='set' id='msg2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='4'>
           <message/>
         </item>
        
       </list>
     </query>
   </iq>
        
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive messages from any entities in the specified roster group.

由于创建和应用了上述列表,用户将不会收到来自指定名册组中任何实体的信息。

Example: User blocks based on subscription type:

示例:基于订阅类型的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='msg3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-sub-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='5'>
           <message/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='msg3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-sub-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='5'>
           <message/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive messages from any entities with the specified subscription type.

创建和应用上述列表后,用户将不会收到来自具有指定订阅类型的任何实体的消息。

Example: User blocks globally:

示例:全局用户块:

   <iq from='romeo@example.net/orchard' type='set' id='msg4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-global-example'>
         <item action='deny' order='6'>
           <message/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='msg4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='message-global-example'>
         <item action='deny' order='6'>
           <message/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive messages from any other users.

由于创建和应用了上述列表,用户将不会收到来自任何其他用户的消息。

10.10. Blocking Inbound Presence Notifications
10.10. 阻止入站状态通知

Server-side privacy lists enable a user to block incoming presence notifications from other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol.

服务器端隐私列表使用户能够根据实体的JID、花名册组或订阅状态(或全局)阻止来自其他实体的传入状态通知。以下示例说明了该协议。

Note: Presence notifications do not include presence subscriptions, only presence information that is broadcasted to the user because the user is currently subscribed to a contact's presence information. Thus this includes presence stanzas with no 'type' attribute or of type='unavailable' only.

注意:状态通知不包括状态订阅,只包括向用户广播的状态信息,因为用户当前已订阅联系人的状态信息。因此,这包括没有“type”属性或仅为class='unavailable'类型的状态节。

Example: User blocks based on JID:

示例:基于JID的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presin1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='7'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='presin1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='7'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive presence notifications from the entity with the specified JID.

作为创建和应用上述列表的结果,用户将不会收到来自具有指定JID的实体的存在通知。

Example: User blocks based on roster group:

示例:基于花名册组的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presin2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='8'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='presin2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='8'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive presence notifications from any entities in the specified roster group.

由于创建和应用了上述列表,用户将不会收到来自指定名册组中任何实体的出席通知。

Example: User blocks based on subscription type:

示例:基于订阅类型的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presin3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-sub-example'>
         <item type='subscription'
               value='to'
               action='deny'
               order='9'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='presin3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-sub-example'>
         <item type='subscription'
               value='to'
               action='deny'
               order='9'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive presence notifications from any entities with the specified subscription type.

作为创建和应用上述列表的结果,用户将不会收到来自具有指定订阅类型的任何实体的存在通知。

Example: User blocks globally:

示例:全局用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presin4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-global-example'>
         <item action='deny' order='11'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='presin4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presin-global-example'>
         <item action='deny' order='11'>
           <presence-in/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive presence notifications from any other users.

作为创建和应用上述列表的结果,用户将不会收到来自任何其他用户的存在通知。

10.11. Blocking Outbound Presence Notifications
10.11. 阻止出站状态通知

Server-side privacy lists enable a user to block outgoing presence notifications to other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol.

服务器端隐私列表使用户能够根据实体的JID、花名册组或订阅状态(或全局)阻止向其他实体发送外出状态通知。以下示例说明了该协议。

Note: Presence notifications do not include presence subscriptions, only presence information that is broadcasted to contacts because those contacts are currently subscribed to the user's presence information. Thus this includes presence stanzas with no 'type' attribute or of type='unavailable' only.

注意:状态通知不包括状态订阅,只包括广播给联系人的状态信息,因为这些联系人当前已订阅用户的状态信息。因此,这包括没有“type”属性或仅为class='unavailable'类型的状态节。

Example: User blocks based on JID:

示例:基于JID的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presout1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='13'>
           <presence-out/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='presout1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='13'>
           <presence-out/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not send presence notifications to the entity with the specified JID.

作为创建和应用上述列表的结果,用户将不会向具有指定JID的实体发送状态通知。

Example: User blocks based on roster group:

示例:基于花名册组的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presout2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='15'>
           <presence-out/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='presout2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='15'>
           <presence-out/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not send presence notifications to any entities in the specified roster group.

创建并应用上述列表后,用户将不会向指定名册组中的任何实体发送出席通知。

Example: User blocks based on subscription type:

示例:基于订阅类型的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presout3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-sub-example'>
         <item type='subscription'
               value='from'
               action='deny'
               order='17'>
           <presence-out/>
        
   <iq from='romeo@example.net/orchard' type='set' id='presout3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-sub-example'>
         <item type='subscription'
               value='from'
               action='deny'
               order='17'>
           <presence-out/>
        
         </item>
       </list>
     </query>
   </iq>
        
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not send presence notifications to any entities with the specified subscription type.

作为创建和应用上述列表的结果,用户将不会向具有指定订阅类型的任何实体发送状态通知。

Example: User blocks globally:

示例:全局用户块:

   <iq from='romeo@example.net/orchard' type='set' id='presout4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-global-example'>
         <item action='deny' order='23'>
           <presence-out/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='presout4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='presout-global-example'>
         <item action='deny' order='23'>
           <presence-out/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not send presence notifications to any other users.

作为创建和应用上述列表的结果,用户将不会向任何其他用户发送状态通知。

10.12. Blocking IQ Stanzas
10.12. 阻塞IQ节

Server-side privacy lists enable a user to block incoming IQ stanzas from other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol.

服务器端隐私列表允许用户根据实体的JID、花名册组或订阅状态(或全局)阻止来自其他实体的传入IQ节。以下示例说明了该协议。

Example: User blocks based on JID:

示例:基于JID的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='iq1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='29'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='iq1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='29'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from the entity with the specified JID.

由于创建和应用了上述列表,用户将不会从具有指定JID的实体接收IQ节。

Example: User blocks based on roster group:

示例:基于花名册组的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='iq2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='31'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='iq2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-group-example'>
         <item type='group'
               value='Enemies'
               action='deny'
               order='31'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from any entities in the specified roster group.

由于创建和应用了上述列表,用户将不会收到来自指定名册组中任何实体的IQ节。

Example: User blocks based on subscription type:

示例:基于订阅类型的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='iq3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-sub-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='17'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='iq3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-sub-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='17'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from any entities with the specified subscription type.

创建和应用上述列表后,用户将不会从具有指定订阅类型的任何实体接收IQ节。

Example: User blocks globally:

示例:全局用户块:

   <iq from='romeo@example.net/orchard' type='set' id='iq4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-global-example'>
         <item action='deny' order='1'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='iq4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='iq-global-example'>
         <item action='deny' order='1'>
           <iq/>
         </item>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from any other users.

创建并应用上述列表后,用户将不会从任何其他用户处收到IQ节。

10.13. Blocking All Communication
10.13. 阻止所有通信

Server-side privacy lists enable a user to block all stanzas from and to other entities based on the entity's JID, roster group, or subscription status (or globally). Note that this includes subscription-related presence stanzas, which are excluded by Blocking Inbound Presence Notifications (Section 10.10). The following examples illustrate the protocol.

服务器端隐私列表允许用户根据实体的JID、花名册组或订阅状态(或全局)阻止与其他实体之间的所有节。请注意,这包括订阅相关的状态节,通过阻止入站状态通知(第10.10节)将其排除在外。以下示例说明了该协议。

Example: User blocks based on JID:

示例:基于JID的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='all1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='23'/>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='all1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-jid-example'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='23'/>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, the entity with the specified JID.

由于创建和应用上述列表,用户将不会收到来自具有指定JID的实体的任何通信,也不会向该实体发送任何节。

Example: User blocks based on roster group:

示例:基于花名册组的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='all2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-group-example'>
         <item type='group'
               value='Enemies'
        
   <iq from='romeo@example.net/orchard' type='set' id='all2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-group-example'>
         <item type='group'
               value='Enemies'
        
               action='deny'
               order='13'/>
       </list>
     </query>
   </iq>
        
               action='deny'
               order='13'/>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, any entities in the specified roster group.

由于创建和应用上述列表,用户将不会收到指定名册组中任何实体的任何通信,也不会向指定名册组中的任何实体发送任何诗节。

Example: User blocks based on subscription type:

示例:基于订阅类型的用户块:

   <iq from='romeo@example.net/orchard' type='set' id='all3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-sub-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='11'/>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='all3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-sub-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='11'/>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, any entities with the specified subscription type.

作为创建和应用上述列表的结果,用户将不会从具有指定订阅类型的任何实体接收任何通信,也不会向其发送任何节。

Example: User blocks globally:

示例:全局用户块:

   <iq from='romeo@example.net/orchard' type='set' id='all4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-global-example'>
         <item action='deny' order='7'/>
       </list>
     </query>
   </iq>
        
   <iq from='romeo@example.net/orchard' type='set' id='all4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='all-global-example'>
         <item action='deny' order='7'/>
       </list>
     </query>
   </iq>
        

As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, any other users.

由于创建和应用上述列表,用户将不会从任何其他用户接收任何通信,也不会向任何其他用户发送任何节。

10.14. Blocked Entity Attempts to Communicate with User
10.14. 被阻止的实体尝试与用户通信

If a blocked entity attempts to send message or presence stanzas to the user, the user's server SHOULD silently drop the stanza and MUST NOT return an error to the sending entity.

如果被阻止的实体试图向用户发送消息或状态节,则用户的服务器应自动删除该节,并且不得向发送实体返回错误。

If a blocked entity attempts to send an IQ stanza of type "get" or "set" to the user, the user's server MUST return to the sending entity a <service-unavailable/> stanza error, since this is the standard error code sent from a client that does not understand the namespace of an IQ get or set. IQ stanzas of other types SHOULD be silently dropped by the server.

如果被阻止的实体试图向用户发送类型为“get”或“set”的IQ节,则用户的服务器必须向发送实体返回<service unavailable/>节错误,因为这是从不理解IQ get或set命名空间的客户端发送的标准错误代码。其他类型的IQ节应该由服务器自动删除。

Example: Blocked entity attempts to send IQ get:

示例:被阻止的实体尝试发送IQ get:

   <iq type='get'
       to='romeo@example.net'
       from='tybalt@example.com/pda'
       id='probing1'>
     <query xmlns='jabber:iq:version'/>
   </iq>
        
   <iq type='get'
       to='romeo@example.net'
       from='tybalt@example.com/pda'
       id='probing1'>
     <query xmlns='jabber:iq:version'/>
   </iq>
        

Example: Server returns error to blocked entity:

示例:服务器向被阻止的实体返回错误:

   <iq type='error'
       from='romeo@example.net'
       to='tybalt@example.com/pda'
       id='probing1'>
     <query xmlns='jabber:iq:version'/>
     <error type='cancel'>
       <service-unavailable
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
   <iq type='error'
       from='romeo@example.net'
       to='tybalt@example.com/pda'
       id='probing1'>
     <query xmlns='jabber:iq:version'/>
     <error type='cancel'>
       <service-unavailable
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>
        
10.15. Higher-Level Heuristics
10.15. 高级启发式

When building a representation of a higher-level privacy heuristic, a client SHOULD use the simplest possible representation.

当构建更高级别隐私启发式的表示时,客户机应该使用最简单的表示。

For example, the heuristic "block all communications with any user not in my roster" could be constructed in any of the following ways:

例如,启发式“阻止与不在我的花名册中的任何用户的所有通信”可以通过以下任一方式构造:

o allow communications from all JIDs in my roster (i.e., listing each JID as a separate list item), but block communications with everyone else

o 允许我花名册中所有JID的通信(即,将每个JID列为单独的列表项),但阻止与其他人的通信

o allow communications from any user who is in one of the groups that make up my roster (i.e., listing each group as a separate list item), but block communications from everyone else

o 允许来自组成我的花名册的其中一个组中的任何用户的通信(即,将每个组列为单独的列表项),但阻止来自其他所有人的通信

o allow communications from any user with whom I have a subscription of 'both' or 'to' or 'from' (i.e., listing each subscription value separately), but block communications from everyone else

o 允许与我订阅“两者”或“至”或“自”的任何用户进行通信(即,分别列出每个订阅值),但阻止与其他人的通信

o block communications from anyone whose subscription state is 'none'

o 阻止订阅状态为“无”的任何人的通信

The final representation is the simplest and SHOULD be used; here is the XML that would be sent in this case:

最后的表述是最简单的,应该使用;以下是在这种情况下将发送的XML:

   <iq type='set' id='heuristic1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='heuristic-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='437'/>
       </list>
     </query>
   </iq>
        
   <iq type='set' id='heuristic1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='heuristic-example'>
         <item type='subscription'
               value='none'
               action='deny'
               order='437'/>
       </list>
     </query>
   </iq>
        
11. Server Rules for Handling XML Stanzas
11. 处理XML节的服务器规则

Basic routing and delivery rules for servers are defined in [XMPP-CORE]. This section defines additional rules for XMPP-compliant instant messaging and presence servers.

服务器的基本路由和交付规则在[XMPP-CORE]中定义。本节定义了与XMPP兼容的即时消息和状态服务器的其他规则。

11.1. Inbound Stanzas
11.1. 入境诗节

If the hostname of the domain identifier portion of the JID contained in the 'to' attribute of an inbound stanza matches a hostname of the server itself and the JID contained in the 'to' attribute is of the form <user@example.com> or <user@example.com/resource>, the server MUST first apply any privacy lists (Section 10) that are in force, then follow the rules defined below:

如果入站节的“to”属性中包含的JID的域标识符部分的主机名与服务器本身的主机名匹配,并且“to”属性中包含的JID的形式为<user@example.com>或<user@example.com/参考资料>,服务器必须首先应用任何有效的隐私列表(第10节),然后遵循下面定义的规则:

1. If the JID is of the form <user@domain/resource> and an available resource matches the full JID, the recipient's server MUST deliver the stanza to that resource.

1. 如果JID的形式是<user@domain/如果一个可用的资源与完整的JID匹配,则接收方的服务器必须将节传递给该资源。

2. Else if the JID is of the form <user@domain> or <user@domain/ resource> and the associated user account does not exist, the recipient's server (a) SHOULD silently ignore the stanza (i.e., neither deliver it nor return an error) if it is a presence stanza, (b) MUST return a <service-unavailable/> stanza error to the sender if it is an IQ stanza, and (c) SHOULD return a <service-unavailable/> stanza error to the sender if it is a message stanza.

2. 否则,如果JID的形式是<user@domain>或<user@domain/resource>并且关联的用户帐户不存在,收件人的服务器(a)应该默默地忽略该节(即,既不传递也不返回错误),如果是状态节,(b)如果是IQ节,则必须向发件人返回<service unavailable/>节错误,和(c)如果是消息节,则应向发送方返回<service unavailable/>节错误。

3. Else if the JID is of the form <user@domain/resource> and no available resource matches the full JID, the recipient's server (a) SHOULD silently ignore the stanza (i.e., neither deliver it

3. 否则,如果JID的形式是<user@domain/resource>如果没有与完整JID匹配的可用资源,则接收方的服务器(a)应该默默地忽略该节(即,两者都不传递它)

nor return an error) if it is a presence stanza, (b) MUST return a <service-unavailable/> stanza error to the sender if it is an IQ stanza, and (c) SHOULD treat the stanza as if it were addressed to <user@domain> if it is a message stanza.

也不返回错误)如果是状态节,(b)如果是IQ节,则必须将<service unavailable/>节错误返回给发送方,并且(c)应将该节视为发往的节<user@domain>如果是信息节。

4. Else if the JID is of the form <user@domain> and there is at least one available resource available for the user, the recipient's server MUST follow these rules:

4. 否则,如果JID的形式是<user@domain>并且用户至少有一个可用资源,收件人的服务器必须遵循以下规则:

1. For message stanzas, the server SHOULD deliver the stanza to the highest-priority available resource (if the resource did not provide a value for the <priority/> element, the server SHOULD consider it to have provided a value of zero). If two or more available resources have the same priority, the server MAY use some other rule (e.g., most recent connect time, most recent activity time, or highest availability as determined by some hierarchy of <show/> values) to choose between them or MAY deliver the message to all such resources. However, the server MUST NOT deliver the stanza to an available resource with a negative priority; if the only available resource has a negative priority, the server SHOULD handle the message as if there were no available resources (defined below). In addition, the server MUST NOT rewrite the 'to' attribute (i.e., it MUST leave it as <user@domain> rather than change it to <user@domain/ resource>).

1. 对于消息节,服务器应该将节段传递到最高优先级的可用资源(如果资源没有为<Prime/>元素提供一个值,服务器应该认为它提供了一个零值)。如果两个或多个可用资源具有相同的优先级,则服务器可以使用一些其他规则(例如,最近的连接时间、最近的活动时间或由<show/>值的某些层次结构确定的最高可用性)在它们之间进行选择,或者可以将消息传递给所有此类资源。但是,服务器不能将节传递给具有负优先级的可用资源;如果唯一可用的资源具有负优先级,则服务器应将消息当作没有可用资源(定义如下)来处理。此外,服务器不得重写“to”属性(即,必须将其保留为<user@domain>而不是把它改成<user@domain/资源>)。

2. For presence stanzas other than those of type "probe", the server MUST deliver the stanza to all available resources; for presence probes, the server SHOULD reply based on the rules defined in Presence Probes (Section 5.1.3). In addition, the server MUST NOT rewrite the 'to' attribute (i.e., it MUST leave it as <user@domain> rather than change it to <user@domain/resource>).

2. 对于“probe”类型以外的状态节,服务器必须将该节传递给所有可用资源;对于状态探测,服务器应根据状态探测中定义的规则进行应答(第5.1.3节)。此外,服务器不得重写“to”属性(即,必须将其保留为<user@domain>而不是把它改成<user@domain/资源>)。

3. For IQ stanzas, the server itself MUST reply on behalf of the user with either an IQ result or an IQ error, and MUST NOT deliver the IQ stanza to any of the available resources. Specifically, if the semantics of the qualifying namespace define a reply that the server can provide, the server MUST reply to the stanza on behalf of the user; if not, the server MUST reply with a <service-unavailable/> stanza error.

3. 对于IQ节,服务器本身必须代表用户回复IQ结果或IQ错误,并且不得将IQ节传递给任何可用资源。具体来说,如果限定名称空间的语义定义了服务器可以提供的回复,则服务器必须代表用户回复该节;如果没有,服务器必须回复<service unavailable/>节错误。

5. Else if the JID is of the form <user@domain> and there are no available resources associated with the user, how the stanza is handled depends on the stanza type:

5. 否则,如果JID的形式是<user@domain>并且没有与用户关联的可用资源,节的处理方式取决于节类型:

1. For presence stanzas of type "subscribe", "subscribed", "unsubscribe", and "unsubscribed", the server MUST maintain a record of the stanza and deliver the stanza at least once (i.e., when the user next creates an available resource); in addition, the server MUST continue to deliver presence stanzas of type "subscribe" until the user either approves or denies the subscription request (see also Presence Subscriptions (Section 5.1.6)).

1. 对于类型为“订阅”、“订阅”、“取消订阅”和“取消订阅”的状态节,服务器必须维护该节的记录,并至少交付该节一次(即,当用户下次创建可用资源时);此外,服务器必须继续发送“订阅”类型的状态节,直到用户批准或拒绝订阅请求(另请参见状态订阅(第5.1.6节))。

2. For all other presence stanzas, the server SHOULD silently ignore the stanza by not storing it for later delivery or replying to it on behalf of the user.

2. 对于所有其他状态节,服务器应通过不存储该节以供以后传递或代表用户回复来忽略该节。

3. For message stanzas, the server MAY choose to store the stanza on behalf of the user and deliver it when the user next becomes available, or forward the message to the user via some other means (e.g., to the user's email account). However, if offline message storage or message forwarding is not enabled, the server MUST return to the sender a <service-unavailable/> stanza error. (Note: Offline message storage and message forwarding are not defined in XMPP, since they are strictly a matter of implementation and service provisioning.)

3. 对于消息节,服务器可以选择代表用户存储该节,并在用户下次可用时交付该节,或者通过一些其他方式(例如,到用户的电子邮件帐户)将消息转发给用户。但是,如果未启用脱机邮件存储或邮件转发,服务器必须向发件人返回<service unavailable/>节错误。(注意:离线消息存储和消息转发未在XMPP中定义,因为它们严格地属于实现和服务提供的问题。)

4. For IQ stanzas, the server itself MUST reply on behalf of the user with either an IQ result or an IQ error. Specifically, if the semantics of the qualifying namespace define a reply that the server can provide, the server MUST reply to the stanza on behalf of the user; if not, the server MUST reply with a <service-unavailable/> stanza error.

4. 对于IQ节,服务器本身必须代表用户回复IQ结果或IQ错误。具体来说,如果限定名称空间的语义定义了服务器可以提供的回复,则服务器必须代表用户回复该节;如果没有,服务器必须回复<service unavailable/>节错误。

11.2. Outbound Stanzas
11.2. 出境诗节

If the hostname of the domain identifier portion of the address contained in the 'to' attribute of an outbound stanza matches a hostname of the server itself, the server MUST deliver the stanza to a local entity according the rules for Inbound Stanzas (Section 11.1).

如果出站节的“to”属性中包含的地址的域标识符部分的主机名与服务器本身的主机名匹配,则服务器必须根据入站节的规则将该节传递给本地实体(第11.1节)。

If the hostname of the domain identifier portion of the address contained in the 'to' attribute of an outbound stanza does not match a hostname of the server itself, the server MUST attempt to route the stanza to the foreign domain. The recommended order of actions is as follows:

如果出站节的“to”属性中包含的地址的域标识符部分的主机名与服务器本身的主机名不匹配,服务器必须尝试将节路由到外域。建议的行动顺序如下:

1. First attempt to resolve the foreign hostname using an [SRV] Service of "xmpp-server" and Proto of "tcp", resulting in resource records such as "_xmpp-server._tcp.example.com.", as specified in [XMPP-CORE].

1. 第一次尝试使用“xmpp-server”的[SRV]服务和“tcp”的Proto解析外部主机名,结果产生了[xmpp-CORE]中指定的资源记录,如“\u xmpp-server.\u tcp.example.com.”。

2. If the "xmpp-server" address record resolution fails, attempt to resolve the "_im" or "_pres" [SRV] Service as specified in [IMP-SRV], using the "_im" Service for <message/> stanzas and the "_pres" Service for <presence/> stanzas (it is up to the implementation how to handle <iq/> stanzas). This will result in one or more resolutions of the form "_im.<proto>.example.com." or "_pres.<proto>.example.com.", where "<proto>" would be a label registered in the Instant Messaging SRV Protocol Label registry or the Presence SRV Protocol Label registry: either "_xmpp" for an XMPP-aware domain or some other IANA-registered label (e.g., "_simple") for a non-XMPP-aware domain.

2. 如果“xmpp服务器”地址记录解析失败,请尝试解析[IMP-SRV]中指定的“\u im”或“\u pres”[SRV]服务,将“\u im”服务用于<message/>节,将“\u pres”服务用于<presence/>节(如何处理<iq/>节取决于实现)。这将导致一个或多个格式为“\u im.<proto>.example.com.”或“\u pres.<proto>.example.com.”的解析,其中“<proto>”将是在即时消息SRV协议标签注册表或状态SRV协议标签注册表中注册的标签:对于xmpp感知域或某些其他IANA注册的标签(例如“\u simple”)对于不支持XMPP的域。

3. If both SRV address record resolutions fail, attempt to perform a normal IPv4/IPv6 address record resolution to determine the IP address using the "xmpp-server" port of 5269 registered with the IANA, as specified in [XMPP-CORE].

3. 如果两个SRV地址记录解析都失败,请尝试执行正常的IPv4/IPv6地址记录解析,以使用在IANA注册的“xmpp服务器”端口5269确定IP地址,如[xmpp-CORE]中所述。

Administrators of server deployments are strongly encouraged to keep the _im._xmpp, _pres._xmpp, and _xmpp._tcp SRV records properly synchronized, since different implementations might perform the "_im" and "_pres" lookups before the "xmpp-server" lookup.

强烈建议服务器部署管理员保持_im._xmpp、_pres._xmpp和_xmpp._tcpsrv记录正确同步,因为不同的实现可能会在“xmpp server”查找之前执行“_im”和“_pres”查找。

12. IM and Presence Compliance Requirements
12. IM和状态合规性要求

This section summarizes the specific aspects of the Extensible Messaging and Presence Protocol that MUST be supported by instant messaging and presence servers and clients in order to be considered compliant implementations. All such applications MUST comply with the requirements specified in [XMPP-CORE]. The text in this section specifies additional compliance requirements for instant messaging and presence servers and clients; note well that the requirements described here supplement but do not supersede the core requirements. Note also that a server or client MAY support only presence or instant messaging, and is not required to support both if only a presence service or an instant messaging service is desired.

本节总结了即时消息和状态服务器和客户端必须支持的可扩展消息和状态协议的特定方面,以便将其视为兼容的实现。所有此类应用必须符合[XMPP-CORE]中规定的要求。本节中的文字规定了即时消息和状态服务器及客户端的其他合规要求;请注意,此处描述的需求是对核心需求的补充,但不会取代核心需求。还请注意,服务器或客户端可能仅支持状态或即时消息传递,并且如果仅需要状态服务或即时消息传递服务,则不需要两者都支持。

12.1. Servers
12.1. 服务器

In addition to core server compliance requirements, an instant messaging and presence server MUST additionally support the following protocols:

除了核心服务器合规性要求外,即时消息和状态服务器还必须支持以下协议:

o All server-related instant messaging and presence syntax and semantics defined in this document, including presence broadcast on behalf of clients, presence subscriptions, roster storage and manipulation, privacy lists, and IM-specific routing and delivery rules

o 本文档中定义的所有与服务器相关的即时消息和状态语法和语义,包括代表客户端的状态广播、状态订阅、花名册存储和操作、隐私列表以及IM特定的路由和传递规则

12.2. Clients
12.2. 客户

In addition to core client compliance requirements, an instant messaging and presence client MUST additionally support the following protocols:

除了核心客户机法规遵从性要求外,即时消息和状态客户端还必须支持以下协议:

o Generation and handling of the IM-specific semantics of XML stanzas as defined by the XML schemas, including the 'type' attribute of message and presence stanzas as well as their child elements

o 生成和处理XML模式定义的XML节的IM特定语义,包括消息和状态节及其子元素的“type”属性

o All client-related instant messaging syntax and semantics defined in this document, including presence subscriptions, roster management, and privacy lists

o 本文档中定义的所有与客户端相关的即时消息语法和语义,包括状态订阅、花名册管理和隐私列表

o End-to-end object encryption as defined in End-to-End Object Encryption in the Extensible Messaging and Presence Protocol (XMPP) [XMPP-E2E]

o 可扩展消息和状态协议(XMPP)[XMPP-E2E]中的端到端对象加密中定义的端到端对象加密

A client MUST also handle addresses that are encoded as "im:" URIs as specified in [CPIM], and MAY do so by removing the "im:" scheme and entrusting address resolution to the server as specified under Outbound Stanzas (Section 11.2).

客户机还必须按照[CPIM]中的规定处理编码为“im:”URI的地址,并且可以通过删除“im:”方案并按照出站节(第11.2节)的规定将地址解析委托给服务器来实现。

13. Internationalization Considerations
13. 国际化考虑

For internationalization considerations, refer to the relevant section of [XMPP-CORE].

有关国际化注意事项,请参阅[XMPP-CORE]的相关章节。

14. Security Considerations
14. 安全考虑

Core security considerations for XMPP are defined in the relevant section of [XMPP-CORE].

XMPP的核心安全注意事项在[XMPP-Core]的相关章节中定义。

Additional considerations that apply only to instant messaging and presence applications of XMPP are defined in several places within this memo; specifically:

本备忘录中的几个地方定义了仅适用于XMPP即时消息和状态应用程序的其他注意事项;明确地:

o When a server processes an inbound stanza of any kind whose intended recipient is a user associated with one of the server's hostnames, the server MUST first apply any privacy lists (Section 10) that are in force (see Server Rules for Handling XML Stanzas (Section 11)).

o 当服务器处理任何类型的入站节(其预期收件人是与服务器主机名之一关联的用户)时,服务器必须首先应用任何有效的隐私列表(第10节)(请参阅处理XML节的服务器规则(第11节))。

o When a server processes an inbound presence stanza of type "probe" whose intended recipient is a user associated with one of the server's hostnames, the server MUST NOT reveal the user's presence information if the sender is an entity that is not authorized to receive that information as determined by presence subscriptions (see Client and Server Presence Responsibilities (Section 5.1)).

o 当服务器处理“probe”类型的入站状态节时,其预期收件人是与服务器主机名之一关联的用户,如果发件人是未经授权接收状态订阅确定的信息的实体,则服务器不得透露该用户的状态信息(参见客户机和服务器存在责任(第5.1节))。

o When a server processes an outbound presence stanza with no type or of type "unavailable", it MUST follow the rules defined under Client and Server Presence Responsibilities (Section 5.1) in order to ensure that such presence information is not broadcasted to entities that are not authorized to know such information.

o 当服务器处理无类型或“不可用”类型的出站状态节时,它必须遵循客户机和服务器状态责任(第5.1节)中定义的规则,以确保此类状态信息不会广播给无权了解此类信息的实体。

o When a server generates an error stanza in response to receiving a stanza for a user who does not exist, the use of the <service-unavailable/> error condition helps protect against well-known dictionary attacks, since this is the same error condition that is returned if, for instance, the namespace of an IQ child element is not understood, or if offline message storage or message forwarding is not enabled for a domain.

o 当服务器响应接收到不存在的用户的节而生成错误节时,使用<service unavailable/>错误条件有助于防止众所周知的字典攻击,因为这是在例如不理解IQ子元素的名称空间时返回的相同错误条件,或者如果未为域启用脱机邮件存储或邮件转发。

15. IANA Considerations
15. IANA考虑

For a number of related IANA considerations, refer to the relevant section of [XMPP-CORE].

有关IANA的一些相关注意事项,请参阅[XMPP-CORE]的相关章节。

15.1. XML Namespace Name for Session Data
15.1. 会话数据的XML命名空间名称

A URN sub-namespace for session-related data in the Extensible Messaging and Presence Protocol (XMPP) is defined as follows. (This namespace name adheres to the format defined in The IETF XML Registry [XML-REG].)

可扩展消息和状态协议(XMPP)中会话相关数据的URN子命名空间定义如下。(此命名空间名称遵循IETF XML注册表[XML-REG]中定义的格式。)

   URI: urn:ietf:params:xml:ns:xmpp-session
   Specification: RFC 3921
   Description: This is the XML namespace name for session-related data
      in the Extensible Messaging and Presence Protocol (XMPP) as
      defined by RFC 3921.
   Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>
        
   URI: urn:ietf:params:xml:ns:xmpp-session
   Specification: RFC 3921
   Description: This is the XML namespace name for session-related data
      in the Extensible Messaging and Presence Protocol (XMPP) as
      defined by RFC 3921.
   Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>
        
15.2. Instant Messaging SRV Protocol Label Registration
15.2. 即时消息SRV协议标签注册

Address Resolution for Instant Messaging and Presence [IMP-SRV] defines an Instant Messaging SRV Protocol Label registry for protocols that can provide services that conform to the "_im" SRV Service label. Because XMPP is one such protocol, the IANA registers the "_xmpp" protocol label in the appropriate registry, as follows:

即时消息和状态的地址解析[IMP-SRV]为可提供符合“im”SRV服务标签的服务的协议定义了即时消息SRV协议标签注册表。由于XMPP就是这样一种协议,IANA在相应的注册表中注册“XMPP”协议标签,如下所示:

   Protocol label: _xmpp
   Specification: RFC 3921
   Description: Instant messaging protocol label for the Extensible
      Messaging and Presence Protocol (XMPP) as defined by RFC 3921.
   Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>
        
   Protocol label: _xmpp
   Specification: RFC 3921
   Description: Instant messaging protocol label for the Extensible
      Messaging and Presence Protocol (XMPP) as defined by RFC 3921.
   Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>
        
15.3. Presence SRV Protocol Label Registration
15.3. 状态SRV协议标签注册

Address Resolution for Instant Messaging and Presence [IMP-SRV] defines a Presence SRV Protocol Label registry for protocols that can provide services that conform to the "_pres" SRV Service label. Because XMPP is one such protocol, the IANA registers the "_xmpp" protocol label in the appropriate registry, as follows:

即时消息和状态的地址解析[IMP-SRV]为协议定义了状态SRV协议标签注册表,该协议可提供符合“_pres”SRV服务标签的服务。由于XMPP就是这样一种协议,IANA在相应的注册表中注册“XMPP”协议标签,如下所示:

   Protocol label: _xmpp
   Specification: RFC 3921
   Description: Presence protocol label for the Extensible Messaging and
      Presence Protocol (XMPP) as defined by RFC 3921.
   Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>
        
   Protocol label: _xmpp
   Specification: RFC 3921
   Description: Presence protocol label for the Extensible Messaging and
      Presence Protocol (XMPP) as defined by RFC 3921.
   Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>
        
16. References
16. 工具书类
16.1. Normative References
16.1. 规范性引用文件

[CPIM] Peterson, J., "Common Profile for Instant Messaging (CPIM)", RFC 3860, August 2004.

[CPIM]Peterson,J.,“即时消息的通用配置文件(CPIM)”,RFC3860,2004年8月。

[IMP-REQS] Day, M., Aggarwal, S., Mohr, G., and J. Vincent, "Instant Messaging/Presence Protocol Requirements", RFC 2779, February 2000.

[IMP-REQS]Day,M.,Aggarwal,S.,Mohr,G.,和J.Vincent,“即时消息/存在协议要求”,RFC 27792000年2月。

[IMP-SRV] Peterson, J., "Address Resolution for Instant Messaging and Presence", RFC 3861, August 2004.

[IMP-SRV]Peterson,J.,“即时消息和状态的地址解析”,RFC 38612004年8月。

[SRV] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000.

[SRV]Gulbrandsen,A.,Vixie,P.和L.Esibov,“用于指定服务位置(DNS SRV)的DNS RR”,RFC 2782,2000年2月。

[TERMS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[术语]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

[XML] Bray, T., Paoli, J., Sperberg-McQueen, C., and E. Maler, "Extensible Markup Language (XML) 1.0 (2nd ed)", W3C REC-xml, October 2000, <http://www.w3.org/TR/REC-xml>.

[XML]Bray,T.,Paoli,J.,Sperberg McQueen,C.,和E.Maler,“可扩展标记语言(XML)1.0(第二版)”,W3C REC XML,2000年10月<http://www.w3.org/TR/REC-xml>.

[XML-NAMES] Bray, T., Hollander, D., and A. Layman, "Namespaces in XML", W3C REC-xml-names, January 1999, <http://www.w3.org/TR/REC-xml-names>.

[XML-NAMES]Bray,T.,Hollander,D.,和A.Layman,“XML中的名称空间”,W3C REC XML名称,1999年1月<http://www.w3.org/TR/REC-xml-names>.

[XMPP-CORE] Saint-Andre, P., "Extensible Messaging and Presence Protocol (XMPP): Core", RFC 3920, October 2004.

[XMPP-CORE]Saint Andre,P.,“可扩展消息和状态协议(XMPP):CORE”,RFC 3920,2004年10月。

[XMPP-E2E] Saint-Andre, P., "End-to-End Object Encryption in the Extensible Messaging and Presence Protocol (XMPP)", RFC 3923, October 2004.

[XMPP-E2E]Saint Andre,P.,“可扩展消息和状态协议(XMPP)中的端到端对象加密”,RFC 39232004年10月。

16.2. Informative References
16.2. 资料性引用

[IMP-MODEL] Day, M., Rosenberg, J., and H. Sugano, "A Model for Presence and Instant Messaging", RFC 2778, February 2000.

[IMP-MODEL]Day,M.,Rosenberg,J.,和H.Sugano,“状态和即时信息模型”,RFC 27782000年2月。

[IRC] Oikarinen, J. and D. Reed, "Internet Relay Chat Protocol", RFC 1459, May 1993.

[IRC]Oikarinen,J.和D.Reed,“互联网中继聊天协议”,RFC 1459,1993年5月。

[JEP-0054] Saint-Andre, P., "vcard-temp", JSF JEP 0054, March 2003.

[JEP-0054]圣安德烈,P.,“vcard temp”,JSF JEP 0054,2003年3月。

[JEP-0077] Saint-Andre, P., "In-Band Registration", JSF JEP 0077, August 2004.

[JEP-0077]圣安德烈,P.,“带内注册”,JSF JEP 0077,2004年8月。

[JEP-0078] Saint-Andre, P., "Non-SASL Authentication", JSF JEP 0078, July 2004.

[JEP-0078]圣安德烈,P.,“非SASL认证”,JSF JEP 0078,2004年7月。

[JSF] Jabber Software Foundation, "Jabber Software Foundation", <http://www.jabber.org/>.

JBF] Jabbor软件基金会,“JabBER软件基金会”,<http://www.jabber.org/>.

[VCARD] Dawson, F. and T. Howes, "vCard MIME Directory Profile", RFC 2426, September 1998.

[VCARD]Dawson,F.和T.Howes,“VCARD MIME目录配置文件”,RFC24261998年9月。

[XML-REG] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, January 2004.

[XML-REG]Mealling,M.“IETF XML注册表”,BCP 81,RFC 3688,2004年1月。

Appendix A. vCards
附录A.电子名片

Sections 3.1.3 and 4.1.4 of [IMP-REQS] require that it be possible to retrieve out-of-band contact information for other users (e.g., telephone number or email address). An XML representation of the vCard specification defined in RFC 2426 [VCARD] is in common use within the Jabber community to provide such information but is out of scope for XMPP (documentation of this protocol is contained in [JEP-0054], published by the Jabber Software Foundation [JSF]).

[IMP-REQS]第3.1.3节和第4.1.4节要求可以检索其他用户的带外联系信息(例如电话号码或电子邮件地址)。在RFB 2426(VCARD)中定义的VCART规范的XML表示在JabBER社区内是常用的,但提供的信息不在XMPP的范围内(JPEB-FAX54)所包含的这个协议包含在[JPE-054 ]中。

Appendix B. XML Schemas
附录B.XML模式

The following XML schemas are descriptive, not normative. For schemas defining the core features of XMPP, refer to [XMPP-CORE].

以下XML模式是描述性的,不是规范性的。有关定义XMPP核心特性的模式,请参阅[XMPP-core]。

B.1 jabber:client
B.1叽叽喳喳:客户
   <?xml version='1.0' encoding='UTF-8'?>
        
   <?xml version='1.0' encoding='UTF-8'?>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:client'
       xmlns='jabber:client'
       elementFormDefault='qualified'>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:client'
       xmlns='jabber:client'
       elementFormDefault='qualified'>
        
     <xs:import namespace='urn:ietf:params:xml:ns:xmpp-stanzas'/>
        
     <xs:import namespace='urn:ietf:params:xml:ns:xmpp-stanzas'/>
        
     <xs:element name='message'>
        <xs:complexType>
           <xs:sequence>
             <xs:choice minOccurs='0' maxOccurs='unbounded'>
               <xs:element ref='subject'/>
               <xs:element ref='body'/>
               <xs:element ref='thread'/>
             </xs:choice>
             <xs:any     namespace='##other'
                         minOccurs='0'
                         maxOccurs='unbounded'/>
             <xs:element ref='error'
                         minOccurs='0'/>
        
     <xs:element name='message'>
        <xs:complexType>
           <xs:sequence>
             <xs:choice minOccurs='0' maxOccurs='unbounded'>
               <xs:element ref='subject'/>
               <xs:element ref='body'/>
               <xs:element ref='thread'/>
             </xs:choice>
             <xs:any     namespace='##other'
                         minOccurs='0'
                         maxOccurs='unbounded'/>
             <xs:element ref='error'
                         minOccurs='0'/>
        
           </xs:sequence>
           <xs:attribute name='from'
                         type='xs:string'
                         use='optional'/>
           <xs:attribute name='id'
                         type='xs:NMTOKEN'
                         use='optional'/>
           <xs:attribute name='to'
                         type='xs:string'
                         use='optional'/>
           <xs:attribute name='type' use='optional' default='normal'>
             <xs:simpleType>
               <xs:restriction base='xs:NCName'>
                 <xs:enumeration value='chat'/>
                 <xs:enumeration value='error'/>
                 <xs:enumeration value='groupchat'/>
                 <xs:enumeration value='headline'/>
                 <xs:enumeration value='normal'/>
               </xs:restriction>
             </xs:simpleType>
           </xs:attribute>
           <xs:attribute ref='xml:lang' use='optional'/>
        </xs:complexType>
     </xs:element>
        
           </xs:sequence>
           <xs:attribute name='from'
                         type='xs:string'
                         use='optional'/>
           <xs:attribute name='id'
                         type='xs:NMTOKEN'
                         use='optional'/>
           <xs:attribute name='to'
                         type='xs:string'
                         use='optional'/>
           <xs:attribute name='type' use='optional' default='normal'>
             <xs:simpleType>
               <xs:restriction base='xs:NCName'>
                 <xs:enumeration value='chat'/>
                 <xs:enumeration value='error'/>
                 <xs:enumeration value='groupchat'/>
                 <xs:enumeration value='headline'/>
                 <xs:enumeration value='normal'/>
               </xs:restriction>
             </xs:simpleType>
           </xs:attribute>
           <xs:attribute ref='xml:lang' use='optional'/>
        </xs:complexType>
     </xs:element>
        
     <xs:element name='body'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='body'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='subject'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='subject'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='thread' type='xs:NMTOKEN'/>
        
     <xs:element name='thread' type='xs:NMTOKEN'/>
        
     <xs:element name='presence'>
        
     <xs:element name='presence'>
        
       <xs:complexType>
         <xs:sequence>
           <xs:choice minOccurs='0' maxOccurs='unbounded'>
             <xs:element ref='show'/>
             <xs:element ref='status'/>
             <xs:element ref='priority'/>
           </xs:choice>
           <xs:any     namespace='##other'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='optional'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='type' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='probe'/>
               <xs:enumeration value='subscribe'/>
               <xs:enumeration value='subscribed'/>
               <xs:enumeration value='unavailable'/>
               <xs:enumeration value='unsubscribe'/>
               <xs:enumeration value='unsubscribed'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
       <xs:complexType>
         <xs:sequence>
           <xs:choice minOccurs='0' maxOccurs='unbounded'>
             <xs:element ref='show'/>
             <xs:element ref='status'/>
             <xs:element ref='priority'/>
           </xs:choice>
           <xs:any     namespace='##other'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='optional'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='type' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='probe'/>
               <xs:enumeration value='subscribe'/>
               <xs:enumeration value='subscribed'/>
               <xs:enumeration value='unavailable'/>
               <xs:enumeration value='unsubscribe'/>
               <xs:enumeration value='unsubscribed'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='show'>
       <xs:simpleType>
         <xs:restriction base='xs:NCName'>
           <xs:enumeration value='away'/>
           <xs:enumeration value='chat'/>
           <xs:enumeration value='dnd'/>
           <xs:enumeration value='xa'/>
         </xs:restriction>
       </xs:simpleType>
        
     <xs:element name='show'>
       <xs:simpleType>
         <xs:restriction base='xs:NCName'>
           <xs:enumeration value='away'/>
           <xs:enumeration value='chat'/>
           <xs:enumeration value='dnd'/>
           <xs:enumeration value='xa'/>
         </xs:restriction>
       </xs:simpleType>
        
     </xs:element>
        
     </xs:element>
        
     <xs:element name='status'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='status'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='priority' type='xs:byte'/>
        
     <xs:element name='priority' type='xs:byte'/>
        
     <xs:element name='iq'>
       <xs:complexType>
         <xs:sequence>
           <xs:any     namespace='##other'
                       minOccurs='0'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='required'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='get'/>
               <xs:enumeration value='result'/>
               <xs:enumeration value='set'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='iq'>
       <xs:complexType>
         <xs:sequence>
           <xs:any     namespace='##other'
                       minOccurs='0'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='required'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='optional'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='get'/>
               <xs:enumeration value='result'/>
               <xs:enumeration value='set'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='error'>
       <xs:complexType>
         <xs:sequence  xmlns:err='urn:ietf:params:xml:ns:xmpp-stanzas'>
        
     <xs:element name='error'>
       <xs:complexType>
         <xs:sequence  xmlns:err='urn:ietf:params:xml:ns:xmpp-stanzas'>
        
           <xs:group   ref='err:stanzaErrorGroup'/>
           <xs:element ref='err:text'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='code' type='xs:byte' use='optional'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='auth'/>
               <xs:enumeration value='cancel'/>
               <xs:enumeration value='continue'/>
               <xs:enumeration value='modify'/>
               <xs:enumeration value='wait'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
       </xs:complexType>
     </xs:element>
        
           <xs:group   ref='err:stanzaErrorGroup'/>
           <xs:element ref='err:text'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='code' type='xs:byte' use='optional'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='auth'/>
               <xs:enumeration value='cancel'/>
               <xs:enumeration value='continue'/>
               <xs:enumeration value='modify'/>
               <xs:enumeration value='wait'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
       </xs:complexType>
     </xs:element>
        
   </xs:schema>
        
   </xs:schema>
        
B.2 jabber:server
B.2 jabber:服务器
   <?xml version='1.0' encoding='UTF-8'?>
        
   <?xml version='1.0' encoding='UTF-8'?>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:server'
       xmlns='jabber:server'
       elementFormDefault='qualified'>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:server'
       xmlns='jabber:server'
       elementFormDefault='qualified'>
        
     <xs:import namespace='urn:ietf:params:xml:ns:xmpp-stanzas'/>
        
     <xs:import namespace='urn:ietf:params:xml:ns:xmpp-stanzas'/>
        
     <xs:element name='message'>
        <xs:complexType>
           <xs:sequence>
             <xs:choice minOccurs='0' maxOccurs='unbounded'>
               <xs:element ref='subject'/>
               <xs:element ref='body'/>
               <xs:element ref='thread'/>
             </xs:choice>
             <xs:any     namespace='##other'
                         minOccurs='0'
                         maxOccurs='unbounded'/>
             <xs:element ref='error'
                         minOccurs='0'/>
           </xs:sequence>
        
     <xs:element name='message'>
        <xs:complexType>
           <xs:sequence>
             <xs:choice minOccurs='0' maxOccurs='unbounded'>
               <xs:element ref='subject'/>
               <xs:element ref='body'/>
               <xs:element ref='thread'/>
             </xs:choice>
             <xs:any     namespace='##other'
                         minOccurs='0'
                         maxOccurs='unbounded'/>
             <xs:element ref='error'
                         minOccurs='0'/>
           </xs:sequence>
        
           <xs:attribute name='from'
                         type='xs:string'
                         use='required'/>
           <xs:attribute name='id'
                         type='xs:NMTOKEN'
                         use='optional'/>
           <xs:attribute name='to'
                         type='xs:string'
                         use='required'/>
           <xs:attribute name='type' use='optional' default='normal'>
             <xs:simpleType>
               <xs:restriction base='xs:NCName'>
                 <xs:enumeration value='chat'/>
                 <xs:enumeration value='error'/>
                 <xs:enumeration value='groupchat'/>
                 <xs:enumeration value='headline'/>
                 <xs:enumeration value='normal'/>
               </xs:restriction>
             </xs:simpleType>
           </xs:attribute>
           <xs:attribute ref='xml:lang' use='optional'/>
        </xs:complexType>
     </xs:element>
        
           <xs:attribute name='from'
                         type='xs:string'
                         use='required'/>
           <xs:attribute name='id'
                         type='xs:NMTOKEN'
                         use='optional'/>
           <xs:attribute name='to'
                         type='xs:string'
                         use='required'/>
           <xs:attribute name='type' use='optional' default='normal'>
             <xs:simpleType>
               <xs:restriction base='xs:NCName'>
                 <xs:enumeration value='chat'/>
                 <xs:enumeration value='error'/>
                 <xs:enumeration value='groupchat'/>
                 <xs:enumeration value='headline'/>
                 <xs:enumeration value='normal'/>
               </xs:restriction>
             </xs:simpleType>
           </xs:attribute>
           <xs:attribute ref='xml:lang' use='optional'/>
        </xs:complexType>
     </xs:element>
        
     <xs:element name='body'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='body'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='subject'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='subject'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='thread' type='xs:NMTOKEN'/>
        
     <xs:element name='thread' type='xs:NMTOKEN'/>
        
     <xs:element name='presence'>
       <xs:complexType>
        
     <xs:element name='presence'>
       <xs:complexType>
        
         <xs:sequence>
           <xs:choice minOccurs='0' maxOccurs='unbounded'>
             <xs:element ref='show'/>
             <xs:element ref='status'/>
             <xs:element ref='priority'/>
           </xs:choice>
           <xs:any     namespace='##other'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='optional'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='type' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='probe'/>
               <xs:enumeration value='subscribe'/>
               <xs:enumeration value='subscribed'/>
               <xs:enumeration value='unavailable'/>
               <xs:enumeration value='unsubscribe'/>
               <xs:enumeration value='unsubscribed'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
         <xs:sequence>
           <xs:choice minOccurs='0' maxOccurs='unbounded'>
             <xs:element ref='show'/>
             <xs:element ref='status'/>
             <xs:element ref='priority'/>
           </xs:choice>
           <xs:any     namespace='##other'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='optional'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='type' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='probe'/>
               <xs:enumeration value='subscribe'/>
               <xs:enumeration value='subscribed'/>
               <xs:enumeration value='unavailable'/>
               <xs:enumeration value='unsubscribe'/>
               <xs:enumeration value='unsubscribed'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='show'>
       <xs:simpleType>
         <xs:restriction base='xs:NCName'>
           <xs:enumeration value='away'/>
           <xs:enumeration value='chat'/>
           <xs:enumeration value='dnd'/>
           <xs:enumeration value='xa'/>
         </xs:restriction>
       </xs:simpleType>
     </xs:element>
        
     <xs:element name='show'>
       <xs:simpleType>
         <xs:restriction base='xs:NCName'>
           <xs:enumeration value='away'/>
           <xs:enumeration value='chat'/>
           <xs:enumeration value='dnd'/>
           <xs:enumeration value='xa'/>
         </xs:restriction>
       </xs:simpleType>
     </xs:element>
        
     <xs:element name='status'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='status'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:string'>
             <xs:attribute ref='xml:lang' use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='priority' type='xs:byte'/>
        
     <xs:element name='priority' type='xs:byte'/>
        
     <xs:element name='iq'>
       <xs:complexType>
         <xs:sequence>
           <xs:any     namespace='##other'
                       minOccurs='0'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='required'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='get'/>
               <xs:enumeration value='result'/>
               <xs:enumeration value='set'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='iq'>
       <xs:complexType>
         <xs:sequence>
           <xs:any     namespace='##other'
                       minOccurs='0'/>
           <xs:element ref='error'
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='from'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='id'
                       type='xs:NMTOKEN'
                       use='required'/>
         <xs:attribute name='to'
                       type='xs:string'
                       use='required'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='error'/>
               <xs:enumeration value='get'/>
               <xs:enumeration value='result'/>
               <xs:enumeration value='set'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute ref='xml:lang' use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='error'>
       <xs:complexType>
         <xs:sequence  xmlns:err='urn:ietf:params:xml:ns:xmpp-stanzas'>
           <xs:group   ref='err:stanzaErrorGroup'/>
           <xs:element ref='err:text'
        
     <xs:element name='error'>
       <xs:complexType>
         <xs:sequence  xmlns:err='urn:ietf:params:xml:ns:xmpp-stanzas'>
           <xs:group   ref='err:stanzaErrorGroup'/>
           <xs:element ref='err:text'
        
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='code' type='xs:byte' use='optional'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='auth'/>
               <xs:enumeration value='cancel'/>
               <xs:enumeration value='continue'/>
               <xs:enumeration value='modify'/>
               <xs:enumeration value='wait'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
       </xs:complexType>
     </xs:element>
        
                       minOccurs='0'/>
         </xs:sequence>
         <xs:attribute name='code' type='xs:byte' use='optional'/>
         <xs:attribute name='type' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='auth'/>
               <xs:enumeration value='cancel'/>
               <xs:enumeration value='continue'/>
               <xs:enumeration value='modify'/>
               <xs:enumeration value='wait'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
       </xs:complexType>
     </xs:element>
        
   </xs:schema>
        
   </xs:schema>
        
B.3 session
B.3会议
   <?xml version='1.0' encoding='UTF-8'?>
        
   <?xml version='1.0' encoding='UTF-8'?>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='urn:ietf:params:xml:ns:xmpp-session'
       xmlns='urn:ietf:params:xml:ns:xmpp-session'
       elementFormDefault='qualified'>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='urn:ietf:params:xml:ns:xmpp-session'
       xmlns='urn:ietf:params:xml:ns:xmpp-session'
       elementFormDefault='qualified'>
        
     <xs:element name='session' type='empty'/>
        
     <xs:element name='session' type='empty'/>
        
     <xs:simpleType name='empty'>
       <xs:restriction base='xs:string'>
         <xs:enumeration value=''/>
       </xs:restriction>
     </xs:simpleType>
        
     <xs:simpleType name='empty'>
       <xs:restriction base='xs:string'>
         <xs:enumeration value=''/>
       </xs:restriction>
     </xs:simpleType>
        
   </xs:schema>
        
   </xs:schema>
        
B.4 jabber:iq:privacy
B.4喋喋不休:智商:隐私
   <?xml version='1.0' encoding='UTF-8'?>
        
   <?xml version='1.0' encoding='UTF-8'?>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:iq:privacy'
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:iq:privacy'
        
       xmlns='jabber:iq:privacy'
       elementFormDefault='qualified'>
        
       xmlns='jabber:iq:privacy'
       elementFormDefault='qualified'>
        
     <xs:element name='query'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='active'
                       minOccurs='0'/>
           <xs:element ref='default'
                       minOccurs='0'/>
           <xs:element ref='list'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='query'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='active'
                       minOccurs='0'/>
           <xs:element ref='default'
                       minOccurs='0'/>
           <xs:element ref='list'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='active'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:NMTOKEN'>
             <xs:attribute name='name'
                           type='xs:string'
                           use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='active'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:NMTOKEN'>
             <xs:attribute name='name'
                           type='xs:string'
                           use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='default'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:NMTOKEN'>
             <xs:attribute name='name'
                           type='xs:string'
                           use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='default'>
       <xs:complexType>
         <xs:simpleContent>
           <xs:extension base='xs:NMTOKEN'>
             <xs:attribute name='name'
                           type='xs:string'
                           use='optional'/>
           </xs:extension>
         </xs:simpleContent>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='list'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='item'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
        
     <xs:element name='list'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='item'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
        
         <xs:attribute name='name'
                       type='xs:string'
                       use='required'/>
       </xs:complexType>
     </xs:element>
        
         <xs:attribute name='name'
                       type='xs:string'
                       use='required'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='item'>
       <xs:complexType>
         <xs:sequence>
           <xs:element name='iq'
                       minOccurs='0'
                       type='empty'/>
           <xs:element name='message'
                       minOccurs='0'
                       type='empty'/>
           <xs:element name='presence-in'
                       minOccurs='0'
                       type='empty'/>
           <xs:element name='presence-out'
                       minOccurs='0'
                       type='empty'/>
         </xs:sequence>
         <xs:attribute name='action' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='allow'/>
               <xs:enumeration value='deny'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute name='order'
                       type='xs:unsignedInt'
                       use='required'/>
         <xs:attribute name='type' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='group'/>
               <xs:enumeration value='jid'/>
               <xs:enumeration value='subscription'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute name='value'
                       type='xs:string'
                       use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='item'>
       <xs:complexType>
         <xs:sequence>
           <xs:element name='iq'
                       minOccurs='0'
                       type='empty'/>
           <xs:element name='message'
                       minOccurs='0'
                       type='empty'/>
           <xs:element name='presence-in'
                       minOccurs='0'
                       type='empty'/>
           <xs:element name='presence-out'
                       minOccurs='0'
                       type='empty'/>
         </xs:sequence>
         <xs:attribute name='action' use='required'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='allow'/>
               <xs:enumeration value='deny'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute name='order'
                       type='xs:unsignedInt'
                       use='required'/>
         <xs:attribute name='type' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='group'/>
               <xs:enumeration value='jid'/>
               <xs:enumeration value='subscription'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute name='value'
                       type='xs:string'
                       use='optional'/>
       </xs:complexType>
     </xs:element>
        
     <xs:simpleType name='empty'>
       <xs:restriction base='xs:string'>
         <xs:enumeration value=''/>
       </xs:restriction>
     </xs:simpleType>
        
     <xs:simpleType name='empty'>
       <xs:restriction base='xs:string'>
         <xs:enumeration value=''/>
       </xs:restriction>
     </xs:simpleType>
        
   </xs:schema>
        
   </xs:schema>
        
B.5 jabber:iq:roster
B.5叽叽喳喳:智商:花名册
   <?xml version='1.0' encoding='UTF-8'?>
        
   <?xml version='1.0' encoding='UTF-8'?>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:iq:roster'
       xmlns='jabber:iq:roster'
       elementFormDefault='qualified'>
        
   <xs:schema
       xmlns:xs='http://www.w3.org/2001/XMLSchema'
       targetNamespace='jabber:iq:roster'
       xmlns='jabber:iq:roster'
       elementFormDefault='qualified'>
        
     <xs:element name='query'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='item'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='query'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='item'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='item'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='group'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
         <xs:attribute name='ask' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='subscribe'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute name='jid' type='xs:string' use='required'/>
         <xs:attribute name='name' type='xs:string' use='optional'/>
         <xs:attribute name='subscription' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
        
     <xs:element name='item'>
       <xs:complexType>
         <xs:sequence>
           <xs:element ref='group'
                       minOccurs='0'
                       maxOccurs='unbounded'/>
         </xs:sequence>
         <xs:attribute name='ask' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
               <xs:enumeration value='subscribe'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
         <xs:attribute name='jid' type='xs:string' use='required'/>
         <xs:attribute name='name' type='xs:string' use='optional'/>
         <xs:attribute name='subscription' use='optional'>
           <xs:simpleType>
             <xs:restriction base='xs:NCName'>
        
               <xs:enumeration value='both'/>
               <xs:enumeration value='from'/>
               <xs:enumeration value='none'/>
               <xs:enumeration value='remove'/>
               <xs:enumeration value='to'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
       </xs:complexType>
     </xs:element>
        
               <xs:enumeration value='both'/>
               <xs:enumeration value='from'/>
               <xs:enumeration value='none'/>
               <xs:enumeration value='remove'/>
               <xs:enumeration value='to'/>
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
       </xs:complexType>
     </xs:element>
        
     <xs:element name='group' type='xs:string'/>
        
     <xs:element name='group' type='xs:string'/>
        
   </xs:schema>
        
   </xs:schema>
        

Appendix C. Differences Between Jabber IM/Presence Protocols and XMPP

附录C.Jabber IM/Presence协议与XMPP之间的差异

This section is non-normative.

本节是非规范性的。

XMPP has been adapted from the protocols originally developed in the Jabber open-source community, which can be thought of as "XMPP 0.9". Because there exists a large installed base of Jabber implementations and deployments, it may be helpful to specify the key differences between the relevant Jabber protocols and XMPP in order to expedite and encourage upgrades of those implementations and deployments to XMPP. This section summarizes the differences that relate specifically to instant messaging and presence applications, while the corresponding section of [XMPP-CORE] summarizes the differences that relate to all XMPP applications.

XMPP是从Jabber开源社区最初开发的协议改编而来的,可以将其视为“XMPP 0.9”。由于存在大量Jabber实现和部署的安装基础,因此指定相关Jabber协议和XMPP之间的关键区别可能会有所帮助,以加快并鼓励将这些实现和部署升级到XMPP。本节总结了与即时消息和状态应用程序相关的差异,[XMPP-CORE]的相应部分总结了与所有XMPP应用程序相关的差异。

C.1 Session Establishment
C.1会议的设立

The client-to-server authentication protocol developed in the Jabber community assumed that every client is an IM client and therefore initiated an IM session upon successful authentication and resource binding, which are performed simultaneously (documentation of this protocol is contained in [JEP-0078], published by the Jabber Software Foundation [JSF]). XMPP maintains a stricter separation between core functionality and IM functionality; therefore, an IM session is not created until the client specifically requests one using the protocol defined under Session Establishment (Section 3).

Jabber社区开发的客户机到服务器身份验证协议假设每个客户机都是IM客户机,因此在成功执行身份验证和资源绑定时启动IM会话,同时执行(该协议的文档包含在[JEP-0078]中),由JabBER软件基金会[JSF]发布。XMPP在核心功能和IM功能之间保持更严格的分离;因此,在客户端使用会话建立(第3节)中定义的协议专门请求IM会话之前,不会创建IM会话。

C.2 Privacy Lists
C.2隐私清单

The Jabber community began to define a protocol for communications blocking (privacy lists) in late 2001, but that effort was deprecated once the XMPP Working Group was formed. Therefore the protocol defined under Blocking Communication (Section 10) is the only such protocol defined for use in the Jabber community.

Jabber社区在2001年末开始定义通信阻塞协议(隐私列表),但一旦XMPP工作组成立,这一努力就遭到了反对。因此,阻塞通信(第10节)下定义的协议是Jabber社区中唯一定义的此类协议。

Contributors

贡献者

Most of the core aspects of the Extensible Messaging and Presence Protocol were developed originally within the Jabber open-source community in 1999. This community was founded by Jeremie Miller, who released source code for the initial version of the jabberd server in January 1999. Major early contributors to the base protocol also included Ryan Eatmon, Peter Millard, Thomas Muldowney, and Dave Smith. Work specific to instant messaging and presence by the XMPP Working Group has concentrated especially on IM session establishment and communication blocking (privacy lists); the session establishment protocol was mainly developed by Rob Norris and Joe Hildebrand, and the privacy lists protocol was originally contributed by Peter Millard.

可扩展消息和状态协议的大多数核心方面最初是在1999年Jabber开源社区中开发的。该社区由Jeremie Miller创建,他于1999年1月发布了jabberd服务器初始版本的源代码。基本协议的主要早期贡献者还包括Ryan Eatmon、Peter Millard、Thomas Muldowney和Dave Smith。XMPP工作组针对即时消息和状态的工作特别集中于IM会话建立和通信阻塞(隐私列表);会话建立协议主要由Rob Norris和Joe Hildebrand开发,隐私列表协议最初由Peter Millard提供。

Acknowledgements

致谢

Thanks are due to a number of individuals in addition to the contributors listed. Although it is difficult to provide a complete list, the following individuals were particularly helpful in defining the protocols or in commenting on the specifications in this memo: Thomas Charron, Richard Dobson, Schuyler Heath, Jonathan Hogg, Craig Kaes, Jacek Konieczny, Lisa Dusseault, Alexey Melnikov, Keith Minkler, Julian Missig, Pete Resnick, Marshall Rose, Jean-Louis Seguineau, Alexey Shchepin, Iain Shigeoka, and David Waite. Thanks also to members of the XMPP Working Group and the IETF community for comments and feedback provided throughout the life of this memo.

除了列出的贡献者之外,还要感谢许多个人。虽然很难提供完整的清单,但以下人员在定义协议或评论本备忘录中的规范方面特别有帮助:托马斯·查伦、理查德·多布森、舒勒·希思、乔纳森·霍格、克雷格·凯斯、雅切克·科尼茨尼、丽莎·杜肖特、阿列克谢·梅尔尼科夫、基思·明克尔、朱利安·米斯格、,皮特·雷斯尼克、马歇尔·罗斯、让·路易斯·塞吉诺、阿列克谢·什切平、伊恩·希戈卡和大卫·韦特。还感谢XMPP工作组和IETF社区的成员在本备忘录的整个生命周期中提供的意见和反馈。

Author's Address

作者地址

Peter Saint-Andre (editor) Jabber Software Foundation

Peter Saint Andre(编辑)Jabbor软件基金会

   EMail: stpeter@jabber.org
        
   EMail: stpeter@jabber.org
        

Full Copyright Statement

完整版权声明

Copyright (C) The Internet Society (2004).

版权所有(C)互联网协会(2004年)。

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

本文件受BCP 78中包含的权利、许可和限制的约束,除其中规定外,作者保留其所有权利。

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

本文件及其包含的信息是按“原样”提供的,贡献者、其代表或赞助的组织(如有)、互联网协会和互联网工程任务组不承担任何明示或暗示的担保,包括但不限于任何保证,即使用本文中的信息不会侵犯任何权利,或对适销性或特定用途适用性的任何默示保证。

Intellectual Property

知识产权

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the IETF's procedures with respect to rights in IETF Documents can be found in BCP 78 and BCP 79.

IETF对可能声称与本文件所述技术的实施或使用有关的任何知识产权或其他权利的有效性或范围,或此类权利下的任何许可可能或可能不可用的程度,不采取任何立场;它也不表示它已作出任何独立努力来确定任何此类权利。有关IETF文件中权利的IETF程序信息,请参见BCP 78和BCP 79。

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

向IETF秘书处披露的知识产权副本和任何许可证保证,或本规范实施者或用户试图获得使用此类专有权利的一般许可证或许可的结果,可从IETF在线知识产权存储库获取,网址为http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.

IETF邀请任何相关方提请其注意任何版权、专利或专利申请,或其他可能涵盖实施本标准所需技术的专有权利。请将信息发送至IETF的IETF-ipr@ietf.org.

Acknowledgement

确认

Funding for the RFC Editor function is currently provided by the Internet Society.

RFC编辑功能的资金目前由互联网协会提供。