XEP-0045

来自Jabber/XMPP中文翻译计划
(版本间的差异)
跳转到: 导航, 搜索
(范围)
(服务端)
 
(未显示4个用户的259个中间版本)
第1行: 第1行:
 
[[Category:XMPP扩展]]
 
[[Category:XMPP扩展]]
[[Category:翻译中]]
+
[[Category:已翻译]]
  
 
'''本文的英文原文来自[http://www.xmpp.org/extensions/xep-0045.html XEP-0045]'''
 
'''本文的英文原文来自[http://www.xmpp.org/extensions/xep-0045.html XEP-0045]'''
第12行: 第12行:
 
XMPP扩展协议的版权(1999-2008)归XMPP标准化基金会(XSF)所有
 
XMPP扩展协议的版权(1999-2008)归XMPP标准化基金会(XSF)所有
  
版权: © 1999 - 2010 XMPP标准化基金会(XSF). 参见法律通告.
+
版权: © 1999 - 2010 XMPP标准化基金会(XSF). 参见[[XEP-0045#法律通告|法律通告]].
  
 
状态: 草案
 
状态: 草案
第30行: 第30行:
 
==范围==
 
==范围==
  
本文着重于和配置,参与以及管理一个独立的基于文本的会议室相关的通用需求. 这里所指出的需求是应用于单个房间级别的并且是"通用的", 某种意义上它们是在Jabber社区广泛讨论的或在现有的Jabber之外的基于文本的会议环境(例如, 定义在 RFC 1459 [1]中的Internet Relay Chat 和它的继承者: RFC 2810 \[2\], RFC 2811 \[3\], RFC 2812 \[4\], RFC 2813 \[5\])中已经存在的.
+
本文着重于和配置,参与以及管理一个独立的基于文本的会议室相关的通用需求. 这里所指出的需求是应用于单个房间级别的并且是"通用的", 某种意义上它们是在Jabber社区广泛讨论的或在现有的Jabber之外的基于文本的会议环境(例如, 定义在 [http://tools.ietf.org/html/rfc1459 RFC 1459] [[XEP-0045#附录G:备注|1]]中的Internet Relay Chat 和它的继承者: [http://tools.ietf.org/html/rfc2810 RFC 2810] [[XEP-0045#附录G:备注|2]], [http://tools.ietf.org/html/rfc2811 RFC 2811] [[XEP-0045#附录G:备注|3]], [http://tools.ietf.org/html/rfc2812 RFC 2812] [[XEP-0045#附录G:备注|4]], [http://tools.ietf.org/html/rfc2813 RFC 2813] [[XEP-0045#附录G:备注|5]])中已经存在的.
  
 
本文明确地不涉及以下需求:
 
本文明确地不涉及以下需求:
  
* 房间之间的关系(例如, 房间的层次)
+
* 房间之间的关系(例如, 房间的层次结构)
  
* 多用户聊天服务的管理(例如, 管理跨越整个服务级别的许可或注册一个全局可用的房间昵称)
+
* 多用户聊天服务的管理(例如, 管理跨越整个服务级别的权限或注册一个全局可用的房间昵称);这些用例定义在[http://xmpp.org/extensions/xep-0133.html Service Administration] [[XEP-0045#附录G:备注|6]]
  
* 独立消息的Moderation
+
* 个别消息的主持
  
* 房间或服务级别的安全和加密
+
* 通过房间发送的消息的加密
  
* 高级特性, 如附加文件给一个房间, 集成白板, 以及和语音服务的交互
+
* 高级特性, 如附加文件给一个房间, 集成白板, 以及和语音或视频聊天服务的接口
  
 
* MUC部署和外来的聊天系统(例如, 和IRC网关或现有的其他IM系统)之间的交互
 
* MUC部署和外来的聊天系统(例如, 和IRC网关或现有的其他IM系统)之间的交互
  
* 在MUC部署之间进行镜像或复制
+
* 在多个MUC部署之间进行镜像或复制
  
这一受限的范围并非蔑视这些都很有用的主题; 无论如何, 这意味着本文专注于讨论和介绍一个易于理解的协议能够被类似的Jabber客户端和组件开发者实现. 将来的协议当然可以涉及以上提到的这些主题.
+
这一受限的范围并非蔑视这些都很有用的主题; 无论如何, 这意味着本文专注于讨论和介绍一个易于理解的协议能够被类似的Jabber客户端和组件开发者实现. 将来的协议当然可能涉及以上提到的这些主题.
  
 
==需求==
 
==需求==
  
本文指明了由Jabber现有的多用户聊天服务提供的最小功能集. 为了向后兼容性的原因, 本文使用原来的"groupchat 1.0"协议作为基线功能, 包括以下这些:
+
本文描述了由Jabber现有的多用户聊天服务提供的最小功能集. 为了向后兼容性起见, 本文使用原来的"groupchat 1.0"协议作为基本功能, 包括以下这些:
  
 
* 每个房间被标识为 <room@service> (例如, <jdev@conference.jabber.org>), 这里 "room" 是房间的名称而 "service" 是多用户聊天服务运行所在的主机名.
 
* 每个房间被标识为 <room@service> (例如, <jdev@conference.jabber.org>), 这里 "room" 是房间的名称而 "service" 是多用户聊天服务运行所在的主机名.
  
* 在一个房间里每个驻留者被标识为 <room@service/nick>, 这里 "nick" 是这个驻留者的房间昵称,定义于加入房间的时候或后来在驻留者驻留房间期间修改.
+
* 在一个房间里每个房客被标识为 <room@service/nick>, 这里 "nick" 是这个房客在这个房间里的昵称,定义于刚加入这个房间的时候,也可以在房客驻留改房间期间修改.
  
* 一个用户通过发送一个出席信息给 <room@service/nick> 来加入一个房间.
+
* 一个用户通过发送出席信息给 <room@service/nick> 来加入一个房间(也就是成为房客).
  
* 在多用户聊天房间里发送的消息使用特殊的类型"groupchat"并且被定向于房间本身 (room@service), 然后反射给所有参与者.
+
* 在多用户聊天房间里发送的消息使用特殊的类型"groupchat"并且被寻址于房间本身 (room@service), 然后反映给所有房客.
  
* 一个驻留者可以改变他或她的房间昵称以及在房间中的可用性状态, 通过发送出席信息给 <room@service/newnick>.
+
* 通过发送出席信息给 <room@service/newnick>,一个房客可以改变他或她的房间昵称以及在房间中的可用性状态 .
  
* 一个驻留者通过发送一个类型为"unavailable"的出席信息给当前的<room@service/nick>来退出房间.
+
* 通过发送一个类型为"unavailable"的出席信息给当前的<room@service/nick>,一个房客可以退出房间.
  
 
本文追加的特性和功能包括以下这些:
 
本文追加的特性和功能包括以下这些:
  
 
# 本地会话日志(不需要房间内的机器人)
 
# 本地会话日志(不需要房间内的机器人)
# 用户可以申请成为一个房间的成员
+
# 允许用户申请房间成员
# 在一个非匿名房间里, 驻留者可以察看一个驻留者的全JID
+
# 在一个非匿名房间里, 允许房客可以察看(另)一个房客的全JID
# 在一个半匿名房间里, moderators可以察看一个驻留者的全JID
+
# 在一个半匿名房间里, 允许主持人可以察看一个房客的全JID
# 只允许moderators修改房间主题
+
# 允许只有主持人修改房间主题
# moderators可以从房间里踢出参与者和访问者
+
# 允许主持人从房间里踢出与会者和游客
# 在一个moderated房间里,moderators可以授权和禁止交谈(也就是说, 交谈的特权), 并且管理交谈列表
+
# 在一个被主持的房间里,主持人可以授予和撤销发言权(也就是说, 发言的权力), 并且管理发言权列表
# 管理员可以授权和取消moderator特权, 并且管理moderator列表
+
# 允许管理员授权和取消主持人权力, 并且管理主持人列表
# 管理员可以在房间禁止用户, 并且管理黑名单
+
# 允许管理员在房间禁止用户, 并管理黑名单
# 管理员可以授权和取消成员特权, 并且管理一个只有成员可以加入的房间的成员列表
+
# 允许管理员授予和撤销成员权力, 并且管理一个仅限成员的房间的成员列表
# 所有者可以限制驻留者的数量
+
# 允许所有者限制房客的数量
# 所有者可以指定其他的所有者
+
# 允许所有者指定其他的所有者(们)
# 所有者可以授权或取消管理特权, 并且管理管理员列表
+
# 允许所有者授予或撤销管理特权, 并管理管理员列表
# 所有者可以销毁房间
+
# 允许所有者销毁房间
  
 
另外, 本文提供了协议元素用于支持以下房间类型:
 
另外, 本文提供了协议元素用于支持以下房间类型:
  
# 公共或隐藏
+
# 公共的或隐藏的
# 持久或临时
+
# 持久的或临时的
# 密码保护或不安全的
+
# 密码保护的或不安全的
# 仅限成员或开放
+
# 仅限成员的或开放的
# moderated或unmoderated
+
# 主持的或非主持的
# 非匿名或半匿名
+
# 非匿名的或半匿名的
  
为了实现这些需求, 本扩展协议需要符合 'http://jabber.org/protocol/muc' 名字空间(以及 在主名字空间URI加上 #owner, #admin, 和 #user 片断).
+
为了实现这些需求, 本扩展协议需要满足 'http://jabber.org/protocol/muc' 名字空间(以及 在主名字空间URI加上 #owner, #admin, 和 #user 片断).
  
 
==术语==
 
==术语==
第98行: 第98行:
 
===通用术语===
 
===通用术语===
  
Affiliation(从属关系) -- 一个长期存在的和房间之间的联系或连接; 可能的从属关系有 "owner"(所有者), "admin"(管理者), "member"(成员), 以及 "outcast"(被排斥者) (当然也可能没有从属关系); 从属关系从角色来看唯一的. 一个从属关系跨越了用户对一个房间的访问期间.
+
Affiliation(岗位) -- 一个长期存在的和房间之间的联系或连接; 可能的岗位有 "owner"(所有者), "admin"(管理者), "member"(成员), 以及 "outcast"(被排斥者) (当然也可能没有岗位); 岗位(affiliation)和角色(role)是有区别的. 一个岗位跨越了用户对一个房间的访问期间.
  
Ban(禁止) -- 从一个房间移除一个用户以使这个用户不能够再进入这个房间 (直到这个禁令被废除为止). 一个被禁止的用户的从属关系为 "outcast"(被排斥者).
+
Ban(禁止) -- 从一个房间移除一个用户以使这个用户不能够再进入这个房间 (直到这个禁令被废除为止). 一个被禁止的用户的岗位(affiliation)为 "outcast"(被排斥者).
  
 
Bare JID(纯JID) -- 一个用户的标识符 <user@host>, 不同于任何已有会话或资源的上下文, 与之相对的是全JID和房间JID.
 
Bare JID(纯JID) -- 一个用户的标识符 <user@host>, 不同于任何已有会话或资源的上下文, 与之相对的是全JID和房间JID.
第106行: 第106行:
 
Full JID(全JID) -- 一个在线用户的标识符 <user@host/resource> , 不同于一个房间的上下文; 与之相对的是纯JID和房间JID.
 
Full JID(全JID) -- 一个在线用户的标识符 <user@host/resource> , 不同于一个房间的上下文; 与之相对的是纯JID和房间JID.
  
GC -- 最小的 "groupchat 1.0" 协议\[6\], Jabber社区于1999年开发; MUC 向后兼容GC.
+
GC -- 最小的 "groupchat 1.0" 协议[7], Jabber社区于1999年开发; MUC 向后兼容GC.
  
History(历史) -- 有限数量的消息节, 由当前讨论的上下文提供发送给一个新的驻留者.
+
History(历史) -- 有限数量的消息节, 由当前讨论的上下文提供发送给一个新的房客.
  
Invitation(邀请) -- 从一个用户发出的特殊消息给另一个用户, 邀请对方加入房间.
+
Invitation(邀请) -- 从一个用户发出的特殊消息给另一个用户, 邀请对方加入房间.; the invitation can be sent directly (see Direct MUC Invitations [8]) or mediated through the room (as described under Inviting Another User to a Room).
  
 
IRC -- Internet Relay Chat.
 
IRC -- Internet Relay Chat.
  
Kick(踢人) -- 临时从一个房间移除一个参与者或访问者; 这个用户任何时候都可以再次进入这个房间. 一个被踢的用户的角色是"none".
+
Kick(踢人) -- 临时从一个房间移除一个与会者或游客; 这个用户任何时候都可以再次进入这个房间. 一个被踢的用户的角色是"none".
  
 
Logging(记录) -- 存储发生在一个房间的讨论内容用于公开发布到房间上下文之外的地方.
 
Logging(记录) -- 存储发生在一个房间的讨论内容用于公开发布到房间上下文之外的地方.
  
Member(成员) -- 一个用户在一个仅限会员的房间内处于"white list"(白名单)内或已经注册到一个公开的房间. 一个成员拥有一个"member"从属关系.
+
Member(成员) -- 一个用户在一个仅限会员的房间内处于"white list"(白名单)内,或已经注册到一个公开的房间. 一个成员的岗位是"member".
  
Moderator(主持人) -- 一个房间角色,通常和房间的管理有关但是这个角色可以被赋予非管理员; 可以踢人, 可以允许和禁止发言, 等等. 一个 moderator 有一个 "moderator" 的角色.
+
Moderator(主持人) -- 一个房间角色,通常和房间的管理有关但是这个角色可以被赋予非管理员; 可以踢人, 可以授予和撤销发言权, 等等. 一个主持人的角色是"moderator".
  
 
MUC -- 本文所定义的基于文本会议的多用户聊天协议.
 
MUC -- 本文所定义的基于文本会议的多用户聊天协议.
  
Occupant(驻留者) -- 一个房间里的任何Jabber用户 (这是一个 "抽象类" 并且不属于任何特定的角色).
+
Occupant(房客) -- 一个房间里的任何Jabber用户 (这是一个 "抽象类" 并且不对应任何特定的角色).
  
Outcast(被排斥者) -- 一个被某个房间禁止的用户. 一个被排斥者的从属关系是 "outcast".
+
Occupant JID(房客JID) -- 在一个房间上下文中的一个房客,以 <room@service/nick> 来标识; 与之相对的是纯JID和全JID.
  
Participant(参与者) -- 一个没有管理权限的驻留者; 在一个 moderated 房间里, 一个参与者更多地被定义为有发言权的 (与之相反的是访问者). 一个参与者有一个 "participant" 的角色.
+
Outcast(被排斥者) -- 一个被某个房间禁止的用户. 一个被排斥者的岗位是 "outcast".
  
Private Message(私有消息) -- 从一个驻留者直接发给另一个房间JID的消息(不是房间本身广播给所有驻留者的消息).
+
Participant(与会者) -- 一个没有管理权限的房客; 在一个被主持的房间里, 参与者更多地被定义为有发言权的 (与之相反的是游客). 一个与会者的角色是"participant".
  
Role(角色) -- 在一个房间里的一个临时的地位或者权限级别, 对于这个房间中用户的长期从属关系来说是唯一的; 可能的角色有 "moderator", "participant"(参与者), 和 "visitor"(访问者) (也可能没有定义好的角色). 一个角色仅仅存在于一个驻留者访问一个房间的期间.
+
Private Message(私有消息) -- 从一个房客直接发给另一个房间JID的消息(不是房间本身广播给所有房客的消息).
 +
 
 +
Role(角色) -- 在一个房间里的一个临时的地位或者权限级别, 对于这个房间中的用户的长期岗位来说是唯一的; 可能的角色有 "moderator"(主持人), "participant"(与会者), 和 "visitor"(游客) (也可能没有预定义的角色). 一个角色仅仅存在于一个房客访问一个房间的期间.
  
 
Room(房间) -- 一个虚拟的地方, Jabber用户象征性地加入它, 来和其他用户一起参与一个实时的基于文本的会议.
 
Room(房间) -- 一个虚拟的地方, Jabber用户象征性地加入它, 来和其他用户一起参与一个实时的基于文本的会议.
  
Room Administrator(房间管理员) -- 一个由房间所有这授权的用户, 可以执行管理功能, 如禁止用户等等; 无论如何, 不允许改变定义的房间特性. 一个管理员有一个 "admin" 从属关系.
+
Room Administrator(房间管理员) -- 一个由房间所有者授权的用户, 可以执行管理功能, 如禁止用户等等; 无论如何, 不允许改变定义的房间特性. 一个管理员的岗位是"admin" .
  
 
Room ID(房间ID) -- 一个房间JID的节点标识符部分, 它可以是不透明的因而对人类用户没有什么含义(见  语法的商业规则Business Rules for syntax); 与之相对的是房间名.
 
Room ID(房间ID) -- 一个房间JID的节点标识符部分, 它可以是不透明的因而对人类用户没有什么含义(见  语法的商业规则Business Rules for syntax); 与之相对的是房间名.
  
Room JID(房间JID) -- 在一个房间上下文中一个驻留者以 <room@service/nick> 来标识; 与之相对的是纯JID和全JID.
+
Room JID(房间JID) -- 房间地址,如 <room@service>  
  
Room Name(房间名) -- 一个用户友好的, 自然语言的房间名字, 由房间所有者配置并在服务发现查询中展示; 相对的是房间ID.
+
Room Name(房间名) -- 一个用户友好的, 自然语言的房间名字, 由房间所有者配置并在服务查询中展示; 与之相对的是房间ID.
  
Room Nickname(房间昵称) -- 房间JID的资源标识符部分(见语法的商业规则); 这是这个房间中一个驻留者展示自己的"友好的名字".
+
Room Nickname(房间昵称) -- 房间JID的资源标识符部分(见语法的商业规则); 这是一个房客在这个房间中所呈现的"友好的名字".
  
Room Owner(房间所有者) -- 建立某个房间的Jabber用户或一个被房间创建者或所有者指派拥有所有者权限(如果允许的话)的Jabber用户; 它被允许改变定义好的房间特性, 也可以执行全部的管理功能. 一个所有者的从属关系为"owner".
+
Room Owner(房间所有者) -- 建立某个房间的Jabber用户或一个被房间创建者或所有者指派拥有所有者权限(如果允许的话)的Jabber用户; 它被允许改变定义好的房间特性, 也可以执行全部的管理功能. 一个所有者的岗位为"owner".
  
Room Roster(房间名册) -- 一个房间中的所有驻留者在一个Jabber客户端的展现.
+
Room Roster(房间名册) -- 一个房间中的所有房客在一个Jabber客户端的展现.
  
Server(服务器) -- 一个Jabber服务器可以选择是否关联一个基于文本的会议服务.
+
Server(服务器) -- 一个Jabber服务器,可以关联或不关联一个基于文本的会议服务.
  
 
Service(服务) -- 一个主机, 提供基于文本的会议的能力; 通常但不必须是一个Jabber服务器的子域(例如, conference.jabber.org).
 
Service(服务) -- 一个主机, 提供基于文本的会议的能力; 通常但不必须是一个Jabber服务器的子域(例如, conference.jabber.org).
  
Subject(主题) -- 一个房间的一个临时讨论标题.
+
Subject(主题) -- 一个房间的临时讨论标题.
  
Visit(访问) -- 一个房间的一个用户的"session"(会话), 当用户进入这个房间时开始(也就是说, 成为一个驻留者) , 结束于用户离开房间之时.
+
Visit(访问) -- 一个房间的一个用户的"session"(会话), 当用户进入这个房间时开始(也就是说, 成为一个房客) , 结束于用户离开房间之时.
  
Visitor(访问者) -- 在一个 moderated 房间, 一个没有发言权的驻留者(相反的是一个参与者). 一个访问的角色是"visitor".
+
Visitor(游客) -- 在一个被主持的房间里的一个没有发言权的房客(相反则是一个与会者). 一个游客的角色是"visitor".
  
Voice(发言权) -- 在一个 moderated 房间, 发送消息给全部参与者的权限.
+
Voice(发言权) -- 在一个被主持的房间里, 发送消息给全部房客的权限.
  
 
===房间类型===
 
===房间类型===
  
Fully-Anonymous Room(全匿名房间) -- 一个房间的驻留者的全JID或纯JID不能被任何人查询到, 包括房间管理员和房间所有者; 这类房间是不推荐的(NOT RECOMMENDED)或不被MUC显式支持, 但是如果一个服务可能会提供适当的配置选项来使用这个协议; 相对的则是非匿名房间和半匿名房间.
+
Hidden Room(隐藏房间) -- 一个无法被任何用户以普通方法如搜索和服务查询来发现的房间; 反义词: 公开(public)房间.
  
Hidden Room(隐藏房间) -- 一个无法被任何用户以普通方法如搜索和服务查询来发现的房间; 反义词: 公开房间.
+
Members-Only Room(仅限会员的房间) -- 如果一个用户不在成员列表中则无法加入的一个房间; 反义词: 开放(open)房间.
  
Members-Only Room(仅限会员的房间) -- 如果一个用户不在成员列表中则无法加入的一个房间; 反义词: 开放房间.
+
Moderated Room(被主持的房间) -- 只有有"发言权"的用户才可以发送消息给所有房客的房间; 反义词: 非主持的(Unmoderated)房间.
  
Moderated Room(Moderated房间) -- 只有有"发言权"的用户才可以发送消息给所有驻留者的房间; 反义词: Unmoderated房间.
+
Non-Anonymous Room(非匿名房间) -- 一个房客的全JID会暴露给所有其他房客的房间, 尽管房客可以选择任何期望的房间昵称; 相对的是半匿名(Semi-Anonymous)房间.
 
+
Non-Anonymous Room(非匿名房间) -- 一个驻留者的全JID会暴露给所有其他驻留者的房间, 尽管驻留者可以选择任何期望的房间昵称; 相对的是半匿名房间和全匿名房间.
+
  
 
Open Room(开放房间) -- 任何人可以加入而不需要在成员列表中的房间; 反义词: 仅限会员的房间.
 
Open Room(开放房间) -- 任何人可以加入而不需要在成员列表中的房间; 反义词: 仅限会员的房间.
第178行: 第178行:
 
Password-Protected Room(密码保护房间) -- 一个用户必须提供正确密码才能加入的房间; 反义词: 非保密房间.
 
Password-Protected Room(密码保护房间) -- 一个用户必须提供正确密码才能加入的房间; 反义词: 非保密房间.
  
Persistent Room(持久房间) -- 如果最后一个驻留者退出也不会被销毁的房间; 反义词: 临时房间.
+
Persistent Room(持久房间) -- 如果最后一个房客退出也不会被销毁的房间; 反义词: 临时房间.
  
 
Public Room(公开房间) -- 用户可以通过普通方法如搜索和服务查询来发现的房间; 反义词: 隐藏房间.
 
Public Room(公开房间) -- 用户可以通过普通方法如搜索和服务查询来发现的房间; 反义词: 隐藏房间.
  
Semi-Anonymous Room(半匿名房间) -- 一个驻留者的全JID只能被房间管理员发现的房间; 相对的是全匿名房间和非匿名房间.
+
Semi-Anonymous Room(半匿名房间) -- 一个房客的全JID只能被房间管理员发现的房间; 相对的是非匿名(Non-Anonymous)房间.
  
Temporary Room(临时房间) -- 如果最后一个驻留者退出就会被销毁的房间; 反义词: 持久房间.
+
Temporary Room(临时房间) -- 如果最后一个房客退出就会被销毁的房间; 反义词: 持久房间.
  
Unmoderated Room(Unmoderated房间) -- 任何驻留者都被允许发送消息给所有驻留者的房间; 反义词: Moderated房间.
+
Unmoderated Room(非主持的房间) -- 任何房客都被允许发送消息给所有房客的房间; 反义词: 被主持的房间.
  
 
Unsecured Room(非保密房间) -- 任何人不需要提供密码就可以进入的房间; 反义词: 密码保护房间.
 
Unsecured Room(非保密房间) -- 任何人不需要提供密码就可以进入的房间; 反义词: 密码保护房间.
  
===4.3 人物===
+
===登场人物===
  
本文的大部分例子使用了 the scenario of the witches' meeting held in a dark cave at the beginning of Act IV, Scene I of Shakespeare's Macbeth, 在这里代表"darkcave@macbeth.shakespeare.lit"聊天室. 人物如下:
+
本文的大部分例子使用了莎士比亚的《麦克白》中第四幕第一场开头女巫在黑洞中开会的场景,在这里使用"coven@chat.shakespeare.lit"代表聊天室. 人物如下:
  
 
'''表1: 剧中人'''
 
'''表1: 剧中人'''
  
 
{|border="1" cellspacing="0"  
 
{|border="1" cellspacing="0"  
!房间昵称 !!JID !!从属关系
+
!Room Nickname !!Full JID!!Affiliation
 
|-
 
|-
|firstwitch ||crone1@shakespeare.lit/desktop ||所有者
+
|firstwitch ||crone1@shakespeare.lit/desktop ||Owner
 
|-
 
|-
|secondwitch ||wiccarocks@shakespeare.lit/laptop ||管理员
+
|secondwitch ||wiccarocks@shakespeare.lit/laptop ||Admin
 
|-
 
|-
|thirdwitch ||hag66@shakespeare.lit/pda ||
+
|thirdwitch ||hag66@shakespeare.lit/pda ||None
 
|}
 
|}
  
==角色和从属关系==
+
==角色(Roles),岗位(Affiliations)和权限(Privileges)==
  
有两个尺度我们可以用来衡量一个用户的连接或在一个房间的地位. 一个是用户和一个房间的长期的从属关系 -- 例如, 一个用户的状态是一个所有者或一个被驱逐者. 另一个是当一个用户驻留于一个聊天室的时候的角色 -- 例如, 一个驻留者的地位是一个主持人,有权利踢出访问者和参与者. 这两个尺度各自都是唯一的, 因为一个从属关系是跨越访问的, 而一个角色只存在于一次访问期间. 另外, 在角色和从属关系之间没有一对一的对应关系; 例如, 某个不从属于某房间的人可能成为一个(临时的)主持人, 以及一个成员可能在一个moderated房间中是一个参与者或访问者. 这些概念以下全面解释.
+
A user might be allowed to perform any number of actions in a room, from joining or sending a message to changing configuration options or destroying the room altogether. We call each permitted action a "privilege". There are two ways we might structure privileges:
 +
 
 +
1. Define each privilege atomically and explicitly define each user's particular privileges; this is flexible but can be confusing to manage.
 +
 
 +
2. Define bundles of privileges that are generally applicable and assign a user-friendly "shortcut" to each bundle (e.g., "moderator" or "admin").
 +
 
 +
MUC使用第2种方式。
 +
 
 +
有两个尺度我们可以用来衡量一个用户的连接或在一个房间的地位. 一个是用户和一个房间的长期的联系 -- 例如, 用户的状态是一个所有者或一个被排斥者. 另一个是当用户驻留于一个聊天室的时候的角色 -- 例如, 一个房客的地位是主持人,有权踢出游客和与会者. 这两个尺度各自都是唯一的, 因为一个岗位是跨越访问的, 而一个角色只存在于一次访问期间. 另外, 在角色和岗位之间没有一对一的对应关系; 例如, 某个不从属于某房间的人可能成为一个(临时的)主持人, 一个成员可能在一个被主持的房间中是一个与会者或游客者. 这些概念以下全面解释.
  
 
===角色===
 
===角色===
  
一个驻留者可能有四种已定义的角色:
+
以下是已定义的角色:
  
# 主持人
+
'''表2: 角色'''
# 参与者
+
{|border="1" cellspacing="0"
# 来访者
+
!名称 !!支持
# 无 (没有角色)
+
|-
 +
| 主持人Moderator  ||必需的
 +
|-
 +
| 无None      ||缺少角色
 +
|-
 +
| 与会者Participant  ||必需的
 +
|-
 +
| 游客Visitor    ||推荐的
 +
|}
  
角色是临时的,它不需要在用户对房间的访问中持续,它可以(MAY)在一个驻留者访问房间期间改变. 一个实现可以(MAY)穿越访问地持久化角色并且应该(SHOULD)在 moderated 房间这样做 (因为在访问者和参与者之间,唯一性对一个 moderated 房间是很关键的).
+
角色是临时的,它不一定要在用户对房间的访问中持久化,它可以(MAY)在一个房客访问房间期间改变. 一个实现可以(MAY)在一次访问期间持久化角色并且应该(SHOULD)在被主持的房间这样做 (因为在游客和与会者之间,唯一性对一个被主持的房间是很关键的).
  
在角色和从属关系之间没有一对一的映射(例如, 一个成员可以是一个参与者或一个访问者).
+
在角色和岗位之间没有一对一的映射(例如, 一个成员可以是一个与会者或一个游客).
  
在房间会话中,一个主持人是最有权力的驻留者, 它能在某种程度走上管理房间的其他驻留者的角色. 一个参与者的权力小于一个主持人, 尽管他或她有权限发言. 在一个moderated房间会话中一个访问者是一个更受限制的角色, 因为访问者不允许发送消息给所有驻留者.
+
在房间会话中,一个主持人是最有权力的房客, 它能在某种程度走上管理房间的其他房客的角色. 一个与会者的权力小于一个主持人, 尽管他或她有权发言. 在一个被主持的房间会话中游客是一个更受限制的角色, 因为访问者不允许发送消息给所有房客.
  
角色的授权,废除, 和维护是基于驻留者的房间昵称或全JID,而不是纯JID. 和这些角色相关的权限,还有角色改变触发的动作, 定义如下.
+
角色的授予,撤销, 和维护是基于房客的房间昵称或全JID,而不是纯JID. 和这些角色相关的权限,还有角色改变触发的动作, 定义在下文中.
  
关于角色的信息必须(MUST)在房间生成或反射的所有出席信息中被发送,从而也被发送给驻留者们.
+
所有在房间中生成或反射的出席信息中关于角色的信息必须(MUST)被发送,从而发送给房客们.
  
 
====权限====
 
====权限====
  
大部分情况下, 角色存在于一个等级中. 例如, 一个参与者可以做任何访问者能做的事, 而一个主持人可以做任何参与者能做的事. 每个角色拥有下一级角色所没有的权限; 这些权限定义于下表作为缺省值(一个实现可以(MAY)提供配置选项来超越这些缺省值).
+
大部分情况下, 角色存在于一个层次中. 例如, 一个与会者可以做任何游客能做的事, 而一个主持人可以做任何与会者能做的事. 每个角色拥有下一级角色所没有的权限; 这些权限定义于下表作为缺省值(一个实现可以(MAY)提供配置选项来重载这些缺省值).
  
'''表2: 和角色相关的权限'''
+
'''表3: 和角色相关的权限'''
  
 
{|border="1" cellspacing="0"  
 
{|border="1" cellspacing="0"  
!权限 !!无 !!访问者 !!参与者 !!主持人
+
!权限 !!无 !!游客 !!与会者 !!主持人
 
|-
 
|-
 
|在房间中出席 ||否 ||是 ||是 ||是
 
|在房间中出席 ||否 ||是 ||是 ||是
 
|-
 
|-
 
|接收消息 ||否 ||是 ||是 ||是
 
|接收消息 ||否 ||是 ||是 ||是
 +
|-
 +
|接收房客出席信息 ||否 ||是* ||是 ||是
 +
|-
 +
|出席信息广播到房间 ||否 ||是* ||是 ||是
 
|-
 
|-
 
|改变可用性状态 ||否 ||是 ||是 ||是
 
|改变可用性状态 ||否 ||是 ||是 ||是
第254行: 第274行:
 
|修改标题 ||否 ||否* ||是* ||是
 
|修改标题 ||否 ||否* ||是* ||是
 
|-
 
|-
|踢出参与者和访问者 ||否 ||否 ||否 ||是
+
|踢出与会者和游客 ||否 ||否 ||否 ||是
 
|-
 
|-
 
|授予发言权 ||否 ||否 ||否 ||是
 
|授予发言权 ||否 ||否 ||否 ||是
 
|-
 
|-
|收回发言权 ||否 ||否 ||否 ||是***
+
|撤销发言权 ||否 ||否 ||否 ||是***
 
|}
 
|}
  
* 缺省; 配置设定可以(MAY)修改这个权限.
+
* 缺省; 设定配置时可以(MAY)修改这个权限.
  
** 一个实现可以(MAY)在非主持的房间缺省地授予发言权给访问者.
+
** 一个实现可以(MAY)在非主持的房间里缺省地授予发言权给游客.
  
*** 一个主持人不能(MUST NOT)从一个管理员或所有者收回发言权.
+
*** 主持人不能(MUST NOT)从一个管理员或所有者收回发言权.
 +
 
 +
====默认角色====
 +
 
 +
服务必须(SHOULD)根据用户的岗位信息来设置房客在房间里的默认角色(没有与岗位(“outcast”)关联的默认角色,因为outcast用户不允许进入房间)。下表对与每个岗位关联的默认角色进行了总结。
 +
 
 +
表4: 基于岗位的默认角色
 +
 
 +
{|border="1" cellspacing="0"
 +
!Room Type !!None !!Member !!Admin !!Owner
 +
|-
 +
|Moderated ||Visitor ||Participant ||Moderator ||Moderator
 +
|-
 +
|Unmoderated ||Participant ||Participant ||Moderator ||Moderator
 +
|-
 +
|Members-Only ||N/A * ||Participant ||Moderator ||Moderator
 +
|-
 +
|Open ||Participant ||Participant ||Moderator ||Moderator
 +
|}
 +
* Entry is not permitted.
  
 
====变更角色====
 
====变更角色====
  
一个驻留者的角色变更方法是定义好的. 有时候驻留者自己的动作导致变更 (例如, 介入或退出房间), 反之有时候由主持人,管理员或所有者的动作导致变更. 如果一个驻留者的角色改变了, 一个 MUC 服务实现必须(MUST)变更这个驻留者的角色来反映这个变更并且传达这已变更给所有驻留者. 角色的变更和它们触发的动作定义于下表.
+
一个房客的角色变更方法是定义好的. 有时候房客自己的动作导致变更 (例如, 加入或退出房间), 反之有时候由主持人,管理员或所有者的动作导致变更. 如果一个房客的角色改变了, 一个 MUC 服务实现必须(MUST)变更这个房客的角色来反映这个变更并且传达这个变更给所有房客. 角色的变更和它们触发的动作定义于下表.
  
'''表3: 角色状态表'''
+
'''表4: 角色状态表'''
  
 
{|border="1" cellspacing="0"  
 
{|border="1" cellspacing="0"  
!> !!无 !!访问者 !!参与者 !!主持人
+
!> !!无 !!游客 !!与会者 !!主持人
 
|-
 
|-
|无 ||-- ||进入moderated房间 ||进入unmoderated房间 ||管理员或所有者进入房间
+
|无 ||-- ||进入被主持的房间 ||进入非主持的房间 ||管理员或所有者进入房间
 
|-
 
|-
|访问者 ||退出房间或被主持人踢出房间 ||-- ||主持人授予发言权 ||管理员或所有者授予主持人权限
+
|游客 ||退出房间或被主持人踢出房间 ||-- ||主持人授予发言权 ||管理员或所有者授予主持人权限
 
|-
 
|-
|参与者 ||退出房间或被主持人踢出房间 ||主持人收回发言权 |-- ||管理员或所有者授予主持人权限
+
|与会者 ||退出房间或被主持人踢出房间 ||主持人撤销发言权 ||-- ||管理员或所有者授予主持人权限  
 
|-
 
|-
|主持人 ||退出房间 ||管理员或所有者改变角色成为访问者* ||管理员或所有者改变角色成为参与者或收回主持人权限* ||--
+
|主持人 ||退出房间 ||管理员或所有者改变角色成为游客* ||管理员或所有者改变角色成为与会者或撤销主持人权限* ||--
 
|}
 
|}
  
* 一个主持人不能(MUST NOT)从一个级别属于等于或高于主持人的驻留者那里收回主持人权限.
+
* 一个主持人不能(MUST NOT)从一个岗位等于或高于主持人的房客那里收回主持人权限.
  
注意: 特定的角色一般暗含特定的权限. 例如, 一个管理员或所有者自动成为一个主持人, 所以如果一个驻留者被授予管理员地位那么这个驻留者事实上将被授予主持人权限; 类似的, 当一个驻留者成为一个 moderated 房间的成员, 这个驻留者自动拥有一个参与者的角色. 无论如何, 失去管理员地位并不足以意味这个驻留者不再是主持人 (因为只要是参与者就可能成为一个主持人). 因此, 当一个驻留者被授予特定的从属关系的时候所拥有的角色是固定的, 反之当一个驻留者失去一个特定的从属关系它的角色是不确定的并取决于(服务的)实现. 因为一个客户端无法预料是否在收回某个从属关系之后这个角色成为什么, 如果它不想同时移除管理员/所有者权限和主持人角色, 那么除从属关系变更之外它还必须特意请求角色变更.
+
注意: 特定的角色一般暗含特定的权限. 例如, 一个管理员或所有者自动成为一个主持人, 所以如果一个房客被授予管理员地位那么这个房客事实上将被授予主持人权限; 类似的, 当一个房客成为一个被主持的房间的成员, 这个房客自动拥有一个与会者的角色. 无论如何, 失去管理员地位并不足以意味这个房客不再是主持人 (因为只要是与会者就可能成为一个主持人). 因此, 当一个房客被授予特定的岗位的时候所拥有的角色是固定的, 反之当一个房客失去一个特定的岗位时它的角色是不确定的并取决于(服务的)实现. 因为一个客户端无法预料是否在撤销某个岗位之后这个角色成为什么, 如果它不想同时移除管理员/所有者权限和主持人角色, 那么除了岗位变更之外它还必须特意请求角色变更.
  
===从属关系===
+
===岗位===
  
一个用户可以有五种已定义的和房间之间的从属关系:
+
已定义了以下岗位:
  
 
# 所有者
 
# 所有者
 
# 管理员
 
# 管理员
 
# 成员
 
# 成员
# 排斥者
+
# 被排斥者
# 无 (缺从属关系)
+
# 无 (缺少岗位)
  
这些从属关系是长时间的跨越一个用户对这个房间的访问期间的并且不受房间里事件的影响. 而且, 在这些从属关系和一个驻留者在房间中的角色之间没有一对一的映射关系. 从属关系被授予, 收回, 和维护都是基于这个用户的纯 JID.
+
必须支持"所有者"这个岗位,推荐支持"管理员","成员","被排斥者"的岗位.("无"表示缺少岗位)
  
如果一个没有已定义的从属关系的用户进入一个房间, 这个用户的从属关系被定义为"无"; 无论如何, 这个从属关系不能穿越(多次的)访问 (也就是说, 一个服务不会跨越访问维护一个 "无 列表").
+
这些岗位是长时间的跨越一个用户对这个房间的访问期间的并且不受房间里事件的影响. 而且, 这些岗位和一个房客在房间中的角色之间没有一对一的映射关系. 岗位被授予,撤销, 和维护都是基于这个用户的纯 JID.
  
成员从属关系为房间所有者或管理员提供了一个方法来指定一个"白名单",其中的用户被允许加入一个仅供会员的房间. 当一个成员加入了一个仅供会员的房间, 他或她的从属关系不会改变, 无论他或她的角色是什么. 成员从属关系也为用户提供一个方法来高效地注册一个开放的房间并在某种方式意义上保持和那个房间的联系(例如可能在房间里预留那个用户的昵称).
+
如果一个没有已定义的岗位的用户进入一个房间, 这个用户的岗位被定义为"无"; 无论如何, 这个岗位不能跨越(多次的)访问 (也就是说, 一个服务不会跨越访问维护一个 "无 列表").
 +
 
 +
"成员"岗位为房间所有者或管理员提供了一个方法来指定一个"白名单",其中的用户被允许加入一个仅供会员的房间. 当一个成员加入了一个仅供会员的房间, 他或她的岗位不会改变, 无论他或她的角色是什么. 成员岗位也为用户提供一个方法来高效地注册一个开放的房间并在某种方式意义上保持和那个房间的联系(例如可能在房间里预留那个用户的昵称).
  
 
一个被排斥者就是一个被从房间踢出来并且不允许进入那个房间的用户.
 
一个被排斥者就是一个被从房间踢出来并且不允许进入那个房间的用户.
  
关于从属关系的信息必须(MUST)由房间生成或反射到所有的出席信息节之中发送给驻留者们.
+
关于岗位的信息必须(MUST)由房间生成或反射到所有的出席信息节之中发送给房客们.
  
 
====权限====
 
====权限====
  
大部分情况下, 从属关系存在一个级别. 例如, 一个所有者可以做任何管理员能做的事情, 而一个管理员可以做任何成员能做的事情. 每个从属关系拥有其下一级从属关系所没有的权限; 这些权限定义在下表中.
+
大部分情况下, 岗位存在一个层次结构. 例如, 一个所有者可以做任何管理员能做的事情, 而一个管理员可以做任何成员能做的事情. 每个岗位拥有其下一级岗位所没有的权限; 这些权限定义在下表中.
  
'''表4: Privileges Associated With Affiliations'''
+
'''表5: 和岗位相关的权限'''
  
 
{|border="1" cellspacing="0"  
 
{|border="1" cellspacing="0"  
第322行: 第363行:
 
|注册一个开放的房间 ||否 ||是 ||N/A ||N/A ||N/A
 
|注册一个开放的房间 ||否 ||是 ||N/A ||N/A ||N/A
 
|-
 
|-
|加入一个仅供会员的房间 ||否 ||否 ||是* ||是 ||是
+
|接收成员列表 ||否 ||否** ||是 ||是 ||是
 +
|-
 +
|加入一个仅限会员的房间 ||否 ||否 ||是* ||是 ||是
 
|-
 
|-
|踢出成员并把用户剔除从属关系 ||否 ||否 ||否 ||是 ||是
+
|禁止成员并把用户的岗位删除 ||否 ||否 ||否 ||是 ||是
 
|-
 
|-
 
|编辑成员列表 ||否 ||否 ||否 ||是 ||是
 
|编辑成员列表 ||否 ||否 ||否 ||是 ||是
第339行: 第382行:
 
|}
 
|}
  
* 作为缺省值, 一个无从属关系的用户进入一个 moderated 房间的身份是一个访问者, 而进入一个开放的房间的身份是一个参与者. 一个成员进入一个房间的身份是参与者. 一个管理员或所有者进入房间的身份是一个主持人.
+
* 作为缺省值, 一个无岗位的用户进入一个被主持的房间的角色是一个游客, 而进入一个开放的房间的角色是一个与会者. 一个成员进入一个房间的角色是与会者. 一个管理员或所有者进入房间的角色是一个主持人.
  
 
** 一个管理员或所有者不能(MUST NOT)撤销另一个管理员或所有者的权限.
 
** 一个管理员或所有者不能(MUST NOT)撤销另一个管理员或所有者的权限.
  
====变更从属关系====
+
====变更岗位====
  
一个用户的从属关系变更方法已经定义得很完善. 有时用户自己的动作导致这些变更(例如, 注册为一个房间的新成员), 反之有时候一个管理员或所有者的动作导致了这些变更. 如果一个用户的从属关系改变了, 一个MUC服务实现必须(MUST)变更这个用户的从属关系来反射这一变更并通知所有驻留者. 从属关系变更和他们出发的动作定义在下表中.
+
一个用户的岗位变更方法已经定义得很完善. 有时用户自己的动作导致这些变更(例如, 注册为一个房间的新成员), 反之有时候一个管理员或所有者的动作导致了这些变更. 如果一个用户的岗位改变了, 一个MUC服务实现必须(MUST)变更这个用户的岗位来反射这一变更并通知所有房客. 岗位变更和他们触发的动作定义在下表中.
  
'''表 5: 从属关系状态表'''
+
'''表6: 岗位状态表'''
  
 
{|border="1" cellspacing="0"  
 
{|border="1" cellspacing="0"  
|  ||Outcast ||None ||Member ||Admin ||Owner
+
|  ||被排斥者(Outcast) ||无(None) ||成员(Member) ||管理员(Admin) ||所有者(Owner)
 
|-
 
|-
|Outcast ||-- ||管理员或所有者移除屏蔽 ||管理员或所有者增加用户到成员列表 ||所有者增加用户到管理员列表 ||所有者增加用户到所有者列表
+
|被排斥者(Outcast) ||-- ||管理员或所有者移除屏蔽 ||管理员或所有者增加用户到成员列表 ||所有者增加用户到管理员列表 ||所有者增加用户到所有者列表
 
|-
 
|-
|None ||管理员或所有者使用屏蔽 ||-- ||管理员或所有者增加用户到成员列表, 或用户注册一个成员(如果允许) ||所有者增加用户到管理员列表 ||所有者增加用户到所有者列表
+
|无(None) ||管理员或所有者使用屏蔽 ||-- ||管理员或所有者增加用户到成员列表, 或用户注册一个成员(如果允许) ||所有者增加用户到管理员列表 ||所有者增加用户到所有者列表
 
|-
 
|-
|Member ||管理员或所有这使用屏蔽 ||管理员或所有者变更从属关系为"none" ||-- ||所有者增加用户到管理员列表 ||所有者增加用户到所有者列表
+
|成员(Member) ||管理员或所有者使用屏蔽 ||管理员或所有者变更岗位为"none" ||-- ||所有者增加用户到管理员列表 ||所有者增加用户到所有者列表
 
|-
 
|-
|Admin ||所有者使用屏蔽 ||所有者变更从属关系为"none" ||所有者变更从属关系为"member" ||-- ||所有者增加用户到所有者列表
+
|管理员(Admin) ||所有者使用屏蔽 ||所有者变更岗位为"none" ||所有者变更岗位为"member" ||-- ||所有者增加用户到所有者列表
 
|-
 
|-
|Owner ||所有者使用屏蔽 ||所有者变更从属关系为"none" ||所有者变更从属关系为"member" ||所有者变更从属关系为"admin" ||--
+
|所有者(Owner) ||所有者使用屏蔽 ||所有者变更岗位为"none" ||所有者变更岗位为"member" ||所有者变更岗位为"admin" ||--
 
|}
 
|}
  
 
==实体用例==
 
==实体用例==
  
一个MUC实现必须(MUST)支持服务探索\[7\].
+
一个MUC实现必须(MUST)支持[http://xmpp.org/extensions/xep-0030.html 服务发现] [[XEP-0045#附录G:备注|7]].
  
===MUC的探索组件支持===
+
===MUC的发现组件支持===
  
一个Jabber实体可能希望探索是否一个服务实现了多用户聊天协议; 为了达到这个目的, 它发送一个服务探索信息("disco#info")查询给这组件的JID:
+
一个Jabber实体可能希望发现是否一个服务实现了多用户聊天协议; 为了达到这个目的, 它发送一个服务发现信息("disco#info")查询给这组件的JID:
  
 
'''例子 1. 用户通过Disco查询聊天服务是否支持MUC'''
 
'''例子 1. 用户通过Disco查询聊天服务是否支持MUC'''
第403行: 第446行:
 
注意: 因为MUC是旧的"groupchat 1.0"协议的超集, 一个MUC服务不应该(SHOULD NOT)返回一个<feature var='gc-1.0'/>条目在一个disco#info结果中.
 
注意: 因为MUC是旧的"groupchat 1.0"协议的超集, 一个MUC服务不应该(SHOULD NOT)返回一个<feature var='gc-1.0'/>条目在一个disco#info结果中.
  
===探索房间===
+
===发现房间===
  
服务探索条目("disco#items")协议使得一个用户可以向一个服务查询相关的条目列表, 在一个聊天服务中这包含这个服务所承载的所有特定房间的集合.
+
发现服务条目("disco#items")协议使得一个用户可以向一个服务查询相关的条目列表, 在一个聊天服务中这包含这个服务所承载的所有特定房间的集合.
  
 
'''例子 3. 用户向聊天服务查询房间'''
 
'''例子 3. 用户向聊天服务查询房间'''
第440行: 第483行:
 
</source>
 
</source>
  
如果全部房间的列表太大(详见[XMPP文档列表/XMPP扩展/XEP-0030]), 服务可以(MAY)只返回部分的房间列表.
+
如果全部房间的列表太大(详见[[XEP-0030]]), 服务可以(MAY)只返回部分的房间列表.如果这样做了, 它应该 SHOULD 包含一个 <set/> 元素 (定义在 [http://xmpp.org/extensions/xep-0059.html Result Set Management] [[XEP-0045#附录G:备注|8]]) 以表明这个列表不是全部的结果集.
 +
 
 +
'''例子 5. 服务返回Disco Item结果的部分列表'''
 +
 
 +
<source lang="xml">
 +
<iq from='rooms.shakespeare.lit'
 +
    id='disco-rsm-1'
 +
    to='hag66@shakespeare.lit/pda'
 +
    type='result'>
 +
  <query xmlns='http://jabber.org/protocol/disco#items'>
 +
    <item jid='alls-well-that-ends-well@rooms.shakespeare.lit'/>
 +
    <item jid='as-you-like-it@rooms.shakespeare.lit'/>
 +
    <item jid='cleopatra@rooms.shakespeare.lit'/>
 +
    <item jid='comedy-of-errors@rooms.shakespeare.lit'/>
 +
    <item jid='coriolanus@rooms.shakespeare.lit'/>
 +
    <item jid='cymbeline@rooms.shakespeare.lit'/>
 +
    <item jid='hamlet@rooms.shakespeare.lit'/>
 +
    <item jid='henry-the-fourth-one@rooms.shakespeare.lit'/>
 +
    <item jid='henry-the-fourth-two@rooms.shakespeare.lit'/>
 +
    <item jid='henry-the-fifth@rooms.shakespeare.lit'/>
 +
    <set xmlns='http://jabber.org/protocol/rsm'>
 +
      <first index='0'>alls-well-that-ends-well@rooms.shakespeare.lit</first>
 +
      <last>henry-the-fifth@rooms.shakespeare.lit</last>
 +
      <count>37</count>
 +
    </set>
 +
  </query>
 +
</iq>
 +
</source>
  
 
===查询房间信息===
 
===查询房间信息===
  
使用 disco#info 协议, 一个用户也可以查询一个特定房间的详情. 为了在进入房间之间确定这个房间的隐私和安全配置用户应该(SHOULD)这样做(详见 Security Considerations).
+
使用 disco#info 协议, 一个用户也可以查询一个特定房间的详情. 为了在进入房间之间确定这个房间的隐私和安全配置用户应该(SHOULD)这样做(详见[[XEP-0045#安全事项|安全事项]]).
  
'''例子 5. 用户查询特定聊天室的信息'''
+
'''例子 6. 用户查询特定聊天室的信息'''
  
 
<source lang="xml">
 
<source lang="xml">
第459行: 第529行:
 
房间必须(MUST)返回它的标识并且应该(SHOULD)返回它支持的特性:
 
房间必须(MUST)返回它的标识并且应该(SHOULD)返回它支持的特性:
  
'''例子 6. 房间返回查询信息结果'''
+
'''例子 7. 房间返回查询信息结果'''
  
 
<source lang="xml">
 
<source lang="xml">
第482行: 第552行:
 
</source>
 
</source>
  
注意: 因为 MUC 是旧的 "groupchat 1.0" 协议的超集, 一个 MUC 房间不应该(SHOULD NOT)在一个disco#info结果中返回<feature var='gc-1.0'/>条目. 房间应该(SHOULD)返回它支持的实质的有意义的特性, 例如密码保护和房间主持(这些特性被完整地列入了特性注册项, 由XMPP注册项维护; 也见于本文的XMPP Registrar 章节).
+
注意: 因为 MUC 是旧的 "groupchat 1.0" 协议的超集, 一个 MUC 房间不应该(SHOULD NOT)在一个disco#info结果中返回<feature var='gc-1.0'/>条目. 房间应该(SHOULD)返回它支持的实质的有意义的特性, 例如密码保护和房间主持(这些特性被完整地列入了特性注册, 由[http://xmpp.org/registrar/ XMPP Registrar]维护; 也见于本文的[[XEP-0045#registrar|XMPP注册]] 章节).
  
一个聊天室可以(MAY)使用服务查询扩展\[8\]在它的disco#info应答中返回更详细的信息, 通过包含一个隐含的其值为"http://jabber.org/protocol/muc#roominfo"的FORM_TYPE属性来标识. 这些信息可能包括关于一个房间的更详细的描述, 当前的房间标题, 以及这个房间当前的驻留者数量:
+
一个聊天室可以(MAY)使用[http://xmpp.org/extensions/xep-0128.html 服务查询扩展] [[XEP-0045#附录G:备注|9]]在它的disco#info应答中返回更详细的信息, 通过包含一个隐含的FORM_TYPE属性值"http://jabber.org/protocol/muc#roominfo"来标识. 这些信息可能包括关于一个房间的更详细的描述, 当前的房间标题, 以及这个房间当前的房客数量:
  
'''例子 7. 房间返回扩展的查询信息结果'''
+
'''例子 8. 房间返回扩展的查询信息结果'''
  
 
<source lang="xml">
 
<source lang="xml">
第538行: 第608行:
 
</source>
 
</source>
  
某些扩展的房间信息可能是动态生成的(例如, 讨论日志的URL地址, 它可能取决于服务器端的配置) 反之另一些信息则可能基于房间的配置.
+
某些扩展的房间信息可能是动态生成的(例如, 讨论记录的URL地址, 它可能取决于服务器那一层的配置); 反之另一些信息则可能基于房间那一层的配置,任何定义在[[XEP-0045#附录G:备注|muc#roomconfig FORM_TYPE]] 里的字段都可以用于扩展服务发现的字段(如上文所示的 muc#roomconfig_changesubject 字段).
  
注意: 前述用于'http://jabber.org/protocol/muc#roominfo'FORM_TYPE的扩展服务查询字段将来还可以扩充(通过本文的Field Standardization章节描述的机制).
+
注意: 前述 'http://jabber.org/protocol/muc#roominfo' FORM_TYPE的扩展服务发现字段将来还可以扩充(通过本文的[[XEP-0045#附录G:备注|字段标准化]]章节描述的机制).
  
 
===查询房间条目===
 
===查询房间条目===
第546行: 第616行:
 
一个用户也可以(MAY)向一个特定的聊天室查询和它相关的条目:
 
一个用户也可以(MAY)向一个特定的聊天室查询和它相关的条目:
  
'''例子 8. 用户查询和一个特定聊天室相关的条目'''
+
'''例子 9. 用户查询和一个特定聊天室相关的条目'''
  
 
<source lang="xml">
 
<source lang="xml">
第557行: 第627行:
 
</source>
 
</source>
  
一个实现可以(MAY)返回现有驻留者的列表(如果那信息是公开可用的话), 或不返回列表(如果那信息是私有的).
+
一个实现可以(MAY)返回现有房客的列表(如果那信息是可公开的), 或不返回列表(如果那信息是私有的).
  
'''例子 9. 房间返回查询条目结果(条目是公开的)'''
+
'''例子 10. 房间返回查询条目结果(条目是公开的)'''
  
 
<source lang="xml">
 
<source lang="xml">
第575行: 第645行:
 
注意: 这些 <item/> 元素由 disco#items 名字空间限定, 而不是 muc 名字空间; 这意味着他们不能拥有 'affiliation' 或 'role' 属性, 例如.
 
注意: 这些 <item/> 元素由 disco#items 名字空间限定, 而不是 muc 名字空间; 这意味着他们不能拥有 'affiliation' 或 'role' 属性, 例如.
  
'''例子 10. 房间返回空的查询条目结果(条目是私有的)'''
+
'''例子 11. 房间返回空的查询条目结果(条目是私有的)'''
  
 
<source lang="xml">
 
<source lang="xml">
第586行: 第656行:
 
</source>
 
</source>
  
===查询一个房间的驻留者===
+
===查询一个房间的房客===
  
如果一个非驻留者试图发送一个查询请求给一个<room@service/nick>类型的地址, 一个 MUC 服务应该(SHOULD)返回这个请求给这个实体并指明一个<bad-request/>错误条件. 如果一个驻留者发送这样一个请求, 服务可以(MAY)把它传递给预订的接收者; 详见本文的 实施指南章节Implementation Guidelines.
+
如果一个非房客试图发送一个查询请求给一个<room@service/nick>类型的地址, 一个 MUC 服务应该(SHOULD)返回这个请求给这个实体并指明一个<bad-request/>错误条件. 如果一个房客发送这样一个请求, 服务可以(MAY)把它传递给指定的接收者; 详见本文的 [[XEP-0045#实现注意事项|实现注意事项]]章节.
  
===查询客户端对MUC的支持===
+
===发现客户端对MUC的支持===
  
 
一个 Jabber 用户可能想发现这个用户的某个联系人是否支持多用户聊天协议. 这可以使用服务发现(协议)来完成.
 
一个 Jabber 用户可能想发现这个用户的某个联系人是否支持多用户聊天协议. 这可以使用服务发现(协议)来完成.
  
'''例子 11. 用户查询联系人对于 MUC 的支持'''
+
'''例子 12. 用户查询联系人对于 MUC 的支持'''
  
 
<source lang="xml">
 
<source lang="xml">
第607行: 第677行:
 
客户端应该(SHOULD)返回它的标识和它支持的特性:
 
客户端应该(SHOULD)返回它的标识和它支持的特性:
  
'''例子 12. 联系人返回发现信息结果'''
+
'''例子 13. 联系人返回发现信息结果'''
  
 
<source lang="xml">
 
<source lang="xml">
第625行: 第695行:
 
</source>
 
</source>
  
一个用户也可能查询一个联系人在哪个房间. 这可以通过特定服务发现节点'http://jabber.org/protocol/muc#rooms'查询联系人的全JID(<user@host/resource>)来完成 :
+
一个用户也可能查询一个联系人在哪个房间. 这可以通过特定服务发现节点 'http://jabber.org/protocol/muc#rooms' 查询联系人的全JID(<user@host/resource>)来完成 :
  
'''例子 13. 用户在当前房间查询联系人'''
+
'''例子 14. 用户在当前房间查询联系人'''
  
 
<source lang="xml">
 
<source lang="xml">
第639行: 第709行:
 
</source>
 
</source>
  
'''例子 14. 联系人返回房间查询结果'''
+
'''例子 15. 联系人返回房间查询结果'''
  
 
<source lang="xml">
 
<source lang="xml">
第654行: 第724行:
 
</source>
 
</source>
  
可选择的, 联系人可以(MAY)把它的房间昵称作为'name'属性的值返回:
+
可选的, 联系人可以(MAY)把它的房间昵称作为'name'属性的值返回:
  
 
<source lang="xml">
 
<source lang="xml">
第663行: 第733行:
 
</source>
 
</source>
  
==驻留者用例==
+
==房客用例==
  
在一个多用户聊天环境中主要的行为者是驻留者, 它可以被认为存在于一个多用户聊天室"之内"并且参与那个房间的讨论 (在本协议中, 参与者和访问者"仅仅"被认为是驻留者, 因为他们不拥有管理员权限). 为了更加清晰起见, 本文中的协议元素中涉及到驻留者的用例分为以下三类:
+
在一个多用户聊天环境中主要的行为者是房客, 它可以被认为存在于一个多用户聊天室"之内"并且参与那个房间的讨论 (在本协议中, 与会者和游客"仅仅"被认为是房客, 因为他们不拥有管理员权限). 为了更加清晰起见, 本文中的协议元素中涉及到驻留者的用例分为以下三类:
  
 
# 现存于 "groupchat 1.0" 协议的最小功能集
 
# 现存于 "groupchat 1.0" 协议的最小功能集
# 对于 "groupchat 1.0" 协议向前兼容的应用, 如处理一些和新房间类型有关的错误
+
# 对于 "groupchat 1.0" 协议直接的应用, 如处理一些和新房间类型有关的错误
# 用来处理"groupchat 1.0"协议未涉及的功能的额外的协议元素(房间邀请, 房间密码, 和房间角色及从属关系相关的扩展出席信息); 在'http://jabber.org/protocol/muc#user'名字空间
+
# 用来处理"groupchat 1.0"协议未涉及的功能的额外的协议元素(房间邀请, 房间密码, 和房间角色及岗位相关的扩展出席信息); 在'http://jabber.org/protocol/muc#user'名字空间
  
注意: 这里所有客户端生成的例子是从服务的角度来展示的, 所以所有由服务收到的节都包含一个'from'属性来表达发送者的全JID(由一个通用的Jabber路由或会话管理者加入). 另外, 通常的表示请求已被完成的 IQ 结果节(如 RFC 3920 \[9\]中所要求的)未被展示.
+
注意: 这里所有客户端生成的例子是从服务的角度来展示的, 所以所有由服务收到的节都包含一个'from'属性来表达发送者的全JID(这个from属性是由一个通用的Jabber路由或会话管理者加入的). 另外, 通常的表示请求已被完成的 IQ 结果节(如 [[RFC 3920]] [10]中所要求的)未显示在这里.
  
 
===进入一个房间===
 
===进入一个房间===
  
====群聊1.0协议====
+
====Groupchat 1.0协议====
  
为了参加一个多用户聊天室的讨论, 一个Jabber用户必须(MUST)首先进入一个房间成为一个驻留者. 在旧的"groupchat 1.0"协议中, 这是通过发送出席信息<room@service/nick>来实现的, 这里"room"是房间的 ID, "service" 是聊天服务的主机名, "nick" 是这个用户在这房间里预期的昵称:
+
为了参加一个多用户聊天室的讨论, 一个Jabber用户必须(MUST)首先进入一个房间成为一个房客. 在旧的"groupchat 1.0"协议中, 这是通过发送出席信息<room@service/nick>来实现的, 这里"room"是房间的 ID, "service" 是聊天服务的主机名, "nick" 是这个用户在这房间里预期的昵称:
  
'''例子 15. Jabber用户进入一个房间(Groupchat 1.0)'''
+
'''例子 16. Jabber用户进入一个房间(Groupchat 1.0)'''
  
 
<source lang="xml">
 
<source lang="xml">
第691行: 第761行:
 
如果用户未指定一个房间昵称, 服务应该(SHOULD)返回一个<jid-malformed/>错误:
 
如果用户未指定一个房间昵称, 服务应该(SHOULD)返回一个<jid-malformed/>错误:
  
'''例子 16. Jabber用户进入一个房间(Groupchat 1.0)'''
+
'''例子 17. Jabber用户进入一个房间(Groupchat 1.0)'''
  
 
<source lang="xml">
 
<source lang="xml">
第708行: 第778行:
 
兼容的多用户聊天服务必须(MUST)接受知道"groupchat 1.0" (GC)协议或multi-user chat (MUC)协议的任何客户端发出上述请求进入会议室; 无论如何, MUC 客户端应该(SHOULD)声明他们的有能力支持 MUC 协议, 方法是在出席信息节里面包含一个空的 <x/> 元素, 满足名字空间 'http://jabber.org/protocol/muc'  (注意不需要 '#user' 部分):
 
兼容的多用户聊天服务必须(MUST)接受知道"groupchat 1.0" (GC)协议或multi-user chat (MUC)协议的任何客户端发出上述请求进入会议室; 无论如何, MUC 客户端应该(SHOULD)声明他们的有能力支持 MUC 协议, 方法是在出席信息节里面包含一个空的 <x/> 元素, 满足名字空间 'http://jabber.org/protocol/muc'  (注意不需要 '#user' 部分):
  
'''例子 17. Jabber用户进入一个房间(Multi-User Chat)'''
+
'''例子 18. Jabber用户准备进入一个房间(Multi-User Chat)'''
  
 
<source lang="xml">
 
<source lang="xml">
第718行: 第788行:
 
</source>
 
</source>
  
在尝试进入房间之间, 一个兼容MUC的客户端应该(SHOULD)首先查询它的保留的房间昵称 (如果有的话), 接下来的协议本文中的 Discovering Reserved Room Nickname 章节对此作了定义.
+
注意: 如果发生了一个和加入房间有关的错误, 服务应该 SHOULD 返回一个包含 MUC 子元素 (i.e., <x xmlns='http://jabber.org/protocol/muc'/>) 的 <presence/> 节,其 type 为 "error".
 +
 
 +
在尝试进入房间之间, 一个兼容MUC的客户端应该(SHOULD)首先查询它的保留的房间昵称 (如果有的话), 接下来的协议本文中的 [[XEP-0045#发现保留的房间昵称|发现保留的房间昵称]] 章节对此作了定义.
  
 
====出席信息广播====
 
====出席信息广播====
  
如果服务能够添加用户到房间, 它必须(MUST)从所有现存的驻留者的房间JID发送出席信息给新的驻留者的全JID, 包括扩展的关于角色的出席信息, 一个符合 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'role'属性值设为"moderator", "participant", 或"visitor", 这个子元素的'affiliation'属性值设为"owner", "admin", "member", 或 "none" 中的一个:
+
如果服务能够添加用户到房间, 它必须(MUST)从所有现存的房客的房间JID发送出席信息给新的房客的全JID, 包括扩展的关于角色的出席信息, 一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'role'属性值设为"moderator", "participant", 或"visitor", 这个子元素的'affiliation'属性值设为"owner", "admin", "member", 或 "none" 中的一个:
  
'''例子 18. 服务从现有的驻留者发送出席信息给新的驻留者'''
+
'''例子 19. 服务从现有的房客发送出席信息给新的房客'''
  
 
<source lang="xml">
 
<source lang="xml">
第743行: 第815行:
 
</source>
 
</source>
  
这个示例中, 用户已从前一个例子进入房间, 有两个人已经进入房间: 一个是昵称为"firstwitch"的(房间拥有者), 另一个是昵称为"secondwitch"的(房间管理员).
+
这个示例中, 用户已从前一个例子进入房间, 有两个人已经在房间里: 一个是昵称为"firstwitch"的(房间拥有者), 另一个是昵称为"secondwitch"的(房间管理员).
  
服务也必须(MUST)从新进入驻留者房间JID向所有驻留者JID发送出席信息(含新驻留者):
+
服务也必须(MUST)从新进入的房客的房间JID向所有房客的全JID发送出席信息(含新房客):
  
示例:19. 服务发送新驻留者的出席信息给所有驻留者
+
'''例子 20. 服务发送新房客的出席信息给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='participant'/>
 
     <item affiliation='member' role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='participant'/>
 
     <item affiliation='member' role='participant'/>
 
 
   </x>
 
   </x>
  
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
 
     to='hag66@shakespeare.lit/pda'>
 
     to='hag66@shakespeare.lit/pda'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='participant'/>
 
     <item affiliation='member' role='participant'/>
 
 
     <status code='110'/>
 
     <status code='110'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
+
</source>
 
        
 
        
 +
在这个例子里, 初始的房间出席信息从新房客(thirdwitch)发送给所有房客, 包括这个新房客自己. 看看上面最后一个节, 由房间以房客的名义发送给用户自己的出席信息,应该 SHOULD 包含一个 110 状态码,这样用户就知道这个出席信息来自于作为房客的那个他自己.
  
 +
服务可以 MAY 重写新房客的房间昵称 (例如, 如果房间昵称被锁定). 如果服务不接受新房客请求的房间昵称,而是分配一个新的房间昵称, 它必须 MUST 包含一个 "210" 状态码在发送给这个新房客的出席信息广播里.
  
 +
'''例子 21. 服务发送新房客的出席信息给新房客'''
  
In this example, initial room presence is being sent from the new occupant (thirdwitch) to all occupants, including the new occupant. As shown in the last stanza, the presence sent by the room to a user from itself as an occupant SHOULD include a status code of 110 so that the user knows this presence refers to itself as an occupant.
+
<source lang="xml">
 
+
 
+
 
+
The service MAY rewrite the new occupant's roomnick (e.g., if roomnicks are locked down). If the service does not accept the new occupant's requested roomnick but instead assigns a new roomnick, it MUST include a status code of "210" in the presence broadcast that it sends to the new occupant.
+
 
+
 
+
 
+
Example 20. Service Sends New Occupant's Presence to New Occupant
+
 
+
 
+
 
+
 
<presence
 
<presence
 
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
 
 
     to='hag66@shakespeare.lit/pda'>
 
     to='hag66@shakespeare.lit/pda'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='participant'/>
 
     <item affiliation='member' role='participant'/>
 
 
     <status code='110'/>
 
     <status code='110'/>
 
 
     <status code='210'/>
 
     <status code='210'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
+
</source>
 
        
 
        
 +
注意: 发送给新房客的出席信息的顺序是很重要的. 服务必须 MUST 首先发送现有房客的完整列表给这个新房客,然后只发送新房客自己的出席信息给新房客. 这有助于客户端知道什么时候它收到了完整的房间名册( "room roster").
  
 +
发送出席信息广播之后(并且只在这之后), 服务可以发送讨论历史, 即时消息, 出席信息更新, 以及其他房间内的流量.
  
 +
====缺省角色====
  
Note: The order of the presence stanzas sent to the new occupant is important. The service MUST first send the complete list of the existing occupants to the new occupant and only then send the new occupant's own presence to the new occupant. This helps the client know when it has received the complete "room roster".
+
下表总结了初始缺省的角色,一个服务应该根据用户的岗位来设置它们(没有和 被排斥者 "outcast" 岗位相关的角色, 因为这些用户不允许进入房间).
  
 +
'''表7: 基于岗位的初始角色'''
  
 +
{|border="1" cellspacing="0"
 +
!房间类型 !!无 !!成员 !!管理员 !!所有者
 +
|-
 +
|被主持的 ||游客 ||与会者 ||主持人 ||主持人
 +
|-
 +
|非主持的 ||与会者 ||与会者 ||主持人 ||主持人
 +
|-
 +
|仅限会员的 ||N/A * ||与会者 ||主持人 ||主持人
 +
|-
 +
|开放的 ||与会者 ||与会者 ||主持人 ||主持人
 +
|}
  
After sending the presence broadcast (and only after doing so), the service may then send discussion history, live messages, presence updates, and other in-room traffic.
+
* 实体不被允许.
  
7.1.4 Default Roles
+
====非匿名房间====
 
+
 
+
 
+
The following table summarizes the initial default roles that a service should set based on the user's affiliation (there is no role associated with the "outcast" affiliation, since such users are not allowed to enter the room).
+
 
+
 
+
 
+
Table 6: Initial Role Based on Affiliation
+
 
+
Room Type None Member Admin Owner
+
 
+
Moderated Visitor Participant Moderator Moderator
+
 
+
Unmoderated Participant Participant Moderator Moderator
+
 
+
Members-Only N/A * Participant Moderator Moderator
+
 
+
Open Participant Participant Moderator Moderator
+
 
+
 
+
 
+
* Entry is not permitted.
+
 
+
7.1.5 Non-Anonymous Rooms
+
 
+
 
+
 
+
If the room is non-anonymous, the service MUST send the new occupant's full JID to all occupants using extended presence information in an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with a 'jid' attribute specifying the occupant's full JID:
+
 
+
 
+
 
+
Example 21. Service Sends Full JID to All Occupants
+
  
 +
如果房间是非匿名的, 服务必须 MUST 发送新房客的全JID给所有房客,使用满足 'http://jabber.org/protocol/muc#user' 名字空间的扩展出席信息,其中带有 <x/> 元素并包含一个 <item/> 子元素,其 'jid' 属性值为这个房客的全JID:
  
 +
'''例子 22. 服务发送全JID给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 
+
.
+
 
+
.
+
 
+
 
        
 
        
 +
</source>
  
 +
如果这个用户正在进入一个非匿名房间(即, 它如上所示,向所有房客通报每个房客的全JID), 服务应该 SHOULD 允许该用户加入本房间,但是必须 MUST 同时警告该用户本房间是非匿名的. 应该 SHOULD 在房间发送给这个新房客的初始出席信息种包含状态码 "100" 来实现这一点:
  
 +
'''例子 23. 服务发送新房客的出席信息给新房客'''
  
If the user is entering a room that is non-anonymous (i.e., which informs all occupants of each occupant's full JID as shown above), the service SHOULD allow the user to enter the room but MUST also warn the user that the room is not anonymous. This SHOULD be done by including a status code of "100" in the initial presence that the room sends to the new occupant:
+
<source lang="xml">
 
+
 
+
 
+
Example 22. Service Sends New Occupant's Presence to New Occupant
+
 
+
 
+
 
+
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hag66@shakespeare.lit/pda'>
 
     to='hag66@shakespeare.lit/pda'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='participant'/>
 
     <item affiliation='member' role='participant'/>
 
 
     <status code='100'/>
 
     <status code='100'/>
 
 
     <status code='110'/>
 
     <status code='110'/>
 
 
     <status code='210'/>
 
     <status code='210'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
无论如何, 也可以 MAY 发送一个 "groupchat" 类型的消息给新房客来达到上述目的,这个消息应该包含一个 <x/> 子元素,并拥有 <status/> 子元素,并且其'code'属性值为"100":
 
+
 
+
 
+
However, it MAY be done by sending a message of type "groupchat" to the new occupant containing an <x/> child with a <status/> element that has the 'code' attribute set to a value of "100":
+
 
+
 
+
 
+
Example 23. Service Warns New Occupant About Lack of Anonymity
+
 
+
  
 +
'''例子 24. 服务警告新房客(该房间)非匿名'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>This room is not anonymous.</body>
 
   <body>This room is not anonymous.</body>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <status code='100'/>
 
     <status code='100'/>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
     
+
附带的状态码协助客户端展示它们自己的通知消息 (例如, 和用户所在地方有关的信息).
  
 +
====半匿名房间====
  
 +
如果房间是半匿名的, 服务必须 MUST 如上文所述从新房客发送出席信息给所有房客, 但是必须 MUST 只在发给"主持人"的时候发送新房客的全JID,而非主持人则不发(全JID).
  
The inclusion of the status code assists clients in presenting their own notification messages (e.g., information appropriate to the user's locality).
+
(注意: 所有随后的例子中,涉及的<item/>元素都带有'jid'属性, 即使这个信息在半匿名房间里不被发送给非主持人.)
  
7.1.6 Semi-Anonymous Rooms
+
====密码保护房间====
 
+
 
+
 
+
If the room is semi-anonymous, the service MUST send the new occupant's full JID in the format shown above only to those occupants with a role of "moderator".
+
 
+
 
+
 
+
(Note: All subsequent examples include the 'jid' attribute for each <item/> element, even though this information is not sent to non-moderators in semi-anonymous rooms.)
+
 
+
7.1.7 Password-Protected Rooms
+
 
+
 
+
 
+
If the room requires a password and the user did not supply one (or the password provided is incorrect), the service MUST deny access to the room and inform the user that they are unauthorized; this is done by returning a presence stanza of type "error" specifying a <not-authorized/> error:
+
 
+
 
+
 
+
Example 24. Service Denies Access Because No Password Provided
+
  
 +
如果房间要求密码验证而用户不能提供(或密码错误), 服务必须 MUST 拒绝访问这个房间并且通知该用户它们是未被授权的; 具体方法是返回一个类型为"error"的出席信息节并标明 <not-authorized/> 错误:
  
 +
'''例子 25. 服务拒绝访问,因为(用户)未提供密码'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='401' type='auth'>
+
  <error type='auth'>
 
+
 
     <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
密码应该 SHOULD 通过进入房间时发送的出席信息节来提供, 包含在满足 'http://jabber.org/protocol/muc' 名字空间的 <x/> 元素的<password/> 子元素里. 密码以明码方式发送; 目前不支持其它验证方法, 而且任何这类的验证或授权方法都将会定义在一个独立的协议里(参见本文的[[XEP-0045#安全事项|安全事项]]章节).
 
+
 
+
 
+
Passwords SHOULD be supplied with the presence stanza sent when entering the room, contained within an <x/> element qualified by the 'http://jabber.org/protocol/muc' namespace and containing a <password/> child. Passwords are to be sent as cleartext; no other authentication methods are supported at this time, and any such authentication or authorization methods shall be defined in a separate specification (see the Security Considerations section of this document).
+
 
+
 
+
 
+
Example 25. User Provides Password On Entering a Room
+
 
+
  
 +
'''例子 26. 用户进入房间时提供密码'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
+
     to='darkcave@chat.shakespeare.lit/thirdwitch'>
     to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
 
     <password>cauldronburn</password>
 
     <password>cauldronburn</password>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
====仅限会员房间====
 
+
 
+
 
+
7.1.8 Members-Only Rooms
+
 
+
 
+
 
+
If the room is members-only but the user is not on the member list, the service MUST deny access to the room and inform the user that they are not allowed to enter the room; this is done by returning a presence stanza of type "error" specifying a <registration-required/> error condition:
+
 
+
 
+
 
+
Example 26. Service Denies Access Because User Is Not on Member List
+
  
 +
如果房间是仅限会员的,但用户不是(该房间的)成员, 服务必须 MUST 拒绝访问这个房间并通知用户它们不被允许进入房间; 具体方法是返回一个"error"类型的出席信息节,并包含一个 <registration-required/> 错误条件:
  
 +
'''例子 27. 服务拒绝访问,因为用户不在成员列表中'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='407' type='auth'>
+
  <error type='auth'>
 
+
 
     <registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
====被禁止的用户====
 
+
 
+
 
+
7.1.9 Banned Users
+
 
+
 
+
 
+
If the user has been banned from the room (i.e., has an affiliation of "outcast"), the service MUST deny access to the room and inform the user of the fact that he or she is banned; this is done by returning a presence stanza of type "error" specifying a <forbidden/> error condition:
+
 
+
 
+
 
+
Example 27. Service Denies Access Because User is Banned
+
  
 +
如果用户已经被房间禁止(即, 其岗位为被排斥者 "outcast"), 服务必须 MUST 拒绝访问这个房间并通知用户他(她)被禁止了; 具体方法是返回一个出席信息节,类型为"error",标明 <forbidden/> 错误条件:
  
 +
'''例子 28. 服务拒绝访问,因为用户被禁止了'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='403' type='auth'>
+
  <error type='auth'>
 
+
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
====昵称冲突====
 
+
 
+
 
+
7.1.10 Nickname Conflict
+
 
+
 
+
 
+
If the room already contains another user with the nickname desired by the user seeking to enter the room (or if the nickname is reserved by another user on the member list), the service MUST deny access to the room and inform the user of the conflict; this is done by returning a presence stanza of type "error" specifying a <conflict/> error condition:
+
 
+
 
+
 
+
Example 28. Service Denies Access Because of Nick Conflict
+
  
 +
如果房间里已经有别的用户使用了准备进入房间的新用户预期的昵称(或如果这个昵称被保留给另一个成员列表里面的用户), 服务必须 MUST 拒绝访问这个房间并通知用户这个冲突; 具体方法是返回一个出席信息节,类型为"error",标明 <conflict/> 错误条件:
  
 +
'''例子 29. 服务拒绝访问,因为昵称冲突'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='409' type='cancel'>
+
  <error type='cancel'>
 
+
 
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
无论如何, 如果现有房客的纯 JID <localpart@domain.tld> 和准备进入房间的用户的纯 JID 相同, 那么服务应该 SHOULD 允许这个用户的进入, 所以这个用户就有两个(或更多) 房间内的会话 "sessions" 使用同一个房间昵称, 每一个对应一个资源. 如果一个服务允许相同纯JID可以同时存在多个房客并使用同一个房间的房间昵称, 它应该 SHOULD 路由房间内的消息给该用户的所有资源并允许用户的所有资源发送消息给房间; 视实现而定,服务来决定如何适当的处理从用户的资源发送的出席信息以及如何路由私有消息到所有或某个资源(基于出席信息优先级或其他机制).
  
 +
如何确定昵称冲突取决于实现(例如, 该服务是否应用于一个特定的惯例, 一个 stringprep 规则如 Resourceprep 或 Nodeprep, 等等).
  
 +
====最大用户数====
  
However, if the bare JID (<node@domain.tld>) of the present occupant matches the bare JID of the user seeking to enter the room, then the service SHOULD allow entry to the user, so that the user has two (or more) in-room "sessions" with the same roomnick, one for each resource. If a service allows more than one occupant with the same bare JID and the same room nickname, it SHOULD route in-room messages to all of the user's resources and allow all of the user's resources to send messages to the room; it is up to the implementation to determine how to appropriately handle presence from the user's resources and how to route private messages to all or only one resource (based on presence priority or some other algorithm).
+
如果房间达到它的最大房客数量, 服务应该 SHOULD 拒绝访问这个房间并通知该用户这个限制; 方法是返回一个出席信息节,类型为"error",标明 <service-unavailable/> 错误条件:
 
+
7.1.11 Max Users
+
 
+
 
+
 
+
If the room has reached its maximum number of users, the service SHOULD deny access to the room and inform the user of the restriction; this is done by returning a presence stanza of type "error" specifying a <service-unavailable/> error condition:
+
 
+
 
+
 
+
Example 29. Service Informs User that Room Occupant Limit Has Been Reached
+
 
+
  
 +
'''例子 30. 服务通知用户该房间已达到房客数量极限'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='503' type='wait'>
+
  <error type='wait'>
 
+
 
     <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
另外, 房间可以踢出空闲用户("idle user")以腾出空间.
  
 +
如果房间的房客数量已达到最大值但是一个房间管理员或所有者试图进入,该房间应该允许管理员或所有者加入,为了使得额外的房客达到一个合理的数目,该数量可以 MAY 做成可配置的。
  
 +
====锁住的房间====
  
Alternatively, the room could kick an "idle user" in order to free up space. Also, a room MUST always allow entry by a room admin or owner.
+
如果一个用户尝试进入一个房间而该房间是锁住的 "locked" (, 在房间创建者提供初始的配置之前以及也就是在房间正式存在之前), 服务必须 MUST 拒绝进入并返回一个 <item-not-found/> 错误给该用户:
 
+
7.1.12 Locked Room
+
 
+
 
+
 
+
If a user attempts to enter a room while it is "locked" (i.e., before the room creator provides an initial configuration and therefore before the room officially exists), the service MUST refuse entry and return an <item-not-found/> error to the user:
+
 
+
 
+
 
+
Example 30. Service Denies Access Because Room Does Not Exist
+
 
+
  
 +
'''例子 31. 服务拒绝访问,因为房间不存在'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='404' type='cancel'>
+
  <error type='cancel'>
 
+
 
     <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
====不存在的房间====
  
 +
如果用户准备进入房间时,该房间已经不存在了, 服务应该 SHOULD 建立它; 无论如何, 这不是必需的, 因为一个实现或部署可以 MAY 选择限制建立房间的权限. 详见本文的[[XEP-0045#新建房间|新建房间]]章节.
  
 +
====房间记录====
  
7.1.13 Nonexistent Room
+
如果用户进入一个房间,该房间的讨论是被记录到一个公开的存档里面(经常可以通过HTTP访问的), 服务应该 SHOULD 允许该用户加入该房间但是必须 MUST 同时警告该用户讨论已被记录. 方法是应该 SHOULD 在房间发送给该新房客的初始出席信息中包含一个状态码 "170":
 
+
 
+
 
+
If the room does not already exist when the user seeks to enter it, the service SHOULD create it; however, this is not required, since an implementation or deployment MAY choose to restrict the privilege of creating rooms. For details, see the Creating a Room section of this document.
+
 
+
7.1.14 Room Logging
+
 
+
 
+
 
+
If the user is entering a room in which the discussions are logged to a public archive (often accessible via HTTP), the service SHOULD allow the user to enter the room but MUST also warn the user that the discussions are logged. This SHOULD be done by including a status code of "170" in the initial presence that the room sends to the new occupant:
+
 
+
 
+
 
+
Example 31. Service Sends New Occupant's Presence to New Occupant
+
 
+
  
 +
'''例子 32. 服务发送新房客的出席信息给新房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hag66@shakespeare.lit/pda'>
 
     to='hag66@shakespeare.lit/pda'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='participant'/>
 
     <item affiliation='member' role='participant'/>
 
 
     <status code='100'/>
 
     <status code='100'/>
 
 
     <status code='110'/>
 
     <status code='110'/>
 
 
     <status code='170'/>
 
     <status code='170'/>
 
 
     <status code='210'/>
 
     <status code='210'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
====讨论历史====
 
+
 
+
 
+
7.1.15 Discussion History
+
 
+
 
+
 
+
After sending initial presence as shown above, a room MAY send discussion history to the new occupant. (The room MUST NOT send any discussion history before it finishes sending room presence as specified in the Presence Broadcast section of this document.) Whether such history is sent, and how many messages comprise the history, shall be determined by the chat service implementation or specific deployment.
+
 
+
 
+
 
+
Example 32. Delivery of Discussion History
+
  
 +
如上发送完初始出席信息之后, 一个房间可以 MAY 发送讨论历史给这个新房客. (在完成按照本文[[XEP-0045#出席信息广播|出席信息广播]]章节规定的发送房间出席信息之前,该房间不能 MUST NOT 发送任何讨论历史.) 是否这个历史要被发送, 以及这个历史里面包含多少条消息, 将由聊天服务实现或特定的部署来决定.
  
 +
'''例子 33. 讨论历史的发送'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/firstwitch'
     from='darkcave@macbeth.shakespeare.lit/firstwitch'
+
 
+
 
     to='hecate@shakespeare.lit/broom'
 
     to='hecate@shakespeare.lit/broom'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
 
   <delay xmlns='urn:xmpp:delay'
 
   <delay xmlns='urn:xmpp:delay'
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
 
     stamp='2002-10-13T23:58:37Z'/>
 
     stamp='2002-10-13T23:58:37Z'/>
 
 
</message>
 
</message>
 
 
  
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='hecate@shakespeare.lit/broom'
 
     to='hecate@shakespeare.lit/broom'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>Thrice and once the hedge-pig whined.</body>
 
   <body>Thrice and once the hedge-pig whined.</body>
 
 
   <delay xmlns='urn:xmpp:delay'
 
   <delay xmlns='urn:xmpp:delay'
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
 
     stamp='2002-10-13T23:58:43Z'/>
 
     stamp='2002-10-13T23:58:43Z'/>
 
 
</message>
 
</message>
 
 
  
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hecate@shakespeare.lit/broom'
 
     to='hecate@shakespeare.lit/broom'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>Harpier cries 'Tis time, 'tis time.</body>
 
   <body>Harpier cries 'Tis time, 'tis time.</body>
 
 
   <delay xmlns='urn:xmpp:delay'
 
   <delay xmlns='urn:xmpp:delay'
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
 
     stamp='2002-10-13T23:58:49Z'/>
 
     stamp='2002-10-13T23:58:49Z'/>
 
 
</message>
 
</message>
 +
</source>
  
     
+
讨论历史消息必须 MUST 标为[http://xmpp.org/extensions/xep-0203.html Delayed Delivery] [[XEP-0045#附录G:备注|11]]信息,满足'urn:xmpp:delay' 名字空间,以表明它们是被延迟发送的并且标明它们最初发出的时间. (注意: 'urn:xmpp:delay' 名字空间定义在 XEP-0203 里面,取代了旧的定义在 [http://xmpp.org/extensions/xep-0091.html Legacy Delayed Delivery] [[XEP-0045#附录G:备注|12]] 里的 'jabber:x:delay' 名字空间 ; XEP-0091状态更改为已过时之前, 实现应该 SHOULD 包含两种日期时间(datetime)格式.). 在非匿名房间里,'from'属性应该 SHOULD 是原始发送者的全JID, 但不能 MUST NOT 在半匿名房间里(在那里'from'属性应该 SHOULD 设置为房间本身的JID). 服务应该 SHOULD 在进入该房间之后,发送任何即时("live")消息之前,发送完所有讨论历史消息.
  
 +
====管理讨论历史====
  
 +
用户可能 MAY 希望管理进入房间时(由房间)提供的讨论历史(可能因为用户带宽比较低或正在使用迷你客户端). 他必须 MUST 在加入房间时发出的初始出席信息节里包含一个 <history/> 子元素. 这个元素有四个可用的属性:
  
Discussion history messages MUST be stamped with Delayed Delivery [10] information qualified by the 'urn:xmpp:delay' namespace to indicate that they are sent with delayed delivery and to specify the times at which they were originally sent. (Note: The 'urn:xmpp:delay' namespace defined in XEP-0203 supersedes the older 'jabber:x:delay' namespace defined in Delayed Delivery [11]; until the status of XEP-0091 is changed to Obsolete, implementations SHOULD include both datetime formats.) The 'from' attribute SHOULD be the full JID of the original sender in non-anonymous rooms, but MUST NOT be in semi-anonymous rooms (where the 'from' attribute SHOULD be set to the JID of the room itself). The service SHOULD send all discussion history messages before delivering any "live" messages sent after the user enters the room.
+
'''表8: 历史管理属性'''
 +
{|border="1" cellspacing="0"
 +
!属性 !!数据类型 !!含义
 +
|-
 +
| maxchars  ||int    ||限制历史中的字符总数为"X" (这里的字符数量是全部 XML 节的字符数, 不只是它们的 XML 字符数据).
 +
|-
 +
| maxstanzas    ||int    ||限制历史中的消息总数为"X".
 +
|-
 +
| seconds  ||int  ||仅发送最后 "X" 秒收到的消息.
 +
|-
 +
| since    ||dateTime    ||仅发送从指定日期时间 datetime 之后收到的消息 (这个datatime必须 MUST 符合[http://xmpp.org/extensions/xep-0082.html XMPP Date and Time Profiles] [[XEP-0045#附录G:备注|13]] 定义的DateTime 规则,).
 +
|}
  
7.1.16 Managing Discussion History
+
服务必须 MUST 发送满足以上条件组合的最小数量的消息, 还要顾及服务级别和房间级别的缺省设置. 服务必须 MUST 只发送完整的消息节(, 它不能 MUST not 按特定字符数把历史从字面上截断, 但是必须 MUST 发送最大数量的完整节,这使得字符数小于或等于 'maxchars' 属性的值). 如果客户端不希望收到历史, 它必须 MUST 'maxchars' 属性值设为"0" (zero).
 
+
 
+
 
+
A user MAY want to manage the amount of discussion history provided on entering a room (perhaps because the user is on a low-bandwidth connection or is using a small-footprint client). This MUST be accomplished by including a <history/> child in the initial presence stanza sent when joining the room. There are four allowable attributes for this element:
+
 
+
 
+
 
+
Table 7: History Management Attributes
+
 
+
Attribute Datatype Meaning
+
 
+
maxchars int Limit the total number of characters in the history to "X" (where the character count is the characters of the complete XML stanzas, not only their XML character data).
+
 
+
maxstanzas int Limit the total number of messages in the history to "X".
+
 
+
seconds int Send only the messages received in the last "X" seconds.
+
 
+
since dateTime Send only the messages received since the datetime specified (which MUST conform to the DateTime profile specified in XMPP Date and Time Profiles [12]).
+
 
+
 
+
 
+
The service MUST send the smallest amount of traffic that meets any combination of the above criteria, taking into account service-level and room-level defaults. The service MUST send complete message stanzas only (i.e., it MUST not literally truncate the history at a certain number of characters, but MUST send the largest number of complete stanzas that results in a number of characters less than or equal to the 'maxchars' value specified). If the client wishes to receive no history, it MUST set the 'maxchars' attribute to a value of "0" (zero).
+
 
+
 
+
 
+
The following examples illustrate the use of this protocol.
+
 
+
 
+
 
+
Example 33. User Requests Limit on Number of Messages in History
+
  
 +
以下例子展示如何使用这个协议.
  
 +
'''例子 34. 用户请求在历史中限制消息数量'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
+
     to='darkcave@chat.shakespeare.lit/thirdwitch'>
     to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
 
     <history maxstanzas='20'/>
 
     <history maxstanzas='20'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
'''例子 35. 用户请求最后三分钟的历史'''
 
+
 
+
 
+
Example 34. User Requests History in Last 3 Minutes
+
 
+
 
+
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
+
     to='darkcave@chat.shakespeare.lit/thirdwitch'>
     to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
 
     <history seconds='180'/>
 
     <history seconds='180'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
'''例子 36. 用户请求从Unix时代到现在的所有历史'''
 
+
 
+
 
+
Example 35. User Requests All History Since the Beginning of the Unix Era
+
 
+
 
+
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
+
     to='darkcave@chat.shakespeare.lit/thirdwitch'>
     to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
+
     <history since='1970-01-01T00:00:00Z'/>
     <history since='1970-01-01T00:00Z'/>
+
 
+
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
服务绝对不应该 SHOULD NOT 返回从Unix时代开始到现在的所有消息, 而应该 SHOULD 基于服务或房间的缺省值返回适当的有限数量的历史给用户.
 
+
 
+
 
+
Obviously the service SHOULD NOT return all messages sent in the room since the beginning of the Unix era, and SHOULD appropriately limit the amount of history sent to the user based on service or room defaults.
+
 
+
 
+
 
+
Example 36. User Requests No History
+
 
+
  
 +
'''例子 37. 用户请求不发送历史'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
+
     to='darkcave@chat.shakespeare.lit/thirdwitch'>
     to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
 
     <history maxchars='0'/>
 
     <history maxchars='0'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
===退出一个房间===
 
+
 
+
 
+
7.2 Exiting a Room
+
 
+
 
+
 
+
In order to exit a multi-user chat room, an occupant sends a presence stanza of type "unavailable" to the <room@service/nick> it is currently using in the room.
+
 
+
 
+
 
+
Example 37. Occupant Exits a Room
+
  
 +
为了退出一个多用户聊天房间, 一个房客发送一个类型为"unavailable"的出席信息节给正在使用这个房间的 <room@service/nick> .
  
 +
'''例子 38. 房客退出一个房间'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
+
     to='darkcave@chat.shakespeare.lit/thirdwitch'
     to='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     type='unavailable'/>
 
     type='unavailable'/>
 +
</source>
  
   
+
服务必须 MUST 接着从要离开的房客的房间JID发送"unavailable"类型的出席信息节给这个要离开的房客的全JID们以及留在房间的房客们:
 
+
 
+
 
+
The service MUST then send presence stanzas of type "unavailable" from the departing occupant's room JID to the full JIDs of the departing occupant and of the remaining occupants:
+
 
+
 
+
 
+
Example 38. Service Sends Presence Related to Departure of Occupant
+
 
+
  
 +
'''例子 39. 服务发送和离开的房客有关的出席信息'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='none'/>
 
     <item affiliation='member' role='none'/>
 
 
     <status code='110'/>
 
     <status code='110'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='none'/>
 
     <item affiliation='member' role='none'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='none'/>
 
     <item affiliation='member' role='none'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
由房间反射的类型为"unavailable"的出席信息节必须 MUST 包含扩展的关于角色和岗位的出席信息; 'role'属性值应该 SHOULD 被设为 "none" 以表示这个人不再是一个房客了.
 
+
 
+
 
+
Presence stanzas of type "unavailable" reflected by the room MUST contain extended presence information about roles and affiliations; the 'role' attribute SHOULD be set to a value of "none" to denote that the individual is no longer an occupant.
+
 
+
 
+
 
+
The occupant MAY include normal <status/> information in the unavailable presence stanzas; this enables the occupant to provide a custom exit message if desired:
+
 
+
 
+
 
+
Example 39. Custom Exit Message
+
  
 +
房客可以 MAY 在出席信息节包含一个常规的 <status/> 信息; 这使房客能在必要的情况下提供一个自定的退出消息:
  
 +
'''例子 40. 自定的退出消息'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     to='darkcave@chat.shakespeare.lit/oldhag'
     to='darkcave@macbeth.shakespeare.lit/oldhag'
+
 
+
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <status>gone where the goblins go</status>
 
   <status>gone where the goblins go</status>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
常规的出席信息节生成规则定义在 [[RFC3921|XMPP IM]] [[XEP-0045#附录G;备注|14]], 所以如果用户发送一个一般的不可用出席信息节, 用户的服务器将广播那个节到 <room@service/nick> ,而该用户之前曾经发送过直接出席信息给这个<room@service/nick>.
  
 +
有可能一个用户不能正常地通过直接发送不可用信息给一个房间来退出该房间. 如果该用户没有发送不可用出席信息就下线了, 用户的服务器负责代替该用户发送不可用出席信息 (依据 RFC 3921). 如果该用户的服务器下线或该用户的服务器和该用户连接的MUC服务失去连接(例如, 在联邦通信), 这个MUC服务负责监视它收到的错误信息节以确定该用户是否下线. 如果该MUC服务确定该用户已下线, 它必须 must 当成该用户自己发送了不可用信息一样地处理这个用户.
  
 +
注意: 如果房间不是持久的并且该房客是最后一个退出的, 服务负责销毁这个房间.
  
Normal presence stanza generation rules apply as defined in XMPP IM [13], so that if the user sends a general unavailable presence stanza, the user's server will broadcast that stanza to the <room@service/nick> to which the user's client has sent directed presence.
+
===更改昵称===
 
+
 
+
 
+
It is possible that a user may not be able to gracefully exit the room by sending unavailable presence directly to the room. If the user goes offline without sending unavailable presence, the user's server is responsible for sending unavailable presence on behalf of the user (in accordance with RFC 3921). If the user's server goes offline or connectivity is lost between the user's server and the MUC service to which the user is connected (e.g., in federated communications), the MUC service is responsible for monitoring error stanzas it receives in order to determine if the user has gone offline. If the MUC service determines that the user has gone offline, it must treat the user as if the user had itself sent unavailable presence.
+
 
+
 
+
 
+
Note: If the room is not persistent and this occupant is the last to exit, the service is responsible for destroying the room.
+
 
+
7.3 Changing Nickname
+
 
+
 
+
 
+
A common feature of multi-user chat rooms is the ability for an occupant to change his or her nickname within the room. In MUC this is done by sending updated presence information to the room, specifically by sending presence to a new room JID in the same room (changing only the resource identifier in the room JID).
+
 
+
 
+
 
+
Example 40. Occupant Changes Nickname
+
  
 +
多用户聊天室的一个常用功能是一个房客能修改自己在房间里的昵称. 在 MUC 里这需要发送一个更新出席信息给房间, 具体来说是在相同的房间里发送出席信息给一个新的房间JID (变更的只是这个房间JID的资源).
  
 +
'''例子 41. 房客修改昵称'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 +
    to='darkcave@chat.shakespeare.lit/oldhag'/>
 +
</source>
  
    to='darkcave@macbeth.shakespeare.lit/oldhag'/>
+
服务接着发送两个出席信息节给每个房客的全JID(包括修改自己昵称的房客本身), 一个是类型为"unavailable"的用于旧的昵称另一个指明新昵称可用了.
  
   
+
这个不可用出席信息必须 MUST 在一个满足'http://jabber.org/protocol/muc#user' 名字空间的 <x/> 子元素里面包含以下扩展的出席信息 :
  
 +
* 新昵称(在这个例子中, nick='oldhag')
 +
* 一个状态码 303
  
 +
这使接受者能从旧昵称关联到新昵称.
  
The service then sends two presence stanzas to the full JID of each occupant (including the occupant who is changing his or her room nickname), one of type "unavailable" for the old nickname and one indicating availability for the new nickname.
+
'''例子 42. 服务更新昵称'''
 
+
 
+
 
+
The unavailable presence MUST contain the following as extended presence information in an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace:
+
 
+
 
+
 
+
    * The new nickname (in this case, nick='oldhag')
+
 
+
    * A status code of 303
+
 
+
 
+
 
+
This enables the recipients to correlate the old roomnick with the new roomnick.
+
 
+
 
+
 
+
Example 41. Service Updates Nick
+
 
+
 
+
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           nick='oldhag'
 
           nick='oldhag'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
     <status code='303'/>
 
     <status code='303'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           nick='oldhag'
 
           nick='oldhag'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
     <status code='303'/>
 
     <status code='303'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           nick='oldhag'
 
           nick='oldhag'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
     <status code='303'/>
 
     <status code='303'/>
 
 
     <status code='110'/>
 
     <status code='110'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/oldhag'
     from='darkcave@macbeth.shakespeare.lit/oldhag'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/oldhag'
     from='darkcave@macbeth.shakespeare.lit/oldhag'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/oldhag'
     from='darkcave@macbeth.shakespeare.lit/oldhag'
+
 
+
 
     to='hag66@shakespeare.lit/pda'>
 
     to='hag66@shakespeare.lit/pda'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
     <status code='110'/>
 
     <status code='110'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
如果该用户尝试修改他或她的房间昵称,但这个昵称已经被其他用户使用了 (或者这个昵称是被这房间的其他用户岗位保留的, 例如, 一个成员或者所有者), 服务必须 MUST 拒绝这次昵称修改并通知该用户这一冲突; 也就是返回一个类型为 "error" 的出席信息节指明 <conflict/> 错误条件:
 
+
 
+
 
+
If the user attempts to change his or her room nickname to a room nickname that is already in use by another user (or that is reserved by another user affiliated with the room, e.g., a member or owner), the service MUST deny the nickname change request and inform the user of the conflict; this is done by returning a presence stanza of type "error" specifying a <conflict/> error condition:
+
 
+
 
+
 
+
Example 42. Service Denies Nickname Change Because of Nick Conflict
+
 
+
  
 +
'''例子 43. 服务拒绝昵称修改,因为昵称冲突'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='409' type='cancel'>
+
  <error type='cancel'>
 
+
 
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
无论如何, 如果现有房客的纯JID <localpart@domain.tld> 和尝试变更昵称的房客的纯JID相同, 那么服务可以 MAY 允许昵称变更. 详见本文的[[XEP-0045#昵称冲突|昵称冲突]]章节.
 
+
 
+
 
+
However, if the bare JID (<node@domain.tld>) of the present occupant matches the bare JID of the user seeking to change his or her nickname, then the service MAY allow the nickname change. See the Nickname Conflict section of this document for details.
+
 
+
 
+
 
+
If the user attempts to change his or her room nickname but room nicknames are "locked down", the service MUST deny the nickname change request and return a presence stanza of type "error" specifying a <not-acceptable/> error condition:
+
 
+
 
+
 
+
Example 43. Service Denies Nickname Change Because Roomnicks Are Locked Down
+
  
 +
如果该用户尝试变更自己的昵称但是房间昵称被锁定了("locked down"), 服务必须 MUST 拒绝这个昵称变更请求并返回一个"error"类型的出席信息节,指明一个 <not-acceptable/> 错误条件:
  
 +
'''例子 44. 服务拒绝昵称变更,因为房间昵称被锁定'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='406' type='cancel'>
+
  <error type='cancel'>
 
+
 
     <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
用户应该 SHOULD 接着发现它的保留昵称,如本文的 [[XEP-0045#发现保留的房间昵称|发现保留的房间昵称]]章节所述.
 
+
 
+
 
+
The user SHOULD then discover its reserved nickname as specified in the Discovering Reserved Room Nickname section of this document.
+
 
+
7.4 Changing Availability Status
+
 
+
 
+
 
+
In multi-user chat systems such as IRC, one common use for changing one's room nickname is to indicate a change in one's availability (e.g., changing one's room nickname to "thirdwitch|away"). In Jabber, availability is of course noted by a change in presence (specifically the <show/> and <status/> elements), which can provide important context within a chatroom. An occupant changes availability status within the room by sending the updated presence to its <room@service/nick>.
+
 
+
 
+
 
+
Example 44. Occupant Changes Availability Status
+
 
+
  
 +
===更改可用性状态===
  
 +
在一个多用户聊天系统里例如IRC, 一个常用的修改某人房间昵称的行为也意味着变更某人的可用性(例如, 变更某人的房间昵称为"thirdwitch|away"). 在Jabber里面, 可用性当然是通过出席信息 (中 <show/> 和 <status/> 元素)的变更来通知的, 这能提供重要的上下文给聊天室. 一个房客通过发送更新的出席信息给它自己的<room@service/nick>来改变他在房间内的可用性状态.
  
 +
'''例子 45. 房客变更可用性状态'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     to='darkcave@chat.shakespeare.lit/oldhag'>
     to='darkcave@macbeth.shakespeare.lit/oldhag'>
+
 
+
 
   <show>xa</show>
 
   <show>xa</show>
 
 
   <status>gone where the goblins go</status>
 
   <status>gone where the goblins go</status>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
服务然后从该房客发送一个出席信息节来修改他或她的出席信息给每个房客的全JID, 包含扩展的出席信息,包括这个房客的角色和全JID(给那些有权知道的人):
 
+
 
+
 
+
The service then sends a presence stanza from the occupant changing his or her presence to the full JID of each occupant, including extended presence information about the occupant's role and full JID to those with privileges to view such information:
+
 
+
 
+
 
+
Example 45. Service Passes Along Changed Presence to All Occupants
+
 
+
  
 +
'''例子 46. 服务传递修改的出席信息给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <show>xa</show>
 
   <show>xa</show>
 
 
   <status>gone where the goblins go</status>
 
   <status>gone where the goblins go</status>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
===邀请其他用户进入一个房间===
 +
====直接邀请====
  
.
+
一个办法是发送一个直接的邀请(而不是由房间本身来间接邀请),定义在[http://xmpp.org/extensions/xep-0249.html Direct MUC Invitations] [[XEP-0045#附录G:备注|15]]. 直接发送邀请有助于适应被邀请者那一边的通信阻塞(对方可能拒绝和和不在好友名单中的实体通信).
  
   
+
====间接邀请====
 
+
 
+
 
+
7.5 Inviting Another User to a Room
+
 
+
 
+
 
+
It can be useful to invite another user to a room in which one is an occupant. To do this, a MUC client MUST send XML of the following form to the <room@service> itself (the reason is OPTIONAL and the message MUST be explicitly or implicitly of type "normal"):
+
 
+
 
+
 
+
Example 46. Occupant Sends an Invitation by Way of Room
+
  
 +
邀请别的用户到一个房间成为房客是很有用的. 为了做到这一点, 一个 MUC 客户端必须 MUST 发送以下格式的 XML 给 <room@service> 本身 (原因(reason)是可选的 OPTIONAL 而消息(message)的类型必须 MUST 是显式或隐式的"normal"类型):
  
 +
'''例子 47. 房客通过房间发送一个邀请'''
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     to='darkcave@chat.shakespeare.lit'>
     to='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite to='hecate@shakespeare.lit'>
 
     <invite to='hecate@shakespeare.lit'>
 
 
       <reason>
 
       <reason>
 
 
         Hey Hecate, this is the place for all good witches!
 
         Hey Hecate, this is the place for all good witches!
 
 
       </reason>
 
       </reason>
 
 
     </invite>
 
     </invite>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
<room@service> 本身必须 MUST 接着增加一个 'from' 地址到 <invite/> 元素,其值为邀请者的纯JID, 全JID, 或房间JID,并发送邀请给 'to' 地址所指明的被邀请者(为了旧的客户端,服务可以 MAY 包含一个消息主体"message body"解释这个邀请或包含一个原因"reason"(子元素); 另外, 房间应该 SHOULD 增加 password 如果该房间是密码保护的):
 
+
 
+
 
+
The <room@service> itself MUST then add a 'from' address to the <invite/> element whose value is the bare JID (or, optionally, the room JID) of the invitor and send the invitation to the invitee captured in the 'to' address (the service SHOULD include a message body explaining the invitation or containing the reason, for the sake of older clients; in addition, the room SHOULD add the password if the room is password-protected):
+
 
+
 
+
 
+
Example 47. Room Sends Invitation to Invitee on Behalf of Invitor
+
 
+
  
 +
'''例子 48. 房间代表邀请者发送邀请给被邀请者'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hecate@shakespeare.lit'>
 
     to='hecate@shakespeare.lit'>
 
  <body>You have been invited to darkcave@macbeth by crone1@shakespeare.lit.</body>
 
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
+
     <invite from='crone1@shakespeare.lit/desktop'>
     <invite from='crone1@shakespeare.lit'>
+
 
+
 
       <reason>
 
       <reason>
 
 
         Hey Hecate, this is the place for all good witches!
 
         Hey Hecate, this is the place for all good witches!
 
 
       </reason>
 
       </reason>
 
 
     </invite>
 
     </invite>
 
 
     <password>cauldronburn</password>
 
     <password>cauldronburn</password>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果房间是仅限成员的, 服务可以 MAY 同时把这个被邀请者加入成员列表. (注意: 在仅限成员的房间里邀请的权力应该 SHOULD 由房间管理员限定; 如果一个没有权限的成员修改成员列表试图邀请别的用户, 服务应该 SHOULD 返回一个 <forbidden/> 错误给该房客; 详见本文的[[XEP-0045#修改成员列表|修改成员列表]]章节.)
  
 +
如果邀请者提供了一个不存在的JID, 房间应该 SHOULD 返回一个 <item-not-found/> 错误给邀请者.
  
 +
被邀请者可以 MAY 选择正式地拒绝 (反之则忽略) 邀请; 这是发送者希望看到的正式的通知. 为了拒绝这个邀请, 被邀请者必须 MUST 发送以下格式的消息给 <room@service> 本身:
  
If the room is members-only, the service MAY also add the invitee to the member list. (Note: Invitation privileges in members-only rooms SHOULD be restricted to room admins; if a member without privileges to edit the member list attempts to invite another user, the service SHOULD return a <forbidden/> error to the occupant; for details, see the Modifying the Member List section of this document.)
+
'''例子 49. 被邀请者谢绝邀请'''
 
+
 
+
 
+
If the invitor supplies a non-existent JID, the room SHOULD return an <item-not-found/> error to the invitor.
+
 
+
 
+
 
+
The invitee MAY choose to formally decline (as opposed to ignore) the invitation; and this is something that the sender may want to be informed about. In order to decline the invitation, the invitee MUST send a message of the following form to the <room@service> itself:
+
 
+
 
+
 
+
Example 48. Invitee Declines Invitation
+
 
+
 
+
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='hecate@shakespeare.lit/broom'
 
     from='hecate@shakespeare.lit/broom'
 
+
     to='darkcave@chat.shakespeare.lit'>
     to='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <decline to='crone1@shakespeare.lit'>
 
     <decline to='crone1@shakespeare.lit'>
 
 
       <reason>
 
       <reason>
 
 
         Sorry, I'm too busy right now.
 
         Sorry, I'm too busy right now.
 
 
       </reason>
 
       </reason>
 
 
     </decline>
 
     </decline>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
'''例子 50. 房间通知邀请者邀请被拒绝了'''
 
+
 
+
 
+
Example 49. Room Informs Invitor that Invitation Was Declined
+
 
+
 
+
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <decline from='hecate@shakespeare.lit'>
 
     <decline from='hecate@shakespeare.lit'>
 
 
       <reason>
 
       <reason>
 
 
         Sorry, I'm too busy right now.
 
         Sorry, I'm too busy right now.
 
 
       </reason>
 
       </reason>
 
 
     </decline>
 
     </decline>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
可能(有人)想知道为什么被邀请者不直接发送拒绝消息给访问者. 主要原因是特定的实现可能 MAY 选择让邀请基于房间JIDs而不是纯JIDs (所以, 例如, 一个房客可能从一个房间邀请某人到另一个房间而不需要知道这个人的纯JID). 因而服务必须 MUST 同时处理邀请和拒绝.
  
 +
===把一对一聊天转为多用户会议===
  
 +
有时候人们需要把一个一对一的聊天转成一个多用户的会议. 以下例子展示了这个流程.
  
It may be wondered why the invitee does not send the decline message directly to the invitor. The main reason is that certain implementations MAY choose to base invitations on room JIDs rather than bare JIDs (so that, for example, an occupant could invite someone from one room to another without knowing that person's bare JID). Thus the service MUST handle both the invites and declines.
+
首先, 两个用户开始一个一对一聊天.
 
+
7.6 Converting a One-to-One Chat Into a Conference
+
 
+
 
+
 
+
Sometimes it is desirable to convert a one-to-one chat into a multi-user conference. The process flow is shown in the following examples.
+
 
+
 
+
 
+
First, two users begin a one-to-one chat.
+
 
+
 
+
 
+
Example 50. A One-to-One Chat
+
 
+
  
 +
'''例子 51. 一个一对一聊天'''
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='chat'>
 
     type='chat'>
 
+
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
 
</message>
 
</message>
 
 
  
 
<message
 
<message
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='chat'>
 
     type='chat'>
 
+
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
 
   <body>Thrice and once the hedge-pig whined.</body>
 
   <body>Thrice and once the hedge-pig whined.</body>
 
 
</message>
 
</message>
 +
</source>
  
   
+
现在第一个用户决定加入第三个人到这个讨论, 所以她 (或, 更准确地说, 她的客户端) 做以下事情:
  
 +
# 新建一个多用户聊天室
 +
# 可选地发送一对一聊天的历史到房间
 +
# 发送一个邀请给第二个人和第三个人, 包含一个 <continue/> 元素 (可选地包含一个 'thread' 属性).
  
 +
注意: 新房间应该 SHOULD 是非匿名的, 可以 MAY 是一个即时房间(定义于本文的[[XEP-0045#新建即时房间|新建即时房间]]章节), 也可以 MAY 有一个从服务接收的唯一房间名(定义于本文的[[XEP-0045#请求唯一的房间名|请求唯一的房间名]]章节.
  
Now the first person decides to include a third person in the discussion, so she (or, more precisely, her client) does the following:
+
注意: 如果这个一对一的聊天消息包含了一个 <thread/> 元素, 这个新建房间的人应该 SHOULD 在历史消息中包含这个 ThreadID, 在邀请中把这个 ThreadID 的值赋予 <continue/> 元素的 'thread' 属性, 并把这 ThreadID 包含在任何新的消息中发送到房间. ThreadIDs 的使用是推荐的 RECOMMENDED ,因为它帮助提供一对一聊天和多用户聊天的连续性.
 
+
 
+
 
+
  1. Creates a new room
+
 
+
  2. Optionally sends history of the one-to-one chat to the room
+
 
+
  3. Sends an invitation to the second person and the third person, including a <continue/> flag.
+
 
+
 
+
 
+
Note: The new room SHOULD be non-anonymous, MAY be an instant room as specified in the Creating an Instant Room section of this document, and MAY have a unique room name received from the service as specified in the Requesting a Unique Room Name section of this document.
+
 
+
 
+
 
+
Example 51. Continuing the Discussion I: User Creates Room
+
 
+
  
 +
'''例子 52. 继续讨论 I: 用户新建房间'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     to='darkcave@chat.shakespeare.lit/firstwitch'>
     to='darkcave@macbeth.shakespeare.lit/firstwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/firstwitch'
     from='darkcave@macbeth.shakespeare.lit/firstwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='owner' role='moderator'/>
 
     <item affiliation='owner' role='moderator'/>
 
+
    <status code='110'/>
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
'''例子 53. 继续讨论 II: 所有者发送历史到房间'''
 
+
 
+
 
+
Example 52. Continuing the Discussion II: Owner Sends History to Room
+
 
+
 
+
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='groupchat'>
 
     type='groupchat'>
 
+
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
 
   <delay xmlns='urn:xmpp:delay'
 
   <delay xmlns='urn:xmpp:delay'
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     stamp='2004-09-29T01:54:37Z'/>
     stamp='20040929T01:54:37Z'/>
+
 
+
 
</message>
 
</message>
 
 
  
 
<message
 
<message
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='groupchat'>
 
     type='groupchat'>
 
+
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
 
   <body>Thrice and once the hedge-pig whined.</body>
 
   <body>Thrice and once the hedge-pig whined.</body>
 
 
   <delay xmlns='urn:xmpp:delay'
 
   <delay xmlns='urn:xmpp:delay'
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     stamp='2004-09-29T01:55:21Z'/>
     stamp='20040929T01:55:21Z'/>
+
 
+
 
</message>
 
</message>
 +
</source>
  
   
+
注意: 使用 Delayed Delivery 协议使房间创建者能够从他一对一聊天历史指明每个消息的日期时间 datetime (通过 'stamp' 属性), 以及每个消息的原始发送者的 JID (通过'from' 属性). 房间创建者应该 SHOULD 在邀请额外的用户到房间之前发送完整的一对一聊天历史, 并且也应该 SHOULD 把第二个人加入该房间之前和第一个人在一对一聊天界面中出现的任何消息当成历史来发送; 如果这个一对一历史特别的大, 发送的客户端可能希望在数秒内发送这个历史而不是一次性发送所有历史(以to 避免触发频率限制). 服务不应该 SHOULD NOT 在从房间所有者接收的历史消息之前添加它自己的延迟元素"delay elements" (见本文的[[XEP-0045#讨论历史|讨论历史]]章节) .
 
+
 
+
 
+
Note: Use of the Delayed Delivery protocol enables the room creator to specify the datetime of each message from the one-to-one chat history (via the 'stamp' attribute), as well as the JID of the original sender of each message (via the 'from' attribute). The room creator SHOULD send the complete one-to-one chat history before inviting additional users to the room, and SHOULD also send as history any messages appearing in the one-to-one chat interface after joining the room and before the second person joins the room; if the one-to-one history is especially large, the sending client may want to send the history over a few seconds rather than all at once (to avoid triggering rate limits). The service SHOULD NOT add its own delay elements (as described in the Discussion History section of this document) to prior chat history messages received from the room owner.
+
 
+
 
+
 
+
Example 53. Continuing the Discussion III: Owner Sends Invitations, Including Continue Flag
+
 
+
  
 +
'''例子 54. 继续讨论 III: 所有者发送邀请(们), 包含 Continue 标志'''
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     to='darkcave@chat.shakespeare.lit'>
     to='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite to='wiccarocks@shakespeare.lit/laptop'>
 
     <invite to='wiccarocks@shakespeare.lit/laptop'>
 
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
+
       <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
       <continue/>
+
 
+
 
     </invite>
 
     </invite>
 
 
     <invite to='hag66@shakespeare.lit'>
 
     <invite to='hag66@shakespeare.lit'>
 
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
+
       <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
       <continue/>
+
 
+
 
     </invite>
 
     </invite>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
注意: 当邀请者的客户端一知道和它一对一聊天的那个人的全JID之后, 它就应该 SHOULD 在邀请中包含这个全JID (而不是纯JID).
 
+
 
+
 
+
Note: Since the invitor's client knows the full JID of the person with whom the invitor was having a one-to-one chat, it SHOULD include the full JID (rather than the bare JID) in the invitation.
+
 
+
 
+
 
+
The invitations are delivered to the invitees:
+
 
+
 
+
 
+
Example 54. Invitations Delivered
+
  
 +
邀请被递送到被邀请者:
  
 +
'''例子 55. 邀请被递送'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'>
     from='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite from='crone1@shakespeare.lit'>
 
     <invite from='crone1@shakespeare.lit'>
 
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
+
       <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
       <continue/>
+
 
+
 
     </invite>
 
     </invite>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 
 
  
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'>
     from='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
     to='hag66@shakespeare.lit'>
 
     to='hag66@shakespeare.lit'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite from='crone1@shakespeare.lit'>
 
     <invite from='crone1@shakespeare.lit'>
 
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
       <reason>This coven needs both wiccarocks and hag66.</reason>
 
+
       <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
       <continue/>
+
 
+
 
     </invite>
 
     </invite>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
当客户端被 <wiccarocks@shakespeare.lit/laptop> 用来接收邀请, 它应该 SHOULD 自动加入或提示用户是否加入 (取决于用户的选项配置) 并且随后无缝地把现有的一对一聊天窗口转到一个多用户会议的窗口:
 
+
 
+
 
+
When the client being used by <wiccarocks@shakespeare.lit/laptop> receives the invitation, it SHOULD auto-join the room or prompt the user whether to join (subject to user preferences) and then seamlessly convert the existing one-to-one chat window into a multi-user conferencing window:
+
 
+
 
+
 
+
Example 55. Invitee Accepts Invitation, Joins Room, and Receives Presence and History
+
 
+
  
 +
'''例子 56. 被邀请者接受邀请, 加入房间, 并接收出席信息和历史'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     to='darkcave@chat.shakespeare.lit/secondwitch'>
     to='darkcave@macbeth.shakespeare.lit/secondwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/firstwitch'
     from='darkcave@macbeth.shakespeare.lit/firstwitch'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='owner' role='moderator'/>
 
     <item affiliation='owner' role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
     to='wiccarocks@shakespeare.lit/laptop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member' role='participant'/>
 
     <item affiliation='member' role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
  
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
+
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
   <body>Thrice the brinded cat hath mew'd.</body>
 
 
   <delay xmlns='urn:xmpp:delay'
 
   <delay xmlns='urn:xmpp:delay'
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     stamp='2004-09-29T01:54:37Z'/>
     stamp='20040929T01:54:37Z'/>
+
 
+
 
</message>
 
</message>
 
 
  
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
+
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
 
   <body>Thrice and once the hedge-pig whined.</body>
 
   <body>Thrice and once the hedge-pig whined.</body>
 
 
   <delay xmlns='urn:xmpp:delay'
 
   <delay xmlns='urn:xmpp:delay'
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     stamp='2004-09-29T01:55:21Z'/>
     stamp='20040929T01:55:21Z'/>
+
 
+
 
</message>
 
</message>
 +
</source>
  
   
+
注意: 事实上,这些消息从 <room@service> 本身而不是 <room@service/nick> 发出,告诉这些接收的客户端这些消息是优先的聊天历史, 因为任何来自房客的消息的 'from' 地址应该等于发送者的房间JID.
  
 +
===房客修改房间标题===
  
 +
如果房间配置允许, 一个房客可以 MAY 被允许修改一个房间的主题. 详见本文的[[XEP-0045#修改房间主题|修改房间主题]]章节.
  
Note: The fact that the messages come from the <room@service> itself rather than <room@service/nick> is a clue to the receiving client that these messages are prior chat history, since any message from a room occupant will have a 'from' address equal to the sender's room JID.
+
===发送私有消息===
 
+
7.7 Occupant Modification of the Room Subject
+
 
+
 
+
 
+
If allowed in accordance with room configuration, a mere occupant MAY be allowed to change the subject in a room. For details, see the Modifying the Room Subject section of this document.
+
 
+
7.8 Sending a Private Message
+
 
+
 
+
 
+
Since each occupant has a unique room JID, an occupant MAY send a "private message" to a selected occupant via the service by sending a message to the occupant's room JID. The message type SHOULD be "chat" and MUST NOT be "groupchat", but MAY be left unspecified (i.e., a normal message). This privilege SHOULD be allowed to any occupant (even a visitor in a moderated room).
+
 
+
 
+
 
+
Example 56. Occupant Sends Private Message
+
  
 +
因为每个房客有一个唯一的房间JID, 一个房客可以 MAY 发送一个私有消息 "private message" 给选定的房客,即通过服务发送一个消息给那房客的房间JID. 这个消息类型应该 SHOULD 是 "chat" 并且不能 MUST NOT 是 "groupchat", 但是可以 MAY 不表明 (即, 一个常规"normal"消息). 这个权力应该 SHOULD 被任何房客允许 (甚至在一个被主持的房间里的游客).
  
 +
'''例子 57. 房客发送私有消息'''
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     to='darkcave@chat.shakespeare.lit/firstwitch'
     to='darkcave@macbeth.shakespeare.lit/firstwitch'
+
 
+
 
     type='chat'>
 
     type='chat'>
 
 
   <body>I'll give thee a wind.</body>
 
   <body>I'll give thee a wind.</body>
 
 
</message>
 
</message>
 +
</source>
  
   
+
服务负责把'from'地址改为发送者的房间JID并递送这个消息到预期的接收者的全JID.
 
+
 
+
 
+
The service is responsible for changing the 'from' address to the sender's room JID and delivering the message to the intended recipient's full JID.
+
 
+
 
+
 
+
Example 57. Recipient Receives the Private Message
+
 
+
  
 +
'''例子 58. 接收者接收私有消息'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='chat'>
 
     type='chat'>
 
 
   <body>I'll give thee a wind.</body>
 
   <body>I'll give thee a wind.</body>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果发送者尝试发送一个类型为 "groupchat" 的私有消息给特定的房客, 服务必须 MUST 拒绝递送这个消息 (因为接收者的客户端期望的房间内的消息类型为"groupchat") 并且返回一个 <bad-request/> 错误给发送者:
 
+
 
+
 
+
If the sender attempts to send a private message of type "groupchat" to a particular occupant, the service MUST refuse to deliver the message (since the recipient's client would expect in-room messages to be of type "groupchat") and return a <bad-request/> error to the sender:
+
 
+
 
+
 
+
Example 58. Occupant Attempts to Send a Message of Type "Groupchat" to a Particular Occupant
+
 
+
  
 +
'''例子 59. 房客尝试发送类型为"Groupchat"的私有消息给特定的房客'''
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     to='darkcave@chat.shakespeare.lit/firstwitch'
     to='darkcave@macbeth.shakespeare.lit/firstwitch'
+
 
+
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>I'll give thee a wind.</body>
 
   <body>I'll give thee a wind.</body>
 
 
</message>
 
</message>
 
 
  
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='error'>
 
     type='error'>
 
 
   <body>I'll give thee a wind.</body>
 
   <body>I'll give thee a wind.</body>
 
+
   <error type='modify'>
   <error code='400' type='modify'>
+
 
+
 
     <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果发送者尝试发送一个私有消息给一个不存在的房间JID, 服务必须 MUST 返回一个 <item-not-found/> 错误给发送者.
  
 +
如果发送者不是预期的接收者正在访问的那个房间的房客, 服务必须 MUST 返回一个 <not-acceptable/> 错误给发送者.
  
 +
===发送消息给所有房客===
  
If the sender attempts to send a private message to a room JID that does not exist, the service MUST return an <item-not-found/> error to the sender.
+
房客发送一个消息给所有房间内的房客的方法,是发送一个类型为 "groupchat" 的消息到 <room@service> 本身 (服务可以 MAY 忽略或拒绝类型不是 "groupchat" 的消息). 在一个被主持的房间, 这个权力限于角色为与会者或更高的房客拥有.
 
+
 
+
 
+
If the sender is not an occupant of the room in which the intended recipient is visiting, the service MUST return a <not-acceptable/> error to the sender.
+
 
+
7.9 Sending a Message to All Occupants
+
 
+
 
+
 
+
An occupant sends a message to all other occupants in the room by sending a message of type "groupchat" to the <room@service> itself (a service MAY ignore or reject messages that do not have a type of "groupchat"). In a moderated room, this privilege is restricted to occupants with a role of participant or higher.
+
 
+
 
+
 
+
Example 59. Occupant Sends a Message to All Occupants
+
 
+
  
 +
'''例子 60. 房客发送一个消息给所有房客'''
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='hag66@shakespeare.lit/pda'
 
     from='hag66@shakespeare.lit/pda'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果发送者在这个房间有发言权 (在被主持的房间里缺省是这样期望), 服务必须 MUST 修改发送者的 'from' 属性成为房间JID并反射这个消息到每个房客的全JID.
 
+
 
+
 
+
If the sender has voice in the room (this is the default except in moderated rooms), the service MUST change the 'from' attribute to the sender's room JID and reflect the message out to the full JID of each occupant.
+
 
+
 
+
 
+
Example 60. Service Reflects Message to All Occupants
+
 
+
  
 +
'''例子 61. 服务反射消息给所有房客'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
 
</message>
 
</message>
 
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
 
</message>
 
</message>
 
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
   <body>Harpier cries: 'tis time, 'tis time.</body>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果发送者是个游客 即, 在一个被主持的房间里没有发言权), 服务可以 MAY 返回一个 <forbidden/> 错误给发送者并且不能 MUST NOT 反射这个消息给所有房客. 如果发送者不是该房间的房客, 服务应该 SHOULD 返回一个 <not-acceptable/> 错误给发送者并且不应该 SHOULD NOT 反射这个消息给所有房客; 这个规则的唯一的例外是,一个实现可以 MAY 允许用户们拥有特定的权限 (例如, 一个房间拥有者, 房间管理员, 或服务级别的管理员) 发送消息到这个房间,即使那些用户不是房客.
  
 +
===注册到房间===
  
 +
一个实现可以 MAY 允许一个无岗位的用户(在一个被主持的房间里, 通常是一个与会者) 注册一个房间从而成为该房间的一个成员 (反之, 一个实现也可以 MAY 限制这个权力并且只允许房间管理员添加新的成员). 特别是, 不在成员列表的人是无法加入一个仅限会员的房间的, 所以为了加入这样一个房间,实体需要申请会籍.
  
If the sender is a visitor (i.e., does not have voice in a moderated room), the service MAY return a <forbidden/> error to the sender and MUST NOT reflect the message to all occupants. If the sender is not an occupant of the room, the service SHOULD return a <not-acceptable/> error to the sender and SHOULD NOT reflect the message to all occupants; the only exception to this rule is that an implementation MAY allow users with certain privileges (e.g., a room owner, room admin, or service-level admin) to send messages to the room even if those users are not occupants.
+
如果允许, 这个功能应该 SHOULD 这样被实现。让用户使用 'jabber:iq:register' 名字空间[[XEP-0077|带内注册]] [[XEP-0045#附录G:备注|16]]提出注册申请给房间,:
 
+
7.10 Registering with a Room
+
 
+
 
+
 
+
An implementation MAY allow an unaffiliated user (in a moderated room, normally a participant) to register with a room and thus become a member of the room (conversely, an implementation MAY restrict this privilege and allow only room admins to add new members). In particular, it is not possible to join a members-only room without being on the member list, so an entity may need to request membership in order to join such a room.
+
 
+
 
+
 
+
If allowed, this functionality SHOULD be implemented by enabling a user to send a request for registration requirements to the room qualified by the 'jabber:iq:register' namespace as described in In-Band Registration [14]:
+
 
+
 
+
 
+
Example 61. User Requests Registration Requirements
+
 
+
  
 +
'''例子 62. 用户提出注册申请'''
  
 +
<source lang="xml">
 
<iq from='hag66@shakespeare.lit/pda'
 
<iq from='hag66@shakespeare.lit/pda'
 
 
     id='reg1'
 
     id='reg1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='jabber:iq:register'/>
 
   <query xmlns='jabber:iq:register'/>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果用户提出的注册申请不被允许注册该房间 (例如, 因为那个权限被限制了), 该房间必须 MUST 返回一个 <not-allowed/> 错误给该用户. 如果该用户已经注册过了, 房间必须 MUST 返回一个类型为"result"的IQ节并包含一个空的<register/>元素(定义于'''XEP-0077'''). 如果该房间不存在, 服务必须 MUST 返回一个 <item-not-found/> 错误.
  
 +
否则, 房间必须 MUST 接着返回一个数据表单"Data Form"给该用户 (定义于[[XEP-0004|数据表单]] [[XEP-0045#附录G:备注|17]]). 注册需要的信息可以 MAY 根据实现和部署的不同而不同并且没有完全定义在本文中 (例如, 本文根据 'http://jabber.org/protocol/muc#register' 名字空间采用的注册字段  FORM_TYPE 可能将来会根据[[XEP-0045#字段标准化|字段标准化]]章节里描述的得到补充,). 以下是一个典型的例子:
  
 +
'''例子 63. 服务返回注册表单'''
  
If the user requesting registration requirements is not allowed to register with the room (e.g., because that privilege has been restricted), the room MUST return a <not-allowed/> error to the user. If the user is already registered, the room MUST reply with an IQ stanza of type "result" that contains an empty <register/> element as described in XEP-0077. If the room does not exist, the service MUST return an <item-not-found/> error.
+
<source lang="xml">
 
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
Otherwise, the room MUST then return a Data Form to the user (as described in Data Forms [15]). The information required to register MAY vary by implementation or deployment and is not fully specified in this document (e.g., the fields registered by this document for the 'http://jabber.org/protocol/muc#register' FORM_TYPE may be supplemented in the future via the mechanisms described in the Field Standardization section of this document). The following can be taken as a fairly typical example:
+
 
+
 
+
 
+
Example 62. Service Returns Registration Form
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='reg1'
 
     id='reg1'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='jabber:iq:register'>
 
   <query xmlns='jabber:iq:register'>
 
 
     <instructions>
 
     <instructions>
 
 
       To register on the web, visit http://shakespeare.lit/
 
       To register on the web, visit http://shakespeare.lit/
 
 
     </instructions>
 
     </instructions>
 
 
     <x xmlns='jabber:x:data' type='form'>
 
     <x xmlns='jabber:x:data' type='form'>
 
 
       <title>Dark Cave Registration</title>
 
       <title>Dark Cave Registration</title>
 
 
       <instructions>
 
       <instructions>
 
 
         Please provide the following information
 
         Please provide the following information
 
 
         to register with this room.
 
         to register with this room.
 
 
       </instructions>
 
       </instructions>
 
 
       <field
 
       <field
 
 
           type='hidden'
 
           type='hidden'
 
 
           var='FORM_TYPE'>
 
           var='FORM_TYPE'>
 
 
         <value>http://jabber.org/protocol/muc#register</value>
 
         <value>http://jabber.org/protocol/muc#register</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
+
           label='Given Name'
           label='First Name'
+
 
+
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#register_first'>
 
           var='muc#register_first'>
 
 
         <required/>
 
         <required/>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
+
           label='Family Name'
           label='Last Name'
+
 
+
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#register_last'>
 
           var='muc#register_last'>
 
 
         <required/>
 
         <required/>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Desired Nickname'
 
           label='Desired Nickname'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#register_roomnick'>
 
           var='muc#register_roomnick'>
 
 
         <required/>
 
         <required/>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Your URL'
 
           label='Your URL'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#register_url'/>
 
           var='muc#register_url'/>
 
 
       <field
 
       <field
 
 
           label='Email Address'
 
           label='Email Address'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#register_email'/>
 
           var='muc#register_email'/>
 
 
       <field
 
       <field
 
 
           label='FAQ Entry'
 
           label='FAQ Entry'
 
 
           type='text-multi'
 
           type='text-multi'
 
 
           var='muc#register_faqentry'/>
 
           var='muc#register_faqentry'/>
 
 
     </x>
 
     </x>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
用户应该 SHOULD 接着提交这个表单:
 
+
 
+
 
+
The user SHOULD then submit the form:
+
 
+
 
+
 
+
Example 63. User Submits Registration Form
+
 
+
  
 +
'''例子 64. 用户提交注册表单'''
  
 +
<source lang="xml">
 
<iq from='hag66@shakespeare.lit/pda'
 
<iq from='hag66@shakespeare.lit/pda'
 
 
     id='reg2'
 
     id='reg2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='jabber:iq:register'>
 
   <query xmlns='jabber:iq:register'>
 
 
     <x xmlns='jabber:x:data' type='submit'>
 
     <x xmlns='jabber:x:data' type='submit'>
 
 
       <field var='FORM_TYPE'>
 
       <field var='FORM_TYPE'>
 
 
         <value>http://jabber.org/protocol/muc#register</value>
 
         <value>http://jabber.org/protocol/muc#register</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#register_first'>
 
       <field var='muc#register_first'>
 
 
         <value>Brunhilde</value>
 
         <value>Brunhilde</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#register_last'>
 
       <field var='muc#register_last'>
 
 
         <value>Entwhistle-Throckmorton</value>
 
         <value>Entwhistle-Throckmorton</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#register_roomnick'>
 
       <field var='muc#register_roomnick'>
 
 
         <value>thirdwitch</value>
 
         <value>thirdwitch</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#register_url'>
 
       <field var='muc#register_url'>
 
 
         <value>http://witchesonline/~hag66/</value>
 
         <value>http://witchesonline/~hag66/</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#register_email'>
 
       <field var='muc#register_email'>
 
 
         <value>hag66@witchesonline</value>
 
         <value>hag66@witchesonline</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#register_faqentry'>
 
       <field var='muc#register_faqentry'>
 
 
         <value>Just another witch.</value>
 
         <value>Just another witch.</value>
 
 
       </field>
 
       </field>
 
 
     </x>
 
     </x>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果期望的房间昵称已经被那个房间保留, 房间必须 MUST 返回一个 <conflict/> 错误给该用户:
  
 +
'''例子 65. 房间返回冲突错误给用户'''
  
 
+
<source lang="xml">
If the desired room nickname is already reserved for that room, the room MUST return a <conflict/> error to the user:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 64. Room Returns Conflict Error to User
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='reg2'
 
     id='reg2'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <error type='cancel'>
   <error code='409' type='cancel'>
+
 
+
 
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果该房间或服务不支持注册, 它必须 MUST 返回一个 <service-unavailable/> 错误给用户:
  
 +
'''例子 66. 房间返回服务不可用错误给用户'''
  
 
+
<source lang="xml">
If the room or service does not support registration, it MUST return a <service-unavailable/> error to the user:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 65. Room Returns Service Unavailable Error to User
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='reg2'
 
     id='reg2'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <error type='cancel'>
   <error code='503' type='cancel'>
+
 
+
 
     <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果用户没有提交合法的数据表格, 房间必须 MUST 返回一个 <bad-request/> 错误给用户:
  
 +
'''例子 67. 房间返回"服务错误的请求"错误给用户'''
  
 
+
<source lang="xml">
If the user did not include a valid data form, the room MUST return a <bad-request/> error to the user:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 66. Room Returns Service Bad Request Error to User
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='reg2'
 
     id='reg2'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <error type='modify'>
   <error code='400' type='modify'>
+
 
+
 
     <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
否则, 该房间必须 MUST 通知用户注册请求被成功地接收到了:
  
 +
'''例子 68. 房间通知用户注册请求已经被处理了'''
  
 
+
<source lang="xml">
Otherwise, the room MUST inform the user that the registration request was successfully received:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 67. Room Informs User that Registration Request Has Been Processed
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='reg2'
 
     id='reg2'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
用户提交表单之后, 服务可以 MAY 向一个房间 管理员/所有者 请求批准该申请 (参见本文的[[XEP-0045#批准注册申请|批准注册申请]]章节) 或也可以 MAY 立刻把该用户的岗位从"none"变更为"member"来添加此用户到成员列表. 如果服务变更了该用户的岗位并且该用户在房间里, 它必须 MUST 从这个用户发送更新的出席信息给所有房客, 声明岗位的变更,这个更新的出席信息应包含一个满足 'http://jabber.org/protocol/muc#user' 名字空间 <x/> 元素并包含一个'affiliation' 属性值设为"member"的 <item/> 子元素.
 
+
 
+
 
+
After the user submits the form, the service MAY request that the submission be approved by a room admin/owner (see the Approving Registration Requests section of this document) or MAY immediately add the user to the member list by changing the user's affiliation from "none" to "member". If the service changes the user's affiliation and the user is in the room, it MUST send updated presence from this individual to all occupants, indicating the change in affiliation by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "member".
+
 
+
 
+
 
+
Example 68. Service Sends Notice of Membership to All Occupants
+
 
+
  
 +
'''例子 69. 服务发送成员变更通知给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果一个用户已经注册到一个房间, 该房间可以 MAY 选择限制这个用户在那个房间仅能使用已注册的昵称. 如果它这样做, 当用户尝试以不同于该用户之前已注册的房间昵称来加入该房间 (这使房间锁定"lock down"房间昵称以保证房客身份的一致性)的时候,它应该 SHOULD 返回一个 <not-acceptable/> 错误给该用户.
  
.
+
===获取成员列表===
  
   
+
根据房间配置如果允许的话, 一个房客可以 MAY 被允许接收房间成员的列表. 详见本文的[[XEP-0045#修改成员列表|修改成员列表]]章节.
  
 +
===发现保留的房间昵称===
  
 +
一个用户可以 MAY 有一个保留的房间昵称, 例如通过显式的房间注册, 数据库集成, 或昵称锁定 "lockdown". 用户应该 SHOULD 在尝试进入该房间之前发现自己的保留昵称. 这可以通过发送一个发现服务信息请求并指定一个服务发现节点"x-roomuser-item"给房间JID来做到.
  
If a user has registered with a room, the room MAY choose to restrict the user to use of the registered nickname only in that room. If it does so, it SHOULD return a <not-acceptable/> error to the user if the user attempts to join the room with a roomnick other than the user's registered roomnick (this enables a room to "lock down" roomnicks for consistent identification of occupants).
+
'''例子 70. 用户请求保留的昵称'''
 
+
7.11 Discovering Reserved Room Nickname
+
 
+
 
+
 
+
A user MAY have a reserved room nickname, for example through explicit room registration, database integration, or nickname "lockdown". A user SHOULD discover his or her reserved nickname before attempting to enter the room. This is done by sending a Service Discovery information request to the room JID while specifying a well-known Service Discovery node of "x-roomuser-item".
+
 
+
 
+
 
+
Example 69. User Requests Reserved Nickname
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='hag66@shakespeare.lit/pda'
 
<iq from='hag66@shakespeare.lit/pda'
 
 
     id='getnick1'
 
     id='getnick1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
 
         node='x-roomuser-item'/>
 
         node='x-roomuser-item'/>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
对一个多用户聊天服务来说,对上述的服务发现节点的支持是可选的 OPTIONAL . 如果房间或服务不支持上述的服务发现节点, 它必须 MUST 返回一个 <feature-not-implemented/> 错误给用户. 如果它支持这个特性并且该用户有一个已注册的昵称, 它必须 MUST 返回这个昵称给这个用户,方法是发送一个服务发现的<identity/>元素,其'name'属性值为这个昵称 (此处 category/type 应该 SHOULD 是 "conference/text"):
  
 +
'''例子 71. 房间返回昵称'''
  
 
+
<source lang="xml">
It is OPTIONAL for a multi-user chat service to support the foregoing service discovery node. If the room or service does not support the foregoing service discovery node, it MUST return a <feature-not-implemented/> error to the user. If it does and the user has a registered nickname, it MUST return the nickname to the user as the value of the 'name' attribute of a Service Discovery <identity/> element (for which the category/type SHOULD be "conference/text"):
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 70. Room Returns Nickname
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='getnick1'
 
     id='getnick1'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
 
         node='x-roomuser-item'>
 
         node='x-roomuser-item'>
 
 
     <identity
 
     <identity
 
 
         category='conference'
 
         category='conference'
 
 
         name='thirdwitch'
 
         name='thirdwitch'
 
 
         type='text'/>
 
         type='text'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果该用户没有已注册的昵称, 房间必须 MUST 返回一个空的服务发现 <query/> 元素 (根据 '''XEP-0030''').
  
 +
即使一个用户已经注册了一个房间昵称, 服务应该 SHOULD 允许该用户在加入该房间时指定一个不同的昵称 (例如, 为了从不同的客户端资源加入), 尽管该服务可以 MAY 选择通过一个 <not-acceptable/> 错误来锁定 "lock down" 昵称并拒绝该用户 . 如果该用户的客户端在加入该房间之后发送上述请求,服务不能 MUST NOT 返回一个错误给该用户, 而应该 SHOULD 返回上文所述.
  
 +
如果另一个用户尝试以第一个用户保留的房间昵称来加入房间, 服务必须 MUST 拒绝第二个用户并返回一个前文所述的 <conflict/> 错误.
  
If the user does not have a registered nickname, the room MUST return a service discovery <query/> element that is empty (in accordance with XEP-0030).
+
===申请发言权===
 
+
 
+
 
+
Even if a user has registered one room nickname, the service SHOULD allow the user to specify a different nickname on entering the room (e.g., in order to join from different client resources), although the service MAY choose to "lock down" nicknames and therefore deny entry to the user, including a <not-acceptable/> error. The service MUST NOT return an error to the user if his or her client sends the foregoing request after having already joined the room, but instead SHOULD reply as described above.
+
 
+
 
+
 
+
If another user attempts to join the room with a nickname reserved by the first user, the service MUST deny entry to the second user and return a <conflict/> error as previously described.
+
 
+
7.12 Requesting Voice
+
 
+
 
+
 
+
It is not possible for a visitor to speak (i.e., send a message to all occupants) in a moderated room. To request voice, a visitor SHOULD send a <message/> stanza containing a data form to the room itself, where data form contains only a 'muc#role' field with a value of "participant".
+
 
+
 
+
 
+
Example 71. Occupant Requests Voice
+
  
 +
在一个被主持的房间里游客是不能发言的 (即, 发送一个消息给所有房客). 为了申请发言权, 一个游客应该 SHOULD 发送包含一个数据表格的 <message/> 节给房间本身, 这个数据表格仅仅是一个 'muc#role' 字段,值为 "participant".
  
 +
'''例子 72. 房客申请发言权'''
  
 +
<source lang="xml">
 
<message from='hag66@shakespeare.lit/pda'
 
<message from='hag66@shakespeare.lit/pda'
 
+
         to='darkcave@chat.shakespeare.lit'>
         to='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
   <x xmlns='jabber:x:data' type='submit'>
 
   <x xmlns='jabber:x:data' type='submit'>
 
 
     <field var='FORM_TYPE'>
 
     <field var='FORM_TYPE'>
 
 
       <value>http://jabber.org/protocol/muc#request</value>
 
       <value>http://jabber.org/protocol/muc#request</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#role'
 
     <field var='muc#role'
 
 
           type='text-single'
 
           type='text-single'
 
 
           label='Requested role'>
 
           label='Requested role'>
 
 
       <value>participant</value>
 
       <value>participant</value>
 
 
     </field>
 
     </field>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
服务接着应该 SHOULD 转发这个请求给房间主持人(们) ,定义于本文的[[XEP-0045#批准发言权申请|批准发言权申请]].
  
 +
==主持人用例==
  
 +
一个主持人有权在房间里执行特定的动作 (例如, 变更某些房客的角色) 但无权变更岗位的持久信息 (它只能被管理员或所有者) 或定义关于这个房间的信息. 具体哪些动作可由主持人执行,取决于配置. 无论如何, 对于 MUC 框架来说, 主持人被规定有权执行以下动作:
  
The service then SHOULD forward the request to the room moderator(s) as described in the Approving Voice Requests section of this document.
+
# 在一个半匿名的房间里发现一个房客的全JID(如上文所述缺省会发生)
 +
# 修改主题
 +
# 从该房间踢出一个与会者或游客
 +
# 在一个被主持的房间里授予或撤销发言权
 +
# 在一个被主持的房间里修改拥有发言权的房客列表
  
8. Moderator Use Cases
+
这些特性将通过一个基于 <iq/> 元素的 请求/应答 交换来实现,这个IQ元素包含一个满足 'http://jabber.org/protocol/muc#admin' 名字空间的子元素. 以下例子展示这个协议和实现如何互动达到期望的功能. (以下除非显式地提及, 任何接下来的管理请求必须 MUST 被拒绝,如果该请求的'from'地址 <user@host> 和主持人的纯JID不符的话; 在这种情况下, 服务必须 MUST 返回一个 <forbidden/> 错误.)
  
 +
===修改房间主题===
  
 +
多用户聊天室的一个常用特性是变更房间主题的能力. 缺省地, 一个房间里只有角色为主持人 "moderator" 的用户应该 SHOULD 被允许变更主题 (尽管这应该 SHOULD 是可配置的, 结果是如果需要的话,仅仅与会者或甚至游客都被允许修改主题). 主题变更是通过发送一个类型为 "groupchat" 的消息给 <room@service>来实现的, 在这里 <message/> 必须 MUST 包含一个 <subject/> 元素以指定新的主题,但不应该 SHOULD NOT 包含其他元素 (例如, 不应该有 <body/> 元素或 <thread/> 元素).
  
A moderator has privileges to perform certain actions within the room (e.g., to change the roles of some occupants) but does not have rights to change persistent information about affiliations (which may be changed only by an admin or owner) or defining information about the room. Exactly which actions may be performed by a moderator is subject to configuration. However, for the purposes of the MUC framework, moderators are stipulated to have privileges to perform the following actions:
+
'''例子 73. 主持人变更主题'''
 
+
 
+
 
+
  1. discover an occupant's full JID in a semi-anonymous room (occurs by default as shown above)
+
 
+
  2. modify the subject
+
 
+
  3. kick a participant or visitor from the room
+
 
+
  4. grant or revoke voice in a moderated room
+
 
+
  5. modify the list of occupants who have voice in a moderated room
+
 
+
 
+
 
+
These features shall be implemented with a request/response exchange using <iq/> elements that contain children qualified by the 'http://jabber.org/protocol/muc#admin' namespace. The examples below illustrate the protocol interactions to implement the desired functionality. (Except where explicitly noted below, any of the following administrative requests MUST be denied if the <user@host> of the 'from' address of the request does not match the bare JID portion of one of the moderators; in this case, the service MUST return a <forbidden/> error.)
+
 
+
8.1 Modifying the Room Subject
+
 
+
 
+
 
+
A common feature of multi-user chat rooms is the ability to change the subject within the room. By default, only users with a role of "moderator" SHOULD be allowed to change the subject in a room (although this SHOULD be configurable, with the result that a mere participant or even visitor may be allowed to change the subject if desired). The subject is changed by sending a message of type "groupchat" to the <room@service>, containing no body but a <subject/> that specifies the new subject:
+
 
+
 
+
 
+
Example 72. Moderator Changes Subject
+
 
+
 
+
  
 +
<source lang="xml">
 
<message
 
<message
 
 
     from='wiccarocks@shakespeare.lit/laptop'
 
     from='wiccarocks@shakespeare.lit/laptop'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <subject>Fire Burn and Cauldron Bubble!</subject>
 
   <subject>Fire Burn and Cauldron Bubble!</subject>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果一个 MUC 服务接收到这样一个消息, 它必须 MUST 以发送这个变更主题消息的那个用户的房间JID作为'from'地址来反射这个消息给所有其他房客:
 
+
 
+
 
+
If a MUC service receives such a message, it MUST reflect the message to all other occupants with a 'from' address equal to the room JID that corresponds to the sender of the subject change:
+
 
+
 
+
 
+
Example 73. Service Informs All Occupants of Subject Change
+
 
+
  
 +
'''例子 74. 服务通知所有房客主题变更'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='groupchat'>
 
     type='groupchat'>
 
 
   <subject>Fire Burn and Cauldron Bubble!</subject>
 
   <subject>Fire Burn and Cauldron Bubble!</subject>
 
 
</message>
 
</message>
  
.
+
[ ... ]
 +
</source>
  
.
+
另外, 当一个新的房客加入房间时,该房间应该 SHOULD 在被发送的讨论历史中包含最后的主题变更.
 
+
.
+
 
+
   
+
 
+
 
+
 
+
In addition, the room SHOULD include the last subject change in the discussion history sent when a new occupant joins the room.
+
 
+
 
+
 
+
A MUC client that receives such a message MAY choose to display an in-room message, such as the following:
+
 
+
 
+
 
+
Example 74. Client Displays Room Subject Change Message
+
  
 +
一个接收到这类信息的 MUC 客户端可以 MAY 选择显示一个房间内的消息, 如下:
  
 +
'''例子 75. 客户端显式房间主题变更消息'''
  
 +
<source lang="xml">
 
* secondwitch has changed the subject to: Fire Burn and Cauldron Bubble!
 
* secondwitch has changed the subject to: Fire Burn and Cauldron Bubble!
 +
</source>
  
   
+
如果一些没有适当权限的人尝试变更房间主题, 服务必须 MUST 返回一个 "error" 类型的消息指明一个 <forbidden/> 错误条件:
 
+
 
+
 
+
If someone without appropriate privileges attempts to change the room subject, the service MUST return a message of type "error" specifying a <forbidden/> error condition:
+
 
+
 
+
 
+
Example 75. Service Returns Error Related to Unauthorized Subject Change
+
 
+
  
 +
'''例子 76. 服务返回未被授权变更主题的错误'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
 
   <subject>Fire Burn and Cauldron Bubble!</subject>
 
   <subject>Fire Burn and Cauldron Bubble!</subject>
 
+
   <error type='auth'>
   <error code='403' type='auth'>
+
 
+
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</message>
 
</message>
 +
</source>
  
   
+
为了移除现有的主题而不是提供一个新主题 (即, 设置主题为空), 客户端应该发送一个空的 <subject/> 元素 (即,  "<subject/>" 或 "<subject></subject>").
  
 +
'''例子 77. 主持人设置空的主题'''
  
 +
<source lang="xml">
 +
<message
 +
    from='wiccarocks@shakespeare.lit/laptop'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='groupchat'>
 +
  <subject></subject>
 +
</message>
 +
</source>
  
8.2 Kicking an Occupant
+
===踢出房客===
 
+
 
+
 
+
A moderator has permissions kick certain kinds of occupants from a room (which occupants are "kickable" depends on service provisioning, room configuration, and the moderator's affiliation -- see below). The kick is normally performed based on the occupant's room nickname (though it MAY be based on the full JID) and is completed by setting the role of a participant or visitor to a value of "none".
+
 
+
 
+
 
+
Example 76. Moderator Kicks Occupant
+
  
 +
主持人有权从一个房间踢出特定种类的房客 (哪些房客是可被踢的 "kickable" 取决于服务规定, 房间配置, 以及主持人的岗位 -- 见下文). 踢人通常基于房客的房间昵称来执行 (尽管可以 MAY 基于全JID) 并且完全是通过把与会者或游客的角色设为 "none" 来实现的.
  
 +
'''例子 78. 主持人踢出房客'''
  
 +
<source lang="xml">
 
<iq from='fluellen@shakespeare.lit/pda'
 
<iq from='fluellen@shakespeare.lit/pda'
 
 
     id='kick1'
 
     id='kick1'
 
 
     to='harfleur@henryv.shakespeare.lit'
 
     to='harfleur@henryv.shakespeare.lit'
 
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='pistol' role='none'>
 
     <item nick='pistol' role='none'>
 
 
       <reason>Avaunt, you cullion!</reason>
 
       <reason>Avaunt, you cullion!</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 移除被踢的用户,通过发送一个类型为 "unavailable" 的出席信息节给每个被踢的房客, 这个出席信息应在其扩展出席信息中包含状态码 307 , 或(可选地)包含 reason 子元素(如果提供了) 以及踢人的执行者的纯JID.
 
+
 
+
 
+
The service MUST remove the kicked occupant by sending a presence stanza of type "unavailable" to each kicked occupant, including status code 307 in the extended presence information, optionally along with the reason (if provided) and the bare JID of the user who initiated the kick.
+
 
+
 
+
 
+
Example 77. Service Removes Kicked Occupant
+
 
+
  
 +
'''例子 79. 服务移除被踢的房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='harfleur@henryv.shakespeare.lit/pistol'
 
     from='harfleur@henryv.shakespeare.lit/pistol'
 
 
     to='pistol@shakespeare.lit/harfleur'
 
     to='pistol@shakespeare.lit/harfleur'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none' role='none'>
 
     <item affiliation='none' role='none'>
 
 
       <actor jid='fluellen@shakespeare.lit'/>
 
       <actor jid='fluellen@shakespeare.lit'/>
 
 
       <reason>Avaunt, you cullion!</reason>
 
       <reason>Avaunt, you cullion!</reason>
 
 
     </item>
 
     </item>
 
 
     <status code='307'/>
 
     <status code='307'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
包含状态码可使客户端能够提交他们自己的通知消息 (例如, 适当的用户位置的信息). 可选的包含原因 reason 元素以及执行者 actor 使得被踢的用户能理解为什么他或她被踢了, 以及被踢的用户可以找谁去理论. [[XEP-0045#附录G:备注|18]]
 
+
 
+
 
+
The inclusion of the status code assists clients in presenting their own notification messages (e.g., information appropriate to the user's locality). The optional inclusion of the reason and actor enable the kicked user to understand why he or she was kicked, and by whom if the kicked occupant would like to discuss the matter. [16]
+
 
+
 
+
 
+
After removing the kicked occupant(s), the service MUST then inform the moderator of success:
+
 
+
 
+
 
+
Example 78. Service Informs Moderator of Success
+
  
 +
移除被踢的房客(们)之后, 服务必须 MUST 接着通知主持人成功了:
  
 +
'''例子 80. 服务通知主持人成功了'''
  
 +
<source lang="xml">
 
<iq from='harfleur@henryv.shakespeare.lit'
 
<iq from='harfleur@henryv.shakespeare.lit'
 
 
     id='kick1'
 
     id='kick1'
 
 
     to='fluellen@shakespeare.lit/pda'
 
     to='fluellen@shakespeare.lit/pda'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
通知主持人之后, 服务必须 MUST 接着通知剩余的房客那个被踢的房客已经不在房间里了,即从被踢者的房间昵称(<room@service/nick>)发送 "unavailable" 类型的出席信息节给所有剩余的房客 (就像房客自愿退出房间时所做的一样), 包含状态码 status 以及可选的原因 reason 和执行者 actor.
 
+
 
+
 
+
After informing the moderator, the service MUST then inform all of the remaining occupants that the kicked occupant is no longer in the room by sending presence stanzas of type "unavailable" from the individual's roomnick (<room@service/nick>) to all the remaining occupants (just as it does when occupants exit the room of their own volition), including the status code and optionally the reason and actor.
+
 
+
 
+
 
+
Example 79. Service Informs Remaining Occupants
+
 
+
  
 +
'''例子 81. 服务通知剩余的房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='harfleur@henryv.shakespeare.lit/pistol'
 
     from='harfleur@henryv.shakespeare.lit/pistol'
 
 
     to='gower@shakespeare.lit/cell'
 
     to='gower@shakespeare.lit/cell'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none' role='none'/>
 
     <item affiliation='none' role='none'/>
 
 
     <status code='307'/>
 
     <status code='307'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
一个用户不能被比自己岗位低的主持人踢出. 所以, 如果一个身为与会者的主持人尝试踢出一个管理员,或一个身为与会者的主持人或管理员尝试踢出一个所有者, 服务必须 MUST 拒绝这个请求并返回一个 <not-allowed/> 错误给发送者:
  
.
+
'''例子 82. 服务对于尝试踢出更高岗位的用户返回错误'''
 
+
   
+
 
+
 
+
 
+
A user cannot be kicked by a moderator with a lower affiliation. Therefore, if a moderator who is a participant attempts to kick an admin or a moderator who is a participant or admin attempts to kick an owner, the service MUST deny the request and return a <not-allowed/> error to the sender:
+
 
+
 
+
 
+
Example 80. Service Returns Error on Attempt to Kick User With Higher Affiliation
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
  
 +
<source lang="xml">
 +
<iq from='darkcave@chat.shakespeare.lit'
 
     id='kicktest'
 
     id='kicktest'
 
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='firstwitch' role='none'>
 
     <item nick='firstwitch' role='none'>
 
 
       <reason>Be gone!</reason>
 
       <reason>Be gone!</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
+
   <error type='cancel'>
   <error code='405' type='cancel'>
+
 
+
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果一个主持人尝试踢出他自己, 服务可以 MAY 拒绝这个请求并返回一个 <conflict/> 错误给发送者. (尽管这个踢出自己的行为可能看起来怪异, 它在 IRC 里很常见,用于在房间里为某人的行为道歉.)
  
 +
===授予游客发言权===
  
 +
在一个被主持的房间里, 主持人可能希望管理房间内谁有水没有发言权 "voice" (即, 发送消息给所有房客的能力). 发言权的授予是基于游客的房间昵称来的, 服务将从内部把这个房间昵称转成游客的全JID. 主持人通过把游客的角色变更为与会者 "participant"来给一个游客授予权限.
  
If a moderator attempts to kick himself, the service MAY deny the request and return a <conflict/> error to the sender. (Although the act of kicking oneself may seem odd, it is common in IRC as a way of apologizing for one's actions in the room.)
+
'''例子 83. 主持人授予权限给一个游客'''
  
8.3 Granting Voice to a Visitor
+
<source lang="xml">
 
+
<iq from='crone1@shakespeare.lit/desktop'
 
+
    id='voice1'
 
+
    to='darkcave@chat.shakespeare.lit'
In a moderated room, a moderator may want to manage who does and does not have "voice" in the room (i.e., the ability to send messages to all occupants). Voice is granted based on the visitor's room nickname, which the service will convert into the visitor's full JID internally. The moderator grants voice to a visitor by changing the visitor's role to "participant" (the <reason/> element is optional):
+
    type='set'>
 
+
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 
+
    <item nick='thirdwitch'
 
+
          role='participant'/>
Example 81. Moderator Grants Voice to a Visitor
+
  </query>
 +
</iq>
 +
</source>
  
 +
<reason/> 元素是可选的 OPTIONAL:
  
 +
'''例子 84. 主持人授予权限给一个游客(包含一个原因 Reason)'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='voice1'
 
     id='voice1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='thirdwitch'
 
     <item nick='thirdwitch'
 
 
           role='participant'>
 
           role='participant'>
 
 
       <reason>A worthy witch indeed!</reason>
 
       <reason>A worthy witch indeed!</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 接着通知主持人成功了:
  
 +
'''例子 85. 服务通知主持人成功了'''
  
 
+
<source lang="xml">
The service MUST then inform the moderator of success:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 82. Service Informs Moderator of Success
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='voice1'
 
     id='voice1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 接着以这个人的<room@service/nick>发送更新的出席信息给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'role'属性值为"participant",指明添加了发言权.
 
+
 
+
 
+
The service MUST then send updated presence from this individual's <room@service/nick> to all occupants, indicating the addition of voice privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'role' attribute set to a value of "participant".
+
 
+
 
+
 
+
Example 83. Service Sends Notice of Voice to All Occupants
+
 
+
  
 +
'''例子 86. 服务发送发言权通知给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           nick='thirdwitch'
 
           nick='thirdwitch'
 
 
           role='participant'>
 
           role='participant'>
 
 
       <reason>A worthy witch indeed!</reason>
 
       <reason>A worthy witch indeed!</reason>
 
 
     </item>
 
     </item>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
===撤销与会者发言权===
 
+
.
+
 
+
   
+
 
+
 
+
 
+
8.4 Revoking Voice from a Participant
+
 
+
 
+
 
+
In a moderated room, a moderator may want to revoke a participant's privileges to speak. The moderator can revoke voice from a participant by changing the participant's role to "visitor":
+
 
+
 
+
 
+
Example 84. Moderator Revokes Voice from a Participant
+
  
 +
在一个被主持的房间里, 主持人可能希望撤销一个与会者发言的权力,主持人通过把与会者的角色变更为游客 "visitor"来撤销一个游客的发言权:
  
 +
'''例子 87. 主持人撤销一个与会者的发言权'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='voice2'
 
     id='voice2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='thirdwitch'
 
     <item nick='thirdwitch'
 
 
           role='visitor'/>
 
           role='visitor'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/> 元素是可选的 OPTIONAL:
  
 +
'''例子 88. 主持人撤销一个与会者的发言权(包含一个原因Reason)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='voice2'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item nick='thirdwitch'
 +
          role='visitor'>
 +
      <reason>Not so worthy after all!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST then inform the moderator of success:
+
服务必须 MUST 接着通知主持人成功了:
  
 +
'''例子 89. 服务通知主持人成功了'''
  
 
+
<source lang="xml">
Example 85. Service Informs Moderator of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='voice2'
 
     id='voice2'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 接着以这个人的<room@service/nick>发送更新的出席信息给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'role'属性值为"visitor",指明移除了发言权.
 
+
 
+
 
+
The service MUST then send updated presence from this individual to all occupants, indicating the removal of voice privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'role' attribute set to a value of "visitor".
+
 
+
 
+
 
+
Example 86. Service Notes Loss of Voice
+
 
+
  
 +
'''例子 90. 服务通知失去发言权'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='visitor'/>
 
           role='visitor'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
一个主持人不能 MUST NOT 从一个岗位等于或高于主持人岗位的用户撤销发言权. 另外, 服务不能 MUST NOT 允许一个管理员或所有者的发言权被任何人撤销. 如果一个主持人尝试撤销这些人的发言权, 服务必须 MUST 拒绝这个请求并返回一个 <not-allowed/> 的错误给发送者(通过以下的违规条目):
  
.
+
'''例子 91. 服务对于尝试从管理员,所有者或更高岗位的用户撤销权限返回错误'''
 
+
   
+
 
+
 
+
 
+
A moderator MUST NOT be able to revoke voice from a user whose affiliation is at or above the moderator's level. In addition, a service MUST NOT allow the voice privileges of an admin or owner to be removed by anyone. If a moderator attempts to revoke voice privileges from such a user, the service MUST deny the request and return a <not-allowed/> error to the sender along with the offending item(s):
+
 
+
 
+
 
+
Example 87. Service Returns Error on Attempt to Revoke Voice from an Admin, Owner, or User with a Higher Affiliation
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
  
 +
<source lang="xml">
 +
<iq from='darkcave@chat.shakespeare.lit'
 
     id='voicetest'
 
     id='voicetest'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='secondwitch' role='visitor'/>
 
     <item nick='secondwitch' role='visitor'/>
 
 
   </query>
 
   </query>
 
+
   <error type='cancel'>
   <error code='405' type='cancel'>
+
 
+
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
===修改发言权列表===
 
+
 
+
 
+
8.5 Modifying the Voice List
+
 
+
 
+
 
+
A moderator in a moderated room may want to modify the voice list. To do so, the moderator first requests the voice list by querying the room for all occupants with a role of 'participant'.
+
 
+
 
+
 
+
Example 88. Moderator Requests Voice List
+
  
 +
在一个被主持的房间里主持人可能希望管理发言权列表. 为了达到这个目的, 主持人首先查询房间所有角色为'participant'的房客列表来请求发言权列表.
  
 +
'''例子 92. 主持人请求发言权列表'''
  
 +
<source lang="xml">
 
<iq from='bard@shakespeare.lit/globe'
 
<iq from='bard@shakespeare.lit/globe'
 
 
     id='voice3'
 
     id='voice3'
 
 
     to='goodfolk@chat.shakespeare.lit'
 
     to='goodfolk@chat.shakespeare.lit'
 
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item role='participant'/>
 
     <item role='participant'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 接着返回发言权列表给主持人; 每个条目必须 MUST 包含 'nick' 'role' 属性并且应该 SHOULD 包含 'affiliation' 'jid' 属性:
 
+
 
+
 
+
The service MUST then return the voice list to the moderator; each item MUST include the 'nick' and 'role' attributes and SHOULD include the 'affiliation' and 'jid' attributes:
+
 
+
 
+
 
+
Example 89. Service Sends Voice List to Moderator
+
 
+
  
 +
'''例子 93. 服务发送发言权列表给主持人'''
  
 +
<source lang="xml">
 
<iq from='goodfolk@chat.shakespeare.lit'
 
<iq from='goodfolk@chat.shakespeare.lit'
 
 
     id='voice3'
 
     id='voice3'
 
 
     to='bard@shakespeare.lit/globe'
 
     to='bard@shakespeare.lit/globe'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='polonius@hamlet/castle'
 
           jid='polonius@hamlet/castle'
 
 
           nick='Polo'
 
           nick='Polo'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='horatio@hamlet/castle'
 
           jid='horatio@hamlet/castle'
 
 
           nick='horotoro'
 
           nick='horotoro'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hecate@shakespeare.lit/broom'
 
           jid='hecate@shakespeare.lit/broom'
 
 
           nick='Hecate'
 
           nick='Hecate'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
主持人可以 MAY 接着修改发言权列表. 为了达到这个目的, 主持人必须 MUST 发送变更了的条目 (, 只有 "delta") 给服务; 每个条目必须 MUST 包含 'nick' 属性和 'role' 属性 (通常设置值为 "participant" "visitor") 但是不应该 SHOULD NOT 包含 'jid' 属性并且不能 MUST NOT 包含 'affiliation' 属性 (它用于管理如所有者那样的岗位而不是与会者那样的角色):
 
+
 
+
 
+
The moderator MAY then modify the voice list. In order to do so, the moderator MUST send the changed items (i.e., only the "delta") back to the service; each item MUST include the 'nick' attribute and 'role' attribute (normally set to a value of "participant" or "visitor") but SHOULD NOT include the 'jid' attribute and MUST NOT include the 'affiliation' attribute (which is used to manage affiliations such as owner rather than the participant role):
+
 
+
 
+
 
+
Example 90. Moderator Sends Modified Voice List to Service
+
 
+
  
 +
'''例子 94. 主持人发送修改的发言权列表给服务'''
  
 +
<source lang="xml">
 
<iq from='bard@shakespeare.lit/globe'
 
<iq from='bard@shakespeare.lit/globe'
 
 
     id='voice4'
 
     id='voice4'
 
 
     to='goodfolk@chat.shakespeare.lit'
 
     to='goodfolk@chat.shakespeare.lit'
 
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='Hecate'
 
     <item nick='Hecate'
 
 
           role='visitor'/>
 
           role='visitor'/>
 
 
     <item nick='rosencrantz'
 
     <item nick='rosencrantz'
 
 
           role='participant'>
 
           role='participant'>
 
 
       <reason>A worthy fellow.</reason>
 
       <reason>A worthy fellow.</reason>
 
 
     </item>
 
     </item>
 
 
     <item nick='guildenstern'
 
     <item nick='guildenstern'
 
 
           role='participant'>
 
           role='participant'>
 
 
       <reason>A worthy fellow.</reason>
 
       <reason>A worthy fellow.</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 接着通知主持人成功了:
 
+
 
+
 
+
The service MUST then inform the moderator of success:
+
 
+
 
+
 
+
Example 91. Service Informs Moderator of Success
+
 
+
  
 +
'''例子 95. 服务通知主持人成功了'''
  
 +
<source lang="xml">
 
<iq from='goodfolk@chat.shakespeare.lit'
 
<iq from='goodfolk@chat.shakespeare.lit'
 
 
     id='voice1'
 
     id='voice1'
 
 
     to='bard@shakespeare.lit/globe'
 
     to='bard@shakespeare.lit/globe'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 接着为任何受影响的人发送更新的出席信息给所有房客, 如前文的用例所述,发送适当的扩展出席信息来指明发言权的变更.
 
+
 
+
 
+
The service MUST then send updated presence for any affected individuals to all occupants, indicating the change in voice privileges by sending the appropriate extended presence stanzas as described in the foregoing use cases.
+
 
+
 
+
 
+
As noted, voice privileges cannot be revoked from a room owner or room admin, nor from any user with a higher affiliation than the moderator making the request. If a room admin attempts to revoke voice privileges from such a user by modifying the voice list, the service MUST deny the request and return a <not-allowed/> error to the sender:
+
 
+
 
+
 
+
Example 92. Service Returns Error on Attempt to Revoke Voice from an Admin, Owner, or User with a Higher Affiliation
+
  
 +
大家知道, 不能撤销一个房间所有者或管理员的发言权, 也不能撤销比发出请求的主持人岗位高的用户的发言权. 如果一个房间管理员尝试通过修改发言权列表来撤销这类用户的发言权, 服务必须 MUST 拒绝请求并返回一个 <not-allowed/> 错误给发送者:
  
 +
'''例子 96. 服务返回错误给试图撤销管理员,所有者或比发送者岗位更高的用户的发言权的发送者'''
  
 +
<source lang="xml">
 
<iq from='goodfolk@chat.shakespeare.lit'
 
<iq from='goodfolk@chat.shakespeare.lit'
 
 
     id='voicetest'
 
     id='voicetest'
 
 
     to='bard@shakespeare.lit/globe'
 
     to='bard@shakespeare.lit/globe'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item jid='hecate@shakespeare.lit'
 
     <item jid='hecate@shakespeare.lit'
 
 
           nick='Hecate'
 
           nick='Hecate'
 
 
           role='visitor'/>
 
           role='visitor'/>
 
 
   </query>
 
   </query>
 
+
   <error type='cancel'>
   <error code='405' type='cancel'>
+
 
+
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
===批准发言权申请===
  
 +
在本文的[[XEP-0045#申请发言权|申请发言权]]章节提到, 当服务接受到一个来自房客的请求,它应该 SHOULD 转发那个请求给房间的主持人(们). 为了达到这个目的, 服务应该 SHOULD 发送一个 <message/> 节给房间主持人(们), 这里 <message/> 节包含一个数据表格data form来批准或拒绝这个申请, 如下所示.
  
 +
'''例子 97. 申请批准发言权表格''
  
8.6 Approving Voice Requests
+
<source lang="xml">
 
+
<message from='darkcave@chat.shakespeare.lit'
 
+
 
+
As noted in the Requesting Voice section of this document, when a service receives a request for voice from an occupant it SHOULD forward that request to the room moderator(s). To do so, the service SHOULD send a <message/> stanza to the room moderator(s), where the <message/> stanza contains a data form asking for approval or denial of the request, as shown below.
+
 
+
 
+
 
+
Example 93. Voice Request Approval Form
+
 
+
 
+
 
+
<message from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
         id='approve'
 
         id='approve'
 
 
         to='crone1@shakespeare.lit/pda'>
 
         to='crone1@shakespeare.lit/pda'>
 
 
   <x xmlns='jabber:x:data' type='form'>
 
   <x xmlns='jabber:x:data' type='form'>
 
 
     <title>Voice request</title>
 
     <title>Voice request</title>
 
 
     <instructions>
 
     <instructions>
 
 
       To approve this request for voice, select  
 
       To approve this request for voice, select  
 
 
       the &quot;Grant voice to this person?&quot;
 
       the &quot;Grant voice to this person?&quot;
 
 
       checkbox and click OK. To skip this request,  
 
       checkbox and click OK. To skip this request,  
 
 
       click the cancel button.
 
       click the cancel button.
 
 
     </instructions>
 
     </instructions>
 
 
     <field var='FORM_TYPE' type='hidden'>
 
     <field var='FORM_TYPE' type='hidden'>
 
 
         <value>http://jabber.org/protocol/muc#request</value>
 
         <value>http://jabber.org/protocol/muc#request</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#role'
 
     <field var='muc#role'
 
 
           type='text-single'
 
           type='text-single'
 
 
           label='Requested role'>
 
           label='Requested role'>
 
 
       <value>participant</value>
 
       <value>participant</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#jid'
 
     <field var='muc#jid'
 
 
           type='text-single'
 
           type='text-single'
 
 
           label='User ID'>
 
           label='User ID'>
 
 
       <value>hag66@shakespeare.lit/pda</value>
 
       <value>hag66@shakespeare.lit/pda</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#roomnick'
 
     <field var='muc#roomnick'
 
 
           type='text-single'
 
           type='text-single'
 
 
           label='Room Nickname'>
 
           label='Room Nickname'>
 
 
       <value>thirdwitch</value>
 
       <value>thirdwitch</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#request_allow'
 
     <field var='muc#request_allow'
 
 
           type='boolean'
 
           type='boolean'
 
 
           label='Grant voice to this person?'>
 
           label='Grant voice to this person?'>
 
 
       <value>false</value>
 
       <value>false</value>
 
 
     </field>
 
     </field>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
为了批准这个申请, 主持人将提交此表格:
 
+
 
+
 
+
In order to approve the request, a moderator shall submit the form:
+
 
+
 
+
 
+
Example 94. Voice Request Approval Submission
+
 
+
  
 +
'''例子 98. 批准发言权申请'''
  
 +
<source lang="xml">
 
<message from='crone1@shakespeare.lit/pda'
 
<message from='crone1@shakespeare.lit/pda'
 
 
         id='approve'
 
         id='approve'
 
+
         to='darkcave@chat.shakespeare.lit'>
         to='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
   <x xmlns='jabber:x:data' type='submit'>
 
   <x xmlns='jabber:x:data' type='submit'>
 
 
     <field var='FORM_TYPE' type='hidden'>
 
     <field var='FORM_TYPE' type='hidden'>
 
 
         <value>http://jabber.org/protocol/muc#request</value>
 
         <value>http://jabber.org/protocol/muc#request</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#role'>
 
     <field var='muc#role'>
 
 
       <value>participant</value>
 
       <value>participant</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#jid'>
 
     <field var='muc#jid'>
 
 
       <value>hag66@shakespeare.lit/pda</value>
 
       <value>hag66@shakespeare.lit/pda</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#roomnick'>
 
     <field var='muc#roomnick'>
 
 
       <value>thirdwitch</value>
 
       <value>thirdwitch</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#request_allow'>
 
     <field var='muc#request_allow'>
 
 
       <value>true</value>
 
       <value>true</value>
 
 
     </field>
 
     </field>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果主持人批准了这个发言权申请, 服务将授予发言权给该房客并发送一个出席信息更新,如本文[[XEP-0045#授予游客发言权|授予游客发言权]]章节所述.
  
 +
==管理员用例==
  
 +
一个房间管理员有权修改用户岗位的持久信息 (例如, 通过禁止用户) 并授予和撤销主持人权限, 但是无权修改房间的定义, 那是唯一属于房间所有者(们)的权力. 具体哪些动作是管理员可以执行的则取决于配置. 无论如何, 在 MUC 框架中的用途, 规定房间管理员最少拥有执行以下操作的权限:
  
If a moderator approves the voice request, the service shall grant voice to the occupant and send a presence update as described in the Granting Voice to a Visitor section of this document.
+
# 在房间里禁止一个用户
 +
# 在房间里修改黑名单
 +
# 授予或撤销成员资格
 +
# 修改成员列表
 +
# 授予或撤销主持人权力
 +
# 修改主持人列表
  
9. Admin Use Cases
+
这些特性将由一个 请求/应答 request/response 式的交换来实现,使用 <iq/> 元素,包含满足 'http://jabber.org/protocol/muc#admin' 名字空间的子元素. 以下例子展示协议如何与实现互动以得到期望的功能. (以下除非显示地声明, 如果发送方的'from'地址中的<user@host>和任何房间管理员的纯JID都不同,接下来的任何管理请求必须 MUST 被拒绝; 这种情况下, 服务必须 MUST 返回一个 <forbidden/> 错误.)
  
 +
===禁止用户===
  
 +
在房间里一个管理员或所有者可以禁止一个或多个用户. 这动作必须 MUST 基于房客的纯JID来执行. 为了禁止一个用户, 管理员必须 MUST 把该用户的岗位改为"outcast".
  
A room administrator has privileges to modify persistent information about user affiliations (e.g., by banning users) and to grant and revoke moderator privileges, but does not have rights to change the defining features of the room, which are the sole province of the room owner(s). Exactly which actions may be performed by a room admin will be subject to configuration. However, for the purposes of the MUC framework, room admins are stipulated to at a minimum have privileges to perform the following actions:
+
'''例子 99. 管理员禁止用户'''
  
 +
<source lang="xml">
 +
<iq from='kinghenryv@shakespeare.lit/throne'
 +
    id='ban1'
 +
    to='southampton@henryv.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item affiliation='outcast'
 +
          jid='earlofcambridge@shakespeare.lit'/>
 +
  </query>
 +
</iq>
 +
</source>
  
 +
<reason/> 元素是可选的 OPTIONAL.
  
  1. ban a user from the room
+
'''例子 100. 管理员禁止用户(包含一个原因 Reason)'''
 
+
  2. modify the list of users who are banned from the room
+
 
+
  3. grant or revoke membership
+
 
+
  4. modify the member list
+
 
+
  5. grant or revoke moderator privileges
+
 
+
  6. modify the list of moderators
+
 
+
 
+
 
+
These features shall be implemented with a request/response exchange using <iq/> elements that contain children qualified by the 'http://jabber.org/protocol/muc#admin' namespace. The examples below illustrate the protocol interactions that implement the desired functionality. (Except where explicitly noted below, any of the following administrative requests MUST be denied if the <user@host> of the 'from' address of the request does not match the bare JID of one of the room admins; in this case, the service MUST return a <forbidden/> error.)
+
 
+
9.1 Banning a User
+
 
+
 
+
 
+
An admin or owner can ban one or more users from a room. The ban MUST be performed based on the occupant's bare JID. In order to ban a user, an admin MUST change the user's affiliation to "outcast".
+
 
+
 
+
 
+
Example 95. Admin Bans User
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
 
     id='ban1'
 
     id='ban1'
 
 
     to='southampton@henryv.shakespeare.lit'
 
     to='southampton@henryv.shakespeare.lit'
 
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='outcast'
 
     <item affiliation='outcast'
 
 
           jid='earlofcambridge@shakespeare.lit'>
 
           jid='earlofcambridge@shakespeare.lit'>
 
 
       <reason>Treason</reason>
 
       <reason>Treason</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 把那个纯JID添加到黑名单, 应该 SHOULD 把被排斥者的昵称从已注册的昵称列表中移除, 并且必须 MUST 通知管理员或所有者成功了:
 
+
 
+
 
+
The service MUST add that bare JID to the ban list, SHOULD remove the outcast's nickname from the list of registered nicknames, and MUST inform the admin or owner of success:
+
 
+
 
+
 
+
Example 96. Service Informs Admin or Owner of Success
+
 
+
  
 +
'''例子 101. 服务通知管理员或所有者成功了'''
  
 +
<source lang="xml">
 
<iq from='southampton@henryv.shakespeare.lit'
 
<iq from='southampton@henryv.shakespeare.lit'
 
 
     id='ban1'
 
     id='ban1'
 
 
     to='kinghenryv@shakespeare.lit/throne'
 
     to='kinghenryv@shakespeare.lit/throne'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 也移除任何还在房间中的被禁止的用户,通过发送 "unavailable" 类型的出席信息节给每个被禁止的房客, 在扩展的出席信息中包含一个状态码 301 , 可选地带上 reason (如果服务提供的话) 以及执行这个禁止动作的用户的纯JID.
 
+
 
+
 
+
The service MUST also remove any banned users who are in the room by sending a presence stanza of type "unavailable" to each banned occupant, including status code 301 in the extended presence information, optionally along with the reason (if provided) and the bare JID of the user who initiated the ban.
+
 
+
 
+
 
+
Example 97. Service Removes Banned User
+
 
+
  
 +
'''例子 102. 服务移除被禁止的用户'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='southampton@henryv.shakespeare.lit/cambridge'
 
     from='southampton@henryv.shakespeare.lit/cambridge'
 
 
     to='earlofcambridge@shakespeare.lit/stabber'
 
     to='earlofcambridge@shakespeare.lit/stabber'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='outcast' role='none'>
 
     <item affiliation='outcast' role='none'>
 
 
       <actor jid='kinghenryv@shakespeare.lit'/>
 
       <actor jid='kinghenryv@shakespeare.lit'/>
 
 
       <reason>Treason</reason>
 
       <reason>Treason</reason>
 
 
     </item>
 
     </item>
 
 
     <status code='301'/>
 
     <status code='301'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
包含状态码可使客户端能够提交他们自己的通知消息 (例如, 适当的用户位置的信息). 可选的包含原因 reason 元素以及执行者 actor 使得被踢的用户能理解为什么他或她被踢了, 以及被踢的用户可以找谁去理论.
 
+
 
+
 
+
The inclusion of the status code assists clients in presenting their own notification messages (e.g., information appropriate to the user's locality). The optional inclusion of the reason and actor enable the banned user to understand why he or she was banned, and by whom if the banned user would like to discuss the matter.
+
 
+
 
+
 
+
The service MUST then inform all of the remaining occupants that the banned user is no longer in the room by sending presence stanzas of type "unavailable" from the banned user to all remaining occupants (just as it does when occupants exit the room of their own volition), including the status code and optionally the reason and actor:
+
 
+
 
+
 
+
Example 98. Service Informs Remaining Occupants
+
  
 +
通知主持人之后, 服务必须 MUST 接着通知剩余的房客那个被禁止的房客已经不在房间里了,即从被禁止用户发送 "unavailable" 类型的出席信息节给所有剩余的房客 (就像房客自愿退出房间时所做的一样), 包含状态码 status 以及可选的原因 reason 和执行者 actor.
  
 +
'''例子 103. 服务通知剩余的房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     type='unavailable'
 
     type='unavailable'
 
 
     from='southampton@henryv.shakespeare.lit/cambridge'
 
     from='southampton@henryv.shakespeare.lit/cambridge'
 
 
     to='exeter@shakespeare.lit/pda'>
 
     to='exeter@shakespeare.lit/pda'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='outcast'
 
     <item affiliation='outcast'
 
 
           jid='earlofcambridge@shakespeare.lit/stabber'
 
           jid='earlofcambridge@shakespeare.lit/stabber'
 
 
           role='none'/>
 
           role='none'/>
 
 
     <status code='301'/>
 
     <status code='301'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 
+
</source>
.
+
 
+
.
+
 
+
   
+
 
+
 
+
 
+
As with Kicking an Occupant, a user cannot be banned by an admin with a lower affiliation. Therefore, if an admin attempts to ban an owner, the service MUST deny the request and return a <not-allowed/> error to the sender:
+
 
+
 
+
 
+
Example 99. Service Returns Error on Attempt to Ban User With Higher Affiliation
+
  
 +
就像[[XEP-0045#踢出房客|踢出房客]]一样, 一个用户不能被自己岗位低的管理员禁止. 所以, 如果一个管理员尝试禁止一个所有者, 服务必须 MUST 拒绝这个请求并返回一个 <not-allowed/> 错误给发送者:
  
 +
'''例子 104. 服务对尝试禁止更高岗位用户返回错误'''
  
 +
<source lang="xml">
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
 
     id='ban1'
 
     id='ban1'
 
 
     to='southampton@henryv.shakespeare.lit'
 
     to='southampton@henryv.shakespeare.lit'
 
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='outcast'
 
     <item affiliation='outcast'
 
 
           jid='earlofcambridge@shakespeare.lit'>
 
           jid='earlofcambridge@shakespeare.lit'>
 
 
       <reason>Treason</reason>
 
       <reason>Treason</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
+
   <error type='cancel'>
   <error code='405' type='cancel'>
+
 
+
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果一个管理员或所有者尝试禁止他自己, 服务必须 MUST 拒绝这个请求并返回一个 <conflict/> 错误给发送者. (注意:这和踢出自己时推荐的服务行为不同, 踢自己的行为服务是允许的.)
  
 +
===修改黑名单===
  
 +
房间管理员可能希望修改黑名单. 注意: 黑名单总是基于用户的纯JID. 要修改黑名单, 管理员首先向房间查询所有岗位为'outcast'的用户以得到黑名单.
  
If an admin or owner attempts to ban himself, the service MUST deny the request and return a <conflict/> error to the sender. (Note: This is different from the recommended service behavior on kicking oneself, which a service may allow.)
+
'''例子 105. 管理员请求黑名单'''
 
+
9.2 Modifying the Ban List
+
 
+
 
+
 
+
A room admin may want to modify the ban list. Note: The ban list is always based on a user's bare JID, although a nick (perhaps the last room nickname associated with that JID) MAY be included for convenience. To modify the list of banned JIDs, the admin first requests the ban list by querying the room for all users with an affiliation of 'outcast'.
+
 
+
 
+
 
+
Example 100. Admin Requests Ban List
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
 
     id='ban2'
 
     id='ban2'
 
 
     to='southampton@henryv.shakespeare.lit'
 
     to='southampton@henryv.shakespeare.lit'
 
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='outcast'/>
 
     <item affiliation='outcast'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 接着返回黑名单给管理员; 每个条目必须 MUST 包含 'affiliation' 'jid' 属性但不应该 SHOULD NOT 包含 'nick' 'role' 属性:
 
+
 
+
 
+
The service MUST then return the list of banned users to the admin; each item MUST include the 'affiliation' and 'jid' attributes but SHOULD NOT include the 'nick' and 'role' attributes:
+
 
+
 
+
 
+
Example 101. Service Sends Ban List to Admin
+
 
+
  
 +
'''例子 106. 服务发送黑名单给管理员'''
  
 +
<source lang="xml">
 
<iq from='southampton@henryv.shakespeare.lit'
 
<iq from='southampton@henryv.shakespeare.lit'
 
 
     id='ban2'
 
     id='ban2'
 
 
     to='kinghenryv@shakespeare.lit/throne'
 
     to='kinghenryv@shakespeare.lit/throne'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='outcast'
 
     <item affiliation='outcast'
 
 
           jid='earlofcambridge@shakespeare.lit'>
 
           jid='earlofcambridge@shakespeare.lit'>
 
 
       <reason>Treason</reason>
 
       <reason>Treason</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
管理员可以 MAY 接着修改黑名单. 为此, 管理员必须 MUST 发送变更的条目 (, 仅是 "delta") 给服务; 每个条目必须 MUST 包含 'affiliation' 属性 (通常设为"outcast"来禁止或"none"来取消禁止) 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,不能 MUST NOT 包含 'role' 属性 (它用来管理角色,例如与会者,而不是被排斥者岗位); 另外, reason actor 元素是可选的 OPTIONAL:
 
+
 
+
 
+
The admin MAY then modify the ban list. In order to do so, the admin MUST send the changed items (i.e., only the "delta") back to the service; each item MUST include the 'affiliation' attribute (normally set to a value of "outcast" to ban or "none" to remove ban) and 'jid' attribute but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'role' attribute (which is used to manage roles such as participant rather than the outcast affiliation); in addition, the reason and actor elements are OPTIONAL:
+
 
+
 
+
 
+
Example 102. Admin Sends Modified Ban List to Service
+
 
+
  
 +
'''例子 107. 管理员发送修改的黑名单给服务'''
  
 +
<source lang="xml">
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
<iq from='kinghenryv@shakespeare.lit/throne'
 
 
     id='ban3'
 
     id='ban3'
 
 
     to='southampton@henryv.shakespeare.lit'
 
     to='southampton@henryv.shakespeare.lit'
 
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='outcast'
 
     <item affiliation='outcast'
 
 
           jid='earlofcambridge@shakespeare.lit'>
 
           jid='earlofcambridge@shakespeare.lit'>
 
 
       <reason>Treason</reason>
 
       <reason>Treason</reason>
 
 
     </item>
 
     </item>
 
 
     <item affiliation='outcast'>
 
     <item affiliation='outcast'>
 
 
           jid='lordscroop@shakespeare.lit'>
 
           jid='lordscroop@shakespeare.lit'>
 
 
       <reason>Treason</reason>
 
       <reason>Treason</reason>
 
 
     </item>
 
     </item>
 
 
     <item affiliation='outcast'
 
     <item affiliation='outcast'
 
 
           jid='sirthomasgrey@shakespeare.lit'>
 
           jid='sirthomasgrey@shakespeare.lit'>
 
 
       <reason>Treason</reason>
 
       <reason>Treason</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
更新黑名单之后, 服务必须 MUST 通知管理员成功了:
 
+
 
+
 
+
After updating the ban list, the service MUST inform the admin of success:
+
 
+
 
+
 
+
Example 103. Service Informs Admin of Success
+
 
+
  
 +
'''例子 108. 服务通知管理员成功了'''
  
 +
<source lang="xml">
 
<iq from='southampton@henryv.shakespeare.lit'
 
<iq from='southampton@henryv.shakespeare.lit'
 
 
     id='ban3'
 
     id='ban3'
 
 
     to='kinghenryv@shakespeare.lit/throne'
 
     to='kinghenryv@shakespeare.lit/throne'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 接着移除受影响的房客 (如果他们在房间里) 并从他们发送更新的出席信息 (包含适当的状态码) 给所有剩余的房客,如 "禁止用户" 用例所述. (服务应该 SHOULD 也移除从保留房间昵称列表中移除每个被禁止的用户的保留昵称, 如果必要.)
  
 +
当一个实体被一个房间禁止, 实现应该 SHOULD 按以下顺序匹配 JIDs (这些匹配规则和'''RFC 3921'''中定义的隐私列表的匹配规则是相同的):
  
 +
# <user@domain/resource> (仅匹配特定的资源)
 +
# <user@domain> (匹配任何资源)
 +
# <domain/resource> (仅匹配特定资源)
 +
# <domain> (匹配域名本身, 就像任何 user@domain 或 domain/resource 一样)
  
The service MUST then remove the affected occupants (if they are in the room) and send updated presence (including the appropriate status code) from them to all the remaining occupants as described in the "Banning a User" use case. (The service SHOULD also remove each banned user's reserved nickname from the list of reserved roomnicks, if appropriate.)
+
一些管理员可能希望在一个 MUC 服务中的所有房间里禁止所有和特定域名相关的用户. 这个功能是一个服务级的特性,所以超过了本文的范围, 它定义在 '''XEP-0133'''里.
  
 +
===授予成员资格===
  
 +
管理员可以授予成员资格给一个用户; 方法是把用户的岗位改为 "member" (通常如果用户在房间里,基于昵称,如果用户不在房间里,则基于纯JID; 在这两种情况下如果提供了昵称, 那么这个昵称就是用户在这个房间的缺省昵称,如果实现支持那个功能的话):
  
When an entity is banned from a room, an implementation SHOULD match JIDs in the following order (these matching rules are the same as those defined for privacy lists in RFC 3921):
+
'''例子 109. 管理员授予成员资格'''
 
+
 
+
 
+
  1. <user@domain/resource> (only that resource matches)
+
 
+
  2. <user@domain> (any 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)
+
 
+
 
+
 
+
Some administrators may wish to ban all users associated with a specific domain from all rooms hosted by a MUC service. Such functionality is a service-level feature and is therefore out of scope for this document (but see Service Administration [17]).
+
 
+
9.3 Granting Membership
+
 
+
 
+
 
+
An admin can grant membership to a user; this is done by changing the user's affiliation to "member" (normally based on nick if the user is in the room, or on bare JID if not; in either case, if the nick is provided, that nick becomes the user's default nick in the room if that functionality is supported by the implementation):
+
 
+
 
+
 
+
Example 104. Admin Grants Membership
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='member1'
 
     id='member1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit'/>
 
           jid='hag66@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/> 元素是可选的 OPTIONAL.
  
 +
'''例子 110. 管理员授予成员资格(包含一个原因Reason)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='member1'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item affiliation='member'
 +
          jid='hag66@shakespeare.lit'>
 +
      <reason>A worthy witch indeed!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST add the user to the member list and then inform the admin of success:
+
服务必须 MUST 把这个用户添加到成员列表,然后通知管理员成功了:
  
 +
'''例子 111. 服务通知管理员成功了'''
  
 
+
<source lang="xml">
Example 105. Service Informs Admin of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='member1'
 
     id='member1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'affiliation'属性值为"member",指明授予了成员资格.
 
+
 
+
 
+
If the user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the granting of membership by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "member".
+
 
+
 
+
 
+
Example 106. Service Sends Notice of Membership to All Occupants
+
 
+
  
 +
'''例子 112. 服务发送成员资格通知给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果该用户不在房间里, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 在这个消息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'affiliation'属性值为"member",指明授予了成员资格.
  
.
+
'''例子 113. 服务发送成员资格通知给所有房客'''
  
      
+
<source lang="xml">
 +
<message
 +
     from='chat.shakespeare.lit'
 +
    to='crone1@shakespeare.lit/desktop'>
 +
  <x xmlns='http://jabber.org/protocol/muc#user'>
 +
    <item affiliation='member'
 +
          jid='hag66@shakespeare.lit'
 +
          role='none'/>
 +
  </x>
 +
</message>
  
 +
[ ... ]
 +
</source>
  
 +
===撤销成员资格===
  
9.4 Revoking Membership
+
一个管理员可能想撤销一个用户的成员资格; 通过把该用户的岗位改为"none":
 
+
 
+
 
+
An admin may want to revoke a user's membership; this is done by changing the user's affiliation to "none":
+
 
+
 
+
 
+
Example 107. Admin Revokes Membership
+
 
+
  
 +
'''例子 114. 管理员撤销成员资格'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='member2'
 
     id='member2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='hag66@shakespeare.lit'/>
 
           jid='hag66@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/> 元素是可选的 OPTIONAL.
  
 +
'''例子 115. 管理员撤销成员资格(包含一个原因Reason)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='member2'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item affiliation='none'
 +
          jid='hag66@shakespeare.lit'>
 +
      <reason>Not so worthy after all!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST remove the user from the member list and then inform the moderator of success:
+
服务必须 MUST 从成员列表中移除该用户然后通知主持人成功了:
  
 +
'''例子 116. 服务通知主持人成功了'''
  
 
+
<source lang="xml">
Example 108. Service Informs Moderator of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='member2'
 
     id='member2'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 接着以这个用户的名义发送更新的出席信息节给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'affiliation'属性值为"none",指明失去了成员资格.
 
+
 
+
 
+
The service MUST then send updated presence from this individual to all occupants, indicating the loss of membership by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "none".
+
 
+
 
+
 
+
Example 109. Service Notes Loss of Membership
+
 
+
  
 +
'''例子 117. 服务通知失去成员资格'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 
+
</source>
.
+
 
+
.
+
 
+
   
+
 
+
 
+
 
+
If the room is members-only, the service MUST remove the user from the room, including a status code of 321 to indicate that the user was removed because of an affiliation change, and inform all remaining occupants:
+
 
+
 
+
 
+
Example 110. Service Removes Non-Member
+
  
 +
如果房间是仅限会员的, 服务必须 MUST 从房间移除这个用户, 包含一个状态码 321 来指明用户被移除是因为岗位变更, 并通知所有剩余的房客:
  
 +
'''例子 118. 服务移除非会员'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none' role='none'>
 
     <item affiliation='none' role='none'>
 
 
       <actor jid='bard@shakespeare.lit'/>
 
       <actor jid='bard@shakespeare.lit'/>
 
 
     </item>
 
     </item>
 
 
     <status code='321'/>
 
     <status code='321'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none' role='none'/>
 
     <item affiliation='none' role='none'/>
 
 
     <status code='321'/>
 
     <status code='321'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
===修改成员列表===
  
.
+
在一个仅限会员的房间的上下文里, 成员列表本质上是一个允许人们加入房间的白名单 "whitelist". 任何不是成员的人等于是被禁止加入该房间, 即使他们的岗位不是"outcast".
  
   
+
在一个开放房间的上下文里, 成员列表只是一个注册了这个房间的用户 (纯JID和保留的昵称) 的列表. 这些用户可以出现在一个房间名册里, 有他们自己的保留房间昵称, 在搜索结果或类似FAQ里被返回给(查询者).
 
+
 
+
 
+
9.5 Modifying the Member List
+
 
+
 
+
 
+
In the context of a members-only room, the member list is essentially a "whitelist" of people who are allowed to enter the room. Anyone who is not a member is effectively banned from entering the room, even if their affiliation is not "outcast".
+
 
+
 
+
 
+
In the context of an open room, the member list is simply a list of users (bare JID and reserved nick) who are registered with the room. Such users may appear in a room roster, have their room nickname reserved, be returned in search results or FAQ queries, and the like.
+
 
+
 
+
 
+
It is RECOMMENDED that only room admins have the privilege to modify the member list in members-only rooms. To do so, the admin first requests the member list by querying the room for all users with an affiliation of "member":
+
 
+
 
+
 
+
Example 111. Admin Requests Member List
+
  
 +
推荐 RECOMMENDED 在仅限会员的房间里只让房间管理员拥有修改成员列表的权力. 为此, 管理员首先请求成员列表,通过查询房间里所有岗位为"member"的用户来实现:
  
 +
'''例子 119. 管理员请求成员列表'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='member3'
 
     id='member3'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='member'/>
 
     <item affiliation='member'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
注意: 在一个仅限会员的房间里,服务也应该 SHOULD 返回成员列表给任何房客; 即, 当一个房间的成员请求房间列表时,它不应该 SHOULD NOT 生成一个 <forbidden/> 错误. 这个功能可帮助客户端展示所有现有的成员,即使他们中的一些人不在房间里, 例如. 帮助成员确定是否另一个用户应该被邀请. 服务也应该 SHOULD 允许任何成员接收成员列表,即使还不是一个房客(译注:即未进入房间).
  
 +
服务必须 MUST 接着返回全部的成员列表给管理员,遵循 'http://jabber.org/protocol/muc#admin' 名字空间; 每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性,每个正在房间里的成员可以 MAY 包含 'nick' 和 'role' 属性.
  
 +
'''例子 120. 服务发送成员列表给管理员'''
  
(A service SHOULD also return the member list to any occupant in a members-only room; i.e., it SHOULD NOT generate a <forbidden/> error when a member in the room requests the member list. This functionality may assist clients in showing all the existing members even if some of them are not in the room, e.g. to help a member determine if another user should be invited.)
+
<source lang="xml">
 
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
The service MUST then return the full member list to the admin qualified by the 'http://jabber.org/protocol/muc#admin' namespace; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for each members that is currently an occupant.
+
 
+
 
+
 
+
Example 112. Service Sends Member List to Admin
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='member3'
 
     id='member3'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit'
 
           jid='hag66@shakespeare.lit'
 
 
           nick='thirdwitch'
 
           nick='thirdwitch'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
管理员可以 MAY 接着修改成员列表. 为此, 管理员必须 MUST 发送变更的条目 (, "delta") 给服务; 每个条目必须 MUST 包含 'affiliation' 属性(通常值设为 "member" "none") 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,并且不能 MUST NOT 包含 'role' 属性(它是用来管理角色的,例如与会者,而不是成员的岗位):
 
+
 
+
 
+
The admin MAY then modify the member list. In order to do so, the admin MUST send the changed items (i.e., only the "delta") to the service; each item MUST include the 'affiliation' attribute (normally set to a value of "member" or "none") and 'jid' attribute but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'role' attribute (which is used to manage roles such as participant rather than the member affiliation):
+
 
+
 
+
 
+
Example 113. Admin Sends Modified Member List to Service
+
 
+
  
 +
'''例子 121. 管理员发送修改的成员列表给服务'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='member4'
 
     id='member4'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='hag66@shakespeare.lit'/>
 
           jid='hag66@shakespeare.lit'/>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hecate@shakespeare.lit'/>
 
           jid='hecate@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 修改成员列表然后通知主持人成功了:
  
 +
'''例子 122. 服务通知主持人成功了'''
  
 
+
<source lang="xml">
The service MUST modify the member list and then inform the moderator of success:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 114. Service Informs Moderator of Success
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='member4'
 
     id='member4'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 变更任何受影响的用户的岗位. 如果该用户已经从成员列表中移除了, 服务必须 MUST 把该用户的岗位从 "member" 变更为 "none". 如果该用户已经被加入到成员列表, 服务必须 MUST 把该用户的岗位改成 "member".
  
 +
如果一个被移除的成员正在一个仅限会员的房间, 服务应该 SHOULD 踢出这个房客,如前文所述,通过把被移除的成员的角色改成 "none" 并发送适当的出席信息给这个被移除的成员来实现. 无论是否被移除的那个用户在或不在一个仅限会员的房间里, 服务必须 MUST 随后拒绝这个用户的进入.
  
 +
对所有的房间类型来说, 服务必须 MUST 以这个用户的名义发送更新的出席信息给所有的房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'affiliation'属性值设为"none",以指明这个岗位的变更.
  
The service MUST change the affiliation of any affected user. If the user has been removed from the member list, the service MUST change the user's affiliation from "member" to "none". If the user has been added to the member list, the service MUST change the user's affiliation to "member".
+
'''例子 123. 服务发送失去成员资格的通知给所有房客'''
 
+
 
+
 
+
If a removed member is currently in a members-only room, the service SHOULD kick the occupant by changing the removed member's role to "none" and send appropriate presence to the removed member as previously described. No matter whether the removed member was in or out of a members-only room, the service MUST subsequently refuse entry to the user.
+
 
+
 
+
 
+
For all room types, the service MUST send updated presence from this individual to all occupants, indicating the change in affiliation by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "none".
+
 
+
 
+
 
+
Example 115. Service Sends Notice of Loss of Membership to All Occupants
+
 
+
 
+
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 
+
</source>
.
+
 
+
.
+
 
+
   
+
 
+
 
+
 
+
In addition, the service SHOULD send an invitation to any user who has been added to the member list of a members-only room if the user is not currently affiliated with the room, for example as an admin or owner (such a user would by definition not be in the room; note also that this example includes a password but not a reason -- both child elements are OPTIONAL):
+
 
+
 
+
 
+
Example 116. Room Sends Invitation to New Member
+
  
 +
另外, 服务必须 SHOULD 发送一个邀请给任何已加入到仅限会员的房间里的成员名单中的用户,如果该用户目前在该房间还没有岗位, 例如作为一个管理员或所有者(这类用户在定义时不在房间里; 同时要注意这个例子里使用了一个密码password而不是原因reason -- 这两个子元素都是可选的 OPTIONAL):
  
 +
'''例子 124. 房间发送邀请给新成员'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hecate@shakespeare.lit'>
 
     to='hecate@shakespeare.lit'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite from='bard@shakespeare.lit'/>
 
     <invite from='bard@shakespeare.lit'/>
 
 
     <password>cauldronburn</password>
 
     <password>cauldronburn</password>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
因为只有管理员们和所有者们应该 SHOULD 被允许修改成员列表, 一个实现可以 MAY 提供一个配置选项,在仅限会员的房间里开放邀请权限给任何成员. 这种情况下, 任何被发送的邀请都应该 SHOULD 自动触发被邀请者加入成员列表. 无论如何, 如果邀请权限被限于管理员们,而普通成员尝试发送邀请, 服务必须 MUST 拒绝这个邀请的的请求并返回一个 <forbidden/> 错误给发送者:
 
+
 
+
 
+
While only admins and owners SHOULD be allowed to modify the member list, an implementation MAY provide a configuration option that opens invitation privileges to any member of a members-only room. In such a situation, any invitation sent SHOULD automatically trigger the addition of the invitee to the member list. However, if invitation privileges are restricted to admins and a mere member attempts to a send an invitation, the service MUST deny the invitation request and return a <forbidden/> error to the sender:
+
 
+
 
+
 
+
Example 117. Service Returns Error on Attempt by Mere Member to Invite Others to a Members-Only Room
+
 
+
  
 +
'''例子 125. 服务在普通成员尝试邀请其他人加入仅限会员的房间时返回错误'''
  
 +
<source lang="xml">
 
<message
 
<message
 
+
     from='darkcave@chat.shakespeare.lit'
     from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite to='hecate@shakespeare.lit'>
 
     <invite to='hecate@shakespeare.lit'>
 
 
       <reason>
 
       <reason>
 
 
         Hey Hecate, this is the place for all good witches!
 
         Hey Hecate, this is the place for all good witches!
 
 
       </reason>
 
       </reason>
 
 
     </invite>
 
     </invite>
 
 
   </x>
 
   </x>
 
+
   <error type='auth'>
   <error code='403' type='auth'>
+
 
+
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</message>
 
</message>
 +
</source>
  
   
+
从开放房间发送的邀请不能 MUST NOT 触发被邀请者加入成员列表.
 
+
 
+
 
+
Invitations sent through an open room MUST NOT trigger the addition of the invitee to the member list.
+
 
+
 
+
 
+
If a user is added to the member list of an open room and the user is in the room, the service MUST send updated presence from this individual to all occupants, indicating the change in affiliation by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "member".
+
 
+
 
+
 
+
Example 118. Service Sends Notice of Membership to All Occupants
+
  
 +
如果一个用户被加入一个开放房间的成员列表并且该用户在该房间内, 服务必须 MUST 以该用户的名义发送更新的出席信息给所有房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'affiliation'属性值设为"member",以指明这个岗位的变更.
  
 +
'''例子 126. 服务发送成员资格通知给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/hecate'
     from='darkcave@macbeth.shakespeare.lit/hecate'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hecate@shakespeare.lit/broom'
 
           jid='hecate@shakespeare.lit/broom'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
===授予主持人权限===
 
+
.
+
 
+
   
+
 
+
 
+
 
+
9.6 Granting Moderator Privileges
+
 
+
 
+
 
+
An admin may want to grant moderator privileges to a participant or visitor; this is done by changing the user's role to "moderator":
+
 
+
 
+
 
+
Example 119. Admin Grants Moderator Privileges
+
  
 +
管理员可能想授予主持人权限给一个与会者或游客; 通过把用户的角色改为 "moderator":
  
 +
'''例子 127. 管理员授予主持人权限'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='mod1'
 
     id='mod1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='thirdwitch'
 
     <item nick='thirdwitch'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/> 元素是可选的 OPTIONAL.
  
 +
'''例子 128. 管理员授予主持人权限(包含一个原因Reason)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='mod1'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item nick='thirdwitch'
 +
          role='moderator'>
 +
      <reason>A worthy witch indeed!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST add the user to the moderator list and then inform the admin of success:
+
服务必须 MUST 添加这个用户到主持人列表然后通知管理员成功了:
  
 +
'''例子 129. 服务通知管理员成功了'''
  
 
+
<source lang="xml">
Example 120. Service Informs Admin of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='mod1'
 
     id='mod1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 接着以该用户的名义发送更新的出席信息给所有的房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'role'属性值设为"moderator",以指明添加了主持人权限.
 
+
 
+
 
+
The service MUST then send updated presence from this individual to all occupants, indicating the addition of moderator privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'role' attribute set to a value of "moderator".
+
 
+
 
+
 
+
Example 121. Service Sends Notice of Moderator Privileges to All Occupants
+
 
+
  
 +
'''例子 130. 服务发送主持人权限通知给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
===撤销主持人权限===
 
+
.
+
 
+
   
+
 
+
 
+
 
+
9.7 Revoking Moderator Privileges
+
 
+
 
+
 
+
An admin may want to revoke a user's moderator privileges. An admin MAY revoke moderator privileges only from a user whose affiliation is "member" or "none" (i.e., not from an owner or admin). The privilege is revoked by changing the user's role to "participant":
+
 
+
 
+
 
+
Example 122. Admin Revokes Moderator Privileges
+
  
 +
管理员可能想撤销用户的主持人权限. 一个管理员只可以 MAY 撤销岗位为"member" 或 "none" (也就是, 非管理员和所有者)的用户的主持人权限. 权限的撤销是通过把用户的角色改为 "participant"实现的:
  
 +
'''例子 131. 管理员撤销主持人权限'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='mod2'
 
     id='mod2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='thirdwitch'
 
     <item nick='thirdwitch'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/> 元素是可选的 OPTIONAL.
  
 +
'''例子 132. 管理员撤销主持人权限(包含一个原因Reason)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='mod2'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item nick='thirdwitch'
 +
          role='participant'>
 +
      <reason>Not so worthy after all!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST remove the user from the moderator list and then inform the admin of success:
+
服务必须 MUST 从主持人列表移除这个用户然后通知管理员成功了:  
  
 +
'''例子 133. 服务通知管理员成功了'''
  
 
+
<source lang="xml">
Example 123. Service Informs Admin of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='mod2'
 
     id='mod2'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 接着以该用户的名义发送更新的出席信息给所有的房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'role'属性值设为"participant",以指明移除了主持人权限.  
 
+
 
+
 
+
The service MUST then send updated presence from this individual to all occupants, indicating the removal of moderator privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'role' attribute set to a value of "participant".
+
 
+
 
+
 
+
Example 124. Service Notes Loss of Moderator Privileges
+
 
+
  
 +
'''例子 134. 服务通知失去了主持人权限'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
大家知道, 管理员不 MUST NOT 被允许从岗位为 "owner" 或 "admin"的用户撤销主持人权限. 如果一个管理员尝试撤销这类用户的权限, 服务必须MUST 拒绝这个请求并返回一个 <not-allowed/> 错误给发送者:
  
.
+
'''例子 135. 服务在用户尝试撤销管理员或所有者的主持人权限时返回错误'''
 
+
   
+
 
+
 
+
 
+
As noted, an admin MUST NOT be allowed to revoke moderator privileges from a user whose affiliation is "owner" or "admin". If an admin attempts to revoke moderator privileges from such a user, the service MUST deny the request and return a <not-allowed/> error to the sender:
+
 
+
 
+
 
+
Example 125. Service Returns Error on Attempt to Revoke Moderator Privileges from an Admin or Owner
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
  
 +
<source lang="xml">
 +
<iq from='darkcave@chat.shakespeare.lit'
 
     id='modtest'
 
     id='modtest'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='secondwitch' role='participant'/>
 
     <item nick='secondwitch' role='participant'/>
 
 
   </query>
 
   </query>
 
+
   <error type='cancel'>
   <error code='405' type='cancel'>
+
 
+
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
===修改主持人列表===
 
+
 
+
 
+
9.8 Modifying the Moderator List
+
 
+
 
+
 
+
An admin may want to modify the moderator list. To do so, the admin first requests the moderator list by querying the room for all users with a role of 'moderator'.
+
 
+
 
+
 
+
Example 126. Admin Requests Moderator List
+
  
 +
管理员可能希望修改主持人列表. 为此, 管理员首先通过请求房间内所有角色为'moderator'的用户来请求主持人列表.
  
 +
'''例子 136. 管理员请求主持人列表'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='mod3'
 
     id='mod3'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item role='moderator'/>
 
     <item role='moderator'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 接着返回主持人列表给管理员; 每个条目必须 MUST 包含 'jid', 'nick', 'role' 属性并应该 SHOULD 包含 'affiliation' 属性:
  
 +
'''例子 137. 服务发送主持人列表给管理员'''
  
 
+
<source lang="xml">
The service MUST then return the moderator list to the admin; each item MUST include the 'jid', 'nick', and 'role' attributes and SHOULD include the 'affiliation' attribute:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 127. Service Sends Moderator List to Admin
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='mod3'
 
     id='mod3'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='hag66@shakespeare.lit/pda'
 
           jid='hag66@shakespeare.lit/pda'
 
 
           nick='thirdwitch'
 
           nick='thirdwitch'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
管理员可以 MAY 接着修改主持人列表. 为此, 管理员必须 MUST发送修改的条目(, "delta") 给服务; 每个条目必须 MUST 包含 'jid' 属性和'role' 属性(通常值设为 "member" "participant") 但不应该 SHOULD NOT 包含 'nick' 属性并且不能 MUST NOT 包含 'affiliation' 属性(它被用于管理类似管理员这样的岗位而不是主持人这样的角色):
 
+
 
+
 
+
The admin MAY then modify the moderator list. In order to do so, the admin MUST send the changed items (i.e., only the "delta") back to the service; each item MUST include the 'jid' attribute and 'role' attribute (normally set to a value of "member" or "participant") but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'affiliation' attribute (which is used to manage affiliations such as admin rather than the moderator role):
+
 
+
 
+
 
+
Example 128. Admin Sends Modified Moderator List to Service
+
 
+
  
 +
'''例子 138. 管理员发送修改了的主持人列表给服务'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='mod4'
 
     id='mod4'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item jid='hag66@shakespeare.lit/pda'
 
     <item jid='hag66@shakespeare.lit/pda'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
     <item jid='hecate@shakespeare.lit/broom'
 
     <item jid='hecate@shakespeare.lit/broom'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务必须 MUST 修改主持人列表并通知管理员成功了:
  
 +
'''例子 139. 服务通知管理员成功了'''
  
 
+
<source lang="xml">
The service MUST modify the moderator list and then inform the admin of success:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 129. Service Informs Admin of Success
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='mod4'
 
     id='mod4'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 随后以所有受影响的用户发送更新的出席信息给所有的房客, 支出主持人权限的变更,通过发送前面用例所述的适当的扩展出席信息.
  
 +
显然, 房间所有者或房间管理员的主持人权限不能被撤销. 如果一个房间管理员尝试通过修改主持人列表来撤销这类用户的主持人权限, 服务必须 MUST 拒绝请求并返回一个 <not-allowed/> 错误给发送者:
  
 +
'''例子 140. 服务在用户尝试撤销管理员或所有者的主持人权限时返回错误'''
  
The service MUST then send updated presence for any affected individuals to all occupants, indicating the change in moderator privileges by sending the appropriate extended presence stanzas as described in the foregoing use cases.
+
<source lang="xml">
 
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
As noted, moderator privileges cannot be revoked from a room owner or room admin. If a room admin attempts to revoke moderator privileges from such a user by modifying the moderator list, the service MUST deny the request and return a <not-allowed/> error to the sender:
+
 
+
 
+
 
+
Example 130. Service Returns Error on Attempt to Revoke Moderator Privileges from an Admin or Owner
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='modtest'
 
     id='modtest'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item jid='hecate@shakespeare.lit/broom'
 
     <item jid='hecate@shakespeare.lit/broom'
 
 
           nick='Hecate'
 
           nick='Hecate'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </query>
 
   </query>
 
+
   <error type='cancel'>
   <error code='405' type='cancel'>
+
 
+
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
===批准注册申请===
  
 +
如果一个服务不自动接受注册到房间的请求, 它可以 MAY 为房间管理员提供一个方法来批准或拒绝来自 Jabber 的注册请求(替代方案是, 它可能提供一个 web 接口或一些其他管理工具). 对这个服务来说,最简单的办法就是,当接收到注册请求时发送一个 <message/> 节给房间管理员(们), 这里的<message/> 节包含一个数据表格 Data Form asking 用来询问管理员是否批准用户的注册申请. 推荐 RECOMMENDED 以下数据表格 Data Form,但是实现可以 MAY 使用完全不同的表格, 或or 在下面的表格基础上补充字段.
  
 +
'''例子 141. 注册申请批准表格'''
  
9.9 Approving Registration Requests
+
<source lang="xml">
 
+
<message from='darkcave@chat.shakespeare.lit'
 
+
 
+
If a service does not automatically accept requests to register with a room, it MAY provide a way for room admins to approve or deny registration requests over Jabber (alternatively, it could provide a web interface or some other admin tool). The simplest way to do so is for the service to send a <message/> stanza to the room admin(s) when the registration request is received, where the <message/> stanza contains a Data Form asking for approval or denial of the request. The following Data Form is RECOMMENDED but implementations MAY use a different form entirely, or supplement the following form with additional fields.
+
 
+
 
+
 
+
Example 131. Registration Request Approval Form
+
 
+
 
+
 
+
<message from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
         id='approve'
 
         id='approve'
 
 
         to='crone1@shakespeare.lit/pda'>
 
         to='crone1@shakespeare.lit/pda'>
 
 
   <x xmlns='jabber:x:data' type='form'>
 
   <x xmlns='jabber:x:data' type='form'>
 
 
     <title>Registration request</title>
 
     <title>Registration request</title>
 
 
     <instructions>
 
     <instructions>
 
 
       To approve this registration request, select the
 
       To approve this registration request, select the
 
 
       &quot;Allow this person to register with the room?&quot;
 
       &quot;Allow this person to register with the room?&quot;
 
 
       checkbox and click OK. To skip this request, click the  
 
       checkbox and click OK. To skip this request, click the  
 
 
       cancel button.
 
       cancel button.
 
 
     </instructions>
 
     </instructions>
 
 
     <field var='FORM_TYPE' type='hidden'>
 
     <field var='FORM_TYPE' type='hidden'>
 
 
         <value>http://jabber.org/protocol/muc#register</value>
 
         <value>http://jabber.org/protocol/muc#register</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#register_first'
 
     <field var='muc#register_first'
 
 
           type='text-single'
 
           type='text-single'
 
+
           label='Given Name'>
           label='First Name'>
+
 
+
 
       <value>Brunhilde</value>
 
       <value>Brunhilde</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#register_last'
 
     <field var='muc#register_last'
 
 
           type="text-single"
 
           type="text-single"
 
+
           label="Family Name">
           label="Last Name">
+
 
+
 
       <value>Entwhistle-Throckmorton</value>
 
       <value>Entwhistle-Throckmorton</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#register_roomnick'
 
     <field var='muc#register_roomnick'
 
 
           type="text-single"
 
           type="text-single"
 
 
           label="Desired Nickname">
 
           label="Desired Nickname">
 
 
       <value>thirdwitch</value>
 
       <value>thirdwitch</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#register_url'
 
     <field var='muc#register_url'
 
 
           type="text-single"
 
           type="text-single"
 
 
           label="User URL">
 
           label="User URL">
 
 
       <value>http://witchesonline/~hag66/</value>
 
       <value>http://witchesonline/~hag66/</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#register_email'
 
     <field var='muc#register_email'
 
 
           type="text-single"
 
           type="text-single"
 
 
           label="Email Address">
 
           label="Email Address">
 
 
       <value>hag66@witchesonline</value>
 
       <value>hag66@witchesonline</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#register_faqentry'
 
     <field var='muc#register_faqentry'
 
 
           type="text-single"
 
           type="text-single"
 
 
           label="FAQ Entry">
 
           label="FAQ Entry">
 
 
       <value>Just another witch.</value>
 
       <value>Just another witch.</value>
 
 
     </field>
 
     </field>
 
 
     <field var='muc#register_allow'
 
     <field var='muc#register_allow'
 
 
           type='boolean'
 
           type='boolean'
 
 
           label='Allow this person to register with the room?'>
 
           label='Allow this person to register with the room?'>
 
 
       <value>0</value>
 
       <value>0</value>
 
 
     </field>
 
     </field>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
   
+
如果管理员批准了注册申请, 服务将把该用户注册到房间.
  
 +
更多高级的批准机制(例如, 使用特定命令[http://xmpp.org/extensions/xep-0050.html Ad-Hoc Commands] [[XEP-0045#附录G:备注|19]]来接收注册申请列表,就像 [http://xmpp.org/extensions/xep-0060.html Publish-Subscribe] [[XEP-0045#附录G:备注|20]]里所做的一样) 超出了本文的范围.
  
 +
==所有者用例==
  
If the admin approves the registration request, the service shall register the user with the room.
+
每个房间必须 MUST 至少有一个所有者, 而所有者(或一个成功者)在一个房间的生命周期里是这个房间长期存在的属性(例如, 所有者在退出一个持久性的房间时不会失去所有权). 本文假定(初始的) 房间所有者是那个新建了该房间的用户并且有一个房间所有者有权修改房间配置选项的定义,例如房间类型. 理想情况下, 房间所有者不仅能指定房间类型(密码保护的, 仅限会员的, 等等) 而且包括如本文的 [XEP-0045#需求|需求]章节所述的房间特定属性. 另外, 如果所有者能指定其他所有者们的JID也是不错的, 但那将取决于具体实现.
  
 +
为了让配置选项更加广泛提供必要的伸缩性, 房间配置将使用 Data Forms ('''XEP-0004'''), 通过使用由 'http://jabber.org/protocol/muc' 名字空间触发. 也就是, 如果一个实体在它请求加入房间的 join/request 里不包含 MUC 名字空间, 那么服务将立刻新建房间,在新建房间之前不等待通过数据表格进行配置(这保证了和旧的"groupchat 1.0"协议的向后兼容); 无论如何, 如果房间的 join/create 请求包含了 MUC 扩展, 那么服务在新建和解锁该房间之前将通过数据表格请求配置.
  
 +
注意: 以下展示的配置选项列出了本文的需求章节的所有特性和房间类型; 无论如何, 实际的配置选项和表格布局将取决于实现和具体的布署. 而且, 这些只是例子,不代表这些就是房间可以拥有的所有允许或需要的配置选项. 一个特定的实现或布署可以 MAY 选择提供额外的配置选项(敏感词过滤, 设置房间的缺省语言, 消息记录, 等等), 这就是为什么在这里使用 'jabber:x:data' 协议是很有价值的.
  
More advanced registration approval mechanisms (e.g., retrieving a list of registration requests using Ad-Hoc Commands [18] as is done in Publish-Subscribe [19]) are out of scope for this document.
+
===新建房间===
 
+
====一般注意事项====
10. Owner Use Cases
+
 
+
 
+
 
+
Every room MUST have at least one owner, and that owner (or a successor) is a long-lived attribute of the room for as long as the room exists (e.g., the owner does not lose ownership on exiting a persistent room). This document assumes that the (initial) room owner is the individual who creates the room and that only a room owner has the right to change defining room configuration settings such as the room type. Ideally, room owners will be able to specify not only the room types (password-protected, members-only, etc.) but also certain attributes of the room as listed in the Requirements section of this document. In addition, it would be good if an owner were able to specify the JIDs of other owners, but that shall be determined by the implementation.
+
 
+
 
+
 
+
In order to provide the necessary flexibility for a wide range of configuration options, Data Forms (XEP-0004) shall be used for room configuration, triggered by use of the 'http://jabber.org/protocol/muc' namespace. That is, if an entity does not include the MUC namespace in its room join/create request, then the service shall create the room and not wait for configuration via Data Forms before creating the room (this ensures backwards-compatibility with the old "groupchat 1.0" protocol); however, if the room join/create request includes the MUC extension, then the service shall require configuration via Data Forms before creating and unlocking the room.
+
 
+
 
+
 
+
Note: The configuration options shown below address all of the features and room types listed in the requirements section of this document; however, the exact configuration options and form layout shall be determined by the implementation or specific deployment. Also, these are examples only and are not intended to define the only allowed or required configuration options for rooms. A given implementation or deployment MAY choose to provide additional configuration options (profanity filters, setting the default language for a room, message logging, etc.), which is why the use of the 'jabber:x:data' protocol is valuable here.
+
 
+
10.1 Creating a Room
+
 
+
10.1.1 General Considerations
+
 
+
 
+
 
+
The privilege to create rooms MAY be restricted to certain users or MAY be reserved to an administrator of the service. If access is restricted and a user attempts to create a room, the service MUST return a <not-allowed/> error:
+
 
+
 
+
 
+
Example 132. Service Informs User of Inability to Create a Room
+
  
 +
新建房间的权限可以 MAY 限制在特定的用户群或可以 MAY 保留给一个服务级别的管理员. 如果访问被拒绝而一个用户试图新建一个房间, 服务必须MUST 返回一个 <not-allowed/> 错误:
  
 +
'''例子 142. 服务通知用户不能新建房间'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/thirdwitch'
     from='darkcave@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
+
   <x xmlns='http://jabber.org/protocol/muc'/>
   <error code='405' type='cancel'>
+
  <error type='cancel'>
 
+
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
如果访问不限制, 服务必须 MUST 允许用户按以下步骤新建房间.
  
 +
从房间创建的视角来看, 本质上有两种房间:
  
 +
* 即时房间"Instant rooms" -- 可以立刻访问并基于某些缺省配置自动创建.
 +
* 保留房间"Reserved rooms" -- 在任何人访问之前由房间配置者手动创建.
  
If access is not restricted, the service MUST allow the user to create a room as described below.
+
新建和配置这些房间的流程如下:
  
 +
# 用户必须 MUST 发送出席信息到 <room@service/nick> 并声明他或她对MUC协议的支持,通过包含一个扩展的出席信息,并包含在一个空的满足'http://jabber.org/protocol/muc'名字空间的 <x/> 子元素里(注意这里不包含 '#owner' 或 '#user' 后缀).
 +
# 如果用户被允许新建房间并且房间还不存在, 服务必须 MUST 根据一些缺省配置新建此房间, 指定请求的用户成为初始的房间拥有者, 并增加这个拥有者到该房间但不允许任何别的用户进入该房间(有效地锁定 "locking"该房间). 从房间发送由所有者收到的初始的出席信息节必须 MUST 包含扩展的出席信息以指出该用户的状态为一个所有者并承认房间已经被创建了(通过状态码 201) 并等待配置.
 +
# 如果初始的房间所有者想新建和配置一个保留房间, 房间所有者必须 MUST 接着请求一个配置,通过发送类型为"get"的IQ节并包含一个空的满足'http://jabber.org/protocol/muc#owner'名字空间的<query/>元素给该房间 ,然后完成第4和第5步. 如果房间所有者喜欢新建一个即时房间, 该房间所有者必须 MUST 发送一个遵循'http://jabber.org/protocol/muc#owner'名字空间的 query 元素并包含一个遵循 'jabber:x:data' 名字空间的空的类型为 "submit" 的 <x/> 元素, 然后跳到第6步.
 +
# 如果房间所有者请求了一个配置表格, 服务必须 MUST 发送一个包含配置表格并遵循 'jabber:x:data'名字空间的 IQ 给房间拥有者. 如果没有配置选项可用, 房间必须 MUST 返回一个空的 query 元素给房间所有者.
 +
# 初始的房间所有者应该 SHOULD 为该房间提供一个开始的配置(或接受缺省配置),通过发送"set"类型并包含完整的配置表格的 IQ . 另外, 房间所有者可以 MAY 取消配置过程. (实现可以 MAY 设置一个初始化配置的超时, 这样如果房间所有者再给定的超时时间内不配置房间, 房间所有者就被假定已经接受了缺省得配置或取消了配置过程.)
 +
# 一旦服务从初始房间所有者接收了完整的配置表格(或接收到了一个即时房间的请求), 服务必须 MUST 解锁 "unlock" 这个房间 (即, 允许其他用户进入此房间) 并发送"result"类型的 IQ  给房间所有者. 如果服务接收到了取消(指令), 它必须 MUST 销毁这个房间.
  
 +
以下例子展示了这个协议流程.
  
From the perspective of room creation, there are in essence two kinds of rooms:
+
首先, Jabber用户必须 MUST 发送出席信息给房间, 包含空的 <x/> 元素,遵循 'http://jabber.org/protocol/muc' 名字空间(当他寻求进入一个房间时也发送和这同样的节).
 
+
 
+
 
+
    *
+
 
+
 
+
 
+
      "Instant rooms" -- these are available for immediate access and are automatically created based on some default configuration.
+
 
+
    *
+
 
+
 
+
 
+
      "Reserved rooms" -- these are manually configured by the room creator before anyone is allowed to enter.
+
 
+
 
+
 
+
The workflow for creating and configuring such rooms is as follows:
+
 
+
 
+
 
+
  1.
+
 
+
 
+
 
+
      The user MUST send presence to <room@service/nick> and signal his or her support for the Multi-User Chat protocol by including extended presence information in an empty <x/> child element qualified by the 'http://jabber.org/protocol/muc' namespace (note the lack of an '#owner' or '#user' fragment).
+
 
+
  2.
+
 
+
 
+
 
+
      If this user is allowed to create a room and the room does not yet exist, the service MUST create the room according to some default configuration, assign the requesting user as the initial room owner, and add the owner to the room but not allow anyone else to enter the room (effectively "locking" the room). The initial presence stanza received by the owner from the room MUST include extended presence information indicating the user's status as an owner and acknowledging that the room has been created (via status code 201) and is awaiting configuration.
+
 
+
  3.
+
 
+
 
+
 
+
      If the initial room owner would like to create and configure a reserved room, the room owner MUST then request a configuration form by sending an IQ stanza of type "get" to the room containing an empty <query/> element qualified by the 'http://jabber.org/protocol/muc#owner' namespace, then complete Steps 4 and 5. If the room owner would prefer to create an instant room, the room owner MUST send a query element qualified by the 'http://jabber.org/protocol/muc#owner' namespace and containing an empty <x/> element of type "submit" qualified by the 'jabber:x:data' namespace, then skip to Step 6.
+
 
+
  4.
+
 
+
 
+
 
+
      If the room owner requested a configuration form, the service MUST send an IQ to the room owner containing a configuration form qualified by the 'jabber:x:data' namespace. If there are no configuration options available, the room MUST return an empty query element to the room owner.
+
 
+
  5.
+
 
+
 
+
 
+
      The initial room owner SHOULD provide a starting configuration for the room (or accept the default configuration) by sending an IQ of type "set" containing the completed configuration form. Alternatively, the room owner MAY cancel the configuration process. (An implementation MAY set a timeout for initial configuration, such that if the room owner does not configure the room within the timeout period, the room owner is assumed to have accepted the default configuration or to have cancelled the configuration process.)
+
 
+
  6.
+
 
+
 
+
 
+
      Once the service receives the completed configuration form from the initial room owner (or receives a request for an instant room), the service MUST "unlock" the room (i.e., allow other users to enter the room) and send an IQ of type "result" to the room owner. If the service receives a cancellation, it MUST destroy the room.
+
 
+
 
+
 
+
The protocol for this workflow is shown in the examples below.
+
 
+
 
+
 
+
First, the Jabber user MUST send presence to the room, including an empty <x/> element qualified by the 'http://jabber.org/protocol/muc' namespace (this is the same stanza sent when seeking to enter a room).
+
 
+
 
+
 
+
Example 133. Jabber User Creates a Room and Signals Support for Multi-User Chat
+
 
+
  
 +
'''例子 143. Jabber用户新建一个房间并声明对多用户聊天的支持'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     to='darkcave@chat.shakespeare.lit/firstwitch'>
     to='darkcave@macbeth.shakespeare.lit/firstwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
如果该房间不存在, 服务应该 SHOULD 新建这个房间(取决于关于新建房间的本地策略), 指定发出请求的用户的纯JID成为所有者, 添加这个所有者到房间, 并通过发送以下格式的出席信息节承认房间新建成功:
 
+
 
+
 
+
If the room does not yet exist, the service SHOULD create the room (subject to local policies regarding room creation), assign the bare JID of the requesting user as the owner, add the owner to the room, and acknowledge successful creation of the room by sending a presence stanza of the following form:
+
 
+
 
+
 
+
Example 134. Service Acknowledges Room Creation
+
 
+
  
 +
'''例子 144. 服务承认房间新建成功'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/firstwitch'
     from='darkcave@macbeth.shakespeare.lit/firstwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='owner'
 
     <item affiliation='owner'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
+
    <status code='110'/>
 
     <status code='201'/>
 
     <status code='201'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
接收到该房间已经创建的通知之后, 房间所有者需要决定是否接受缺省的房间配置(即, 新建一个即时房间 "instant room") 还是做一些不同于缺省房间设置的配置 (即, 新建一个保留房间"reserved room"). 完成这两个用例的协议流程展示如下.
  
 +
注意: 如果如上的发送到一个不存在的房间里的出席信息节没有包含一个遵循 'http://jabber.org/protocol/muc'名字空间的 <x/> 元素, 服务应该SHOULD 立刻新建一个缺省的房间(即, 它必须 MUST 假定客户端支持 "groupchat 1.0" 而不是 Multi-User Chat, 所以在等待房间创建者决定是创建即时房间还是保留房间的时候,它不能 MUST NOT 锁定这个房间).
  
 +
====新建即时房间====
  
After receiving notification that the room has been created, the room owner needs to decide whether to accept the default room configuration (i.e., create an "instant room") or configure the room to have something other than the default room configuration (i.e., create a "reserved room"). The protocol flows for completing those two use cases are shown in the following sections.
+
如果初始的房间所有者想接受缺省的房间配置(, 新建一个即时房间"instant room"), 房间所有者必须 MUST 拒绝初始配置表格,通过发送一个 IQ set <room@service> 本身,包含一个遵循'http://jabber.org/protocol/muc#owner'名字空间的 <query/> 元素, 这里 <query/> 的唯一子元素是一个空的遵循'jabber:x:data'名字空间的 <x/> 元素并且拥有一个 'type'属性值为 "submit":
 
+
 
+
 
+
Note: If the presence stanza sent to a nonexistent room does not include an <x/> element qualified by the 'http://jabber.org/protocol/muc' namespace as shown above, the service SHOULD create a default room without delay (i.e., it MUST assume that the client supports "groupchat 1.0" rather than Multi-User Chat and therefore it MUST NOT lock the room while waiting for the room creator to either accept an instant room or configure a reserved room).
+
 
+
10.1.2 Creating an Instant Room
+
 
+
 
+
 
+
If the initial room owner wants to accept the default room configuration (i.e., create an "instant room"), the room owner MUST decline an initial configuration form by sending an IQ set to the <room@service> itself containing a <query/> element qualified by the 'http://jabber.org/protocol/muc#owner' namespace, where the only child of the <query/> is an empty <x/> element that is qualified by the 'jabber:x:data' namespace and that possesses a 'type' attribute whose value is "submit":
+
 
+
 
+
 
+
Example 135. Owner Requests Instant Room
+
 
+
  
 +
'''例子 145. 所有者请求即时房间'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='create1'
 
     id='create1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
 
     <x xmlns='jabber:x:data' type='submit'/>
 
     <x xmlns='jabber:x:data' type='submit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
服务必须 MUST 接着解锁该房间并允许其他实体加入它.
  
 +
====新建保留房间====
  
 +
如果初始的房间所有者想新建并配置一个保留房间, 这个房间所有者必须 MUST 请求初始配置表格,通过发送一个 IQ get 给 <room@service> 本身,包含一个空的遵循 'http://jabber.org/protocol/muc#owner' 名字空间的 <query/> 元素 :
  
The service MUST then unlock the room and allow other entities to join it.
+
'''例子 146. 所有者请求配置表单'''
 
+
10.1.3 Creating a Reserved Room
+
 
+
 
+
 
+
If the initial room owner wants to create and configure a reserved room, the room owner MUST request an initial configuration form by sending an IQ get to the <room@service> itself containing an empty <query/> element qualified by the 'http://jabber.org/protocol/muc#owner' namespace:
+
 
+
 
+
 
+
Example 136. Owner Requests Configuration Form
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='create1'
 
     id='create1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
如果房间还不存在, 服务必须 MUST 返回一个初始的房间配置表单给该用户. (注意: 以下例子展示一个配置选项的典型例子. 已登记用于房间创建和配置的所有 x:data 字段列表由 XMPP Registrar 维护; 参见本文的 [[XEP-0045#XMPP注册项事项|XMPP注册项事项]] 章节.)
  
 +
'''例子 147. 服务发送配置表单'''
  
 
+
<source lang="xml">
If the room does not already exist, the service MUST return an initial room configuration form to the user. (Note: The following example shows a representative sample of configuration options. A full list of x:data fields registered for use in room creation and configuration is maintained by the XMPP Registrar; see the XMPP Registrar Considerations section of this document.)
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 137. Service Sends Configuration Form
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='create1'
 
     id='create1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
 
     <x xmlns='jabber:x:data' type='form'>
 
     <x xmlns='jabber:x:data' type='form'>
 
 
       <title>Configuration for "darkcave" Room</title>
 
       <title>Configuration for "darkcave" Room</title>
 
 
       <instructions>
 
       <instructions>
 
 
           Your room darkcave@macbeth has been created!
 
           Your room darkcave@macbeth has been created!
 
 
           The default configuration is as follows:
 
           The default configuration is as follows:
 
 
             - No logging
 
             - No logging
 
 
             - No moderation
 
             - No moderation
 
 
             - Up to 20 occupants
 
             - Up to 20 occupants
 
 
             - No password required
 
             - No password required
 
 
             - No invitation required
 
             - No invitation required
 
 
             - Room is not persistent
 
             - Room is not persistent
 
 
             - Only admins may change the subject
 
             - Only admins may change the subject
 
 
             - Presence broadcasted for all users
 
             - Presence broadcasted for all users
 
 
           To accept the default configuration, click OK. To
 
           To accept the default configuration, click OK. To
 
 
           select a different configuration, please complete
 
           select a different configuration, please complete
 
 
           this form.
 
           this form.
 
 
       </instructions>
 
       </instructions>
 
 
       <field
 
       <field
 
 
           type='hidden'
 
           type='hidden'
 
 
           var='FORM_TYPE'>
 
           var='FORM_TYPE'>
 
 
         <value>http://jabber.org/protocol/muc#roomconfig</value>
 
         <value>http://jabber.org/protocol/muc#roomconfig</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Natural-Language Room Name'
 
           label='Natural-Language Room Name'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#roomconfig_roomname'/>
 
           var='muc#roomconfig_roomname'/>
 
 
       <field
 
       <field
 
 
           label='Short Description of Room'
 
           label='Short Description of Room'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#roomconfig_roomdesc'/>
 
           var='muc#roomconfig_roomdesc'/>
 
 
       <field
 
       <field
 
 
           label='Natural Language for Room Discussions'
 
           label='Natural Language for Room Discussions'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#roomconfig_lang'/>
 
           var='muc#roomconfig_lang'/>
 
 
       <field
 
       <field
 
 
           label='Enable Public Logging?'
 
           label='Enable Public Logging?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_enablelogging'>
 
           var='muc#roomconfig_enablelogging'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Allow Occupants to Change Subject?'
 
           label='Allow Occupants to Change Subject?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_changesubject'>
 
           var='muc#roomconfig_changesubject'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Allow Occupants to Invite Others?'
 
           label='Allow Occupants to Invite Others?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_allowinvites'>
 
           var='muc#roomconfig_allowinvites'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Maximum Number of Occupants'
 
           label='Maximum Number of Occupants'
 
 
           type='list-single'
 
           type='list-single'
 
 
           var='muc#roomconfig_maxusers'>
 
           var='muc#roomconfig_maxusers'>
 
 
         <value>20</value>
 
         <value>20</value>
 
 
         <option label='10'><value>10</value></option>
 
         <option label='10'><value>10</value></option>
 
 
         <option label='20'><value>20</value></option>
 
         <option label='20'><value>20</value></option>
 
 
         <option label='30'><value>30</value></option>
 
         <option label='30'><value>30</value></option>
 
 
         <option label='50'><value>50</value></option>
 
         <option label='50'><value>50</value></option>
 
 
         <option label='100'><value>100</value></option>
 
         <option label='100'><value>100</value></option>
 
 
         <option label='None'><value>none</value></option>
 
         <option label='None'><value>none</value></option>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Roles for which Presence is Broadcast'
 
           label='Roles for which Presence is Broadcast'
 
 
           type='list-multi'
 
           type='list-multi'
 
 
           var='muc#roomconfig_presencebroadcast'>
 
           var='muc#roomconfig_presencebroadcast'>
 
 
         <value>moderator</value>
 
         <value>moderator</value>
 
 
         <value>participant</value>
 
         <value>participant</value>
 
 
         <value>visitor</value>
 
         <value>visitor</value>
 
 
         <option label='Moderator'><value>moderator</value></option>
 
         <option label='Moderator'><value>moderator</value></option>
 
 
         <option label='Participant'><value>participant</value></option>
 
         <option label='Participant'><value>participant</value></option>
 
 
         <option label='Visitor'><value>visitor</value></option>
 
         <option label='Visitor'><value>visitor</value></option>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
+
          label='Roles and Affiliations that May Retrieve Member List'
 +
          type='list-multi'
 +
          var='muc#roomconfig_getmemberlist'>
 +
        <value>moderator</value>
 +
        <value>participant</value>
 +
        <value>visitor</value>
 +
        <option label='Moderator'><value>moderator</value></option>
 +
        <option label='Participant'><value>participant</value></option>
 +
        <option label='Visitor'><value>visitor</value></option>
 +
      </field>
 +
      <field
 
           label='Make Room Publicly Searchable?'
 
           label='Make Room Publicly Searchable?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_publicroom'>
 
           var='muc#roomconfig_publicroom'>
 
 
         <value>1</value>
 
         <value>1</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Make Room Persistent?'
 
           label='Make Room Persistent?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_persistentroom'>
 
           var='muc#roomconfig_persistentroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Make Room Moderated?'
 
           label='Make Room Moderated?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_moderatedroom'>
 
           var='muc#roomconfig_moderatedroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Make Room Members-Only?'
 
           label='Make Room Members-Only?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_membersonly'>
 
           var='muc#roomconfig_membersonly'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Password Required to Enter?'
 
           label='Password Required to Enter?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_passwordprotectedroom'>
 
           var='muc#roomconfig_passwordprotectedroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field type='fixed'>
 
       <field type='fixed'>
 
 
         <value>
 
         <value>
 
 
           If a password is required to enter this room,
 
           If a password is required to enter this room,
 
 
           you must specify the password below.
 
           you must specify the password below.
 
 
         </value>
 
         </value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Password'
 
           label='Password'
 
 
           type='text-private'
 
           type='text-private'
 
 
           var='muc#roomconfig_roomsecret'/>
 
           var='muc#roomconfig_roomsecret'/>
 
 
       <field
 
       <field
 
 
           label='Who May Discover Real JIDs?'
 
           label='Who May Discover Real JIDs?'
 
 
           type='list-single'
 
           type='list-single'
 
 
           var='muc#roomconfig_whois'>
 
           var='muc#roomconfig_whois'>
 
 
         <option label='Moderators Only'>
 
         <option label='Moderators Only'>
 
 
           <value>moderators</value>
 
           <value>moderators</value>
 
 
         </option>
 
         </option>
 
 
         <option label='Anyone'>
 
         <option label='Anyone'>
 
 
           <value>anyone</value>
 
           <value>anyone</value>
 
 
         </option>
 
         </option>
 
 
       </field>
 
       </field>
 
 
       <field type='fixed'>
 
       <field type='fixed'>
 
 
         <value>
 
         <value>
 
 
           You may specify additional people who have
 
           You may specify additional people who have
 
 
           administrative privileges in the room. Please
 
           administrative privileges in the room. Please
 
 
           provide one Jabber ID per line.
 
           provide one Jabber ID per line.
 
 
         </value>
 
         </value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Room Admins'
 
           label='Room Admins'
 
 
           type='jid-multi'
 
           type='jid-multi'
 
 
           var='muc#roomconfig_roomadmins'/>
 
           var='muc#roomconfig_roomadmins'/>
 
 
       <field type='fixed'>
 
       <field type='fixed'>
 
 
         <value>
 
         <value>
 
 
           You may specify additional owners for this
 
           You may specify additional owners for this
 
 
           room. Please provide one Jabber ID per line.
 
           room. Please provide one Jabber ID per line.
 
 
         </value>
 
         </value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Room Owners'
 
           label='Room Owners'
 
 
           type='jid-multi'
 
           type='jid-multi'
 
 
           var='muc#roomconfig_roomowners'/>
 
           var='muc#roomconfig_roomowners'/>
 
 
     </x>
 
     </x>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
注意: _whois 配置选项指定该房间是非匿名的(值为 "anyone"), 半匿名的(值为"moderators"), 还是全匿名的(值为"none", 不显示在这).
  
 +
如果没有配置选项可用, 服务必须 MUST 返回空的 query 元素给房间所有者:
  
 +
'''例子 148. 服务通知所有者没有配置可用'''
  
Note: The _whois configuration option specifies whether the room is non-anonymous (a value of "anyone"), semi-anonymous (a value of "moderators"), or fully anonmyous (a value of "none", not shown here).
+
<source lang="xml">
 
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
If there are no configuration options available, the service MUST return an empty query element to the room owner:
+
 
+
 
+
 
+
Example 138. Service Informs Owner that No Configuration is Possible
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='create1'
 
     id='create1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
房间所有者应该 SHOULD 接着填好表单并提交给服务.
 
+
 
+
 
+
The room owner SHOULD then fill out the form and submit it to the service.
+
 
+
 
+
 
+
Example 139. Owner Submits Configuration Form
+
 
+
  
 +
'''例子 149. 所有者提交配置表单'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='create2'
 
     id='create2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
 
     <x xmlns='jabber:x:data' type='submit'>
 
     <x xmlns='jabber:x:data' type='submit'>
 
 
       <field var='FORM_TYPE'>
 
       <field var='FORM_TYPE'>
 
 
         <value>http://jabber.org/protocol/muc#roomconfig</value>
 
         <value>http://jabber.org/protocol/muc#roomconfig</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_roomname'>
 
       <field var='muc#roomconfig_roomname'>
 
 
         <value>A Dark Cave</value>
 
         <value>A Dark Cave</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_roomdesc'>
 
       <field var='muc#roomconfig_roomdesc'>
 
 
         <value>The place for all good witches!</value>
 
         <value>The place for all good witches!</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_enablelogging'>
 
       <field var='muc#roomconfig_enablelogging'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_changesubject'>
 
       <field var='muc#roomconfig_changesubject'>
 
 
         <value>1</value>
 
         <value>1</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_allowinvites'>
 
       <field var='muc#roomconfig_allowinvites'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_maxusers'>
 
       <field var='muc#roomconfig_maxusers'>
 
 
         <value>10</value>
 
         <value>10</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_publicroom'>
 
       <field var='muc#roomconfig_publicroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_persistentroom'>
 
       <field var='muc#roomconfig_persistentroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_moderatedroom'>
 
       <field var='muc#roomconfig_moderatedroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_membersonly'>
 
       <field var='muc#roomconfig_membersonly'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_passwordprotectedroom'>
 
       <field var='muc#roomconfig_passwordprotectedroom'>
 
 
         <value>1</value>
 
         <value>1</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_roomsecret'>
 
       <field var='muc#roomconfig_roomsecret'>
 
 
         <value>cauldronburn</value>
 
         <value>cauldronburn</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_whois'>
 
       <field var='muc#roomconfig_whois'>
 
 
         <value>moderators</value>
 
         <value>moderators</value>
 
 
       </field>
 
       </field>
 
 
       <field var='muc#roomconfig_roomadmins'>
 
       <field var='muc#roomconfig_roomadmins'>
 
 
         <value>wiccarocks@shakespeare.lit</value>
 
         <value>wiccarocks@shakespeare.lit</value>
 
 
         <value>hecate@shakespeare.lit</value>
 
         <value>hecate@shakespeare.lit</value>
 
 
       </field>
 
       </field>
 
 
     </x>
 
     </x>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
如果房间创建成功, 服务必须 MUST 通知新的房间所有者成功了:
  
 +
'''例子 150. 服务通知新房间所有者成功'''
  
 
+
<source lang="xml">
If room creation is successful, the service MUST inform the new room owner of success:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 140. Service Informs New Room Owner of Success
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='create2'
 
     id='create2'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
     
+
如果因为指定的房间配置违反了一个或多个服务策略而导致房间创建失败 (例如, 因为密码保护房间的密码为空), 服务必须 MUST 返回一个 <not-acceptable/> 错误.
  
 +
'''例子 151. 服务通知所有者请求的配置选项不被接受'''
  
 
+
<source lang="xml">
If the room creation fails because the specified room configuration options violate one or more service policies (e.g., because the password for a password-protected room is blank), the service MUST return a <not-acceptable/> error.
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 141. Service Informs Owner that Requested Configuration Options Are Unacceptable
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='create2'
 
     id='create2'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='error'>
 
     type='error'>
 
 
   <error type='modify'>
 
   <error type='modify'>
 
 
     <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
另一方面, 房间所有者可以 MAY 取消配置过程:
 
+
 
+
 
+
Alternatively, the room owner MAY cancel the configuration process:
+
 
+
 
+
 
+
Example 142. Owner Cancels Initial Configuration
+
 
+
  
 +
'''例子 152. 所有者取消初始的配置'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='create2'
 
     id='create2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
 
     <x xmlns='jabber:x:data' type='cancel'/>
 
     <x xmlns='jabber:x:data' type='cancel'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
如果房间所有者取消了初始的房间配置, 服务应该 SHOULD 销毁房间, 确保发送不可用出席信息给房间所有者 (详见 "销毁房间" 用例).
  
 +
如果房间所有者在提交表单之前因为任何原因下线了(例如, 失去连接), 服务将接收到一个类型为 "unavailable" 的出席信息节,从所有者到所有者的 <room@service/nick> 或到 <room@service> (或两者). 服务必须 MUST 接着销毁这个房间, 发送一个 "unavailable" 类型的出席信息节,从房间到所有者,包含一个 <destroy/> 元素以及 reason (子元素)(如果提供了) ,参见本文的 [[XEP-0045#销毁房间|销毁房间]]章节.
  
 +
====申请唯一房间名====
  
If the room owner cancels the initial configuration, the service SHOULD destroy the room, making sure to send unavailable presence to the room owner (see the "Destroying a Room" use case for protocol details).
+
在一些场合 (例如, 当 [[XEP-0045#把一对一聊天转为多用户会议|把一对一聊天转为会议]]), 房间创建者可能想在尝试新建房间之前请求一个唯一的房间名 (例如, 避免可能的房间冲突). 为此, 服务可以 MAY 如本章所述支持这个特性. (如果服务支持这个特性, 它必须 MUST 在对服务发现信息请求应答时返回一个 "http://jabber.org/protocol/muc#unique" 特性.)
 
+
 
+
 
+
If the room owner becomes unavailable for any reason before submitting the form (e.g., a lost connection), the service will receive a presence stanza of type "unavailable" from the owner to the owner's <room@service/nick> or to <room@service> (or both). The service MUST then destroy the room, sending a presence stanza of type "unavailable" from the room to the owner including a <destroy/> element and reason (if provided) as defined in the Destroying a Room section of this document.
+
 
+
10.1.4 Requesting a Unique Room Name
+
 
+
 
+
 
+
In some situations (e.g., when Converting a One-to-One Chat Into a Conference), the room creator may want to request a unique room name before attempting to create the room (e.g., to avoid the possibility of a room conflict). In order to facilitate this, a service MAY support the feature described in this section. (If a service does support this feature, it MUST return a feature of "http://jabber.org/protocol/muc#unique" in its response to service discovery information requests.)
+
 
+
 
+
 
+
The room creator requests a unique room name by sending an IQ-get to the service itself, containing an empty <unique/> element qualified by the 'http://jabber.org/protocol/muc#unique' namespace:
+
 
+
 
+
 
+
Example 143. Entity Requests Unique Room Name
+
  
 +
房间创建者通过发送一个 IQ-get 给服务本身来请求唯一房间名, 这个IQ节中包含一个空的 <unique/> 元素,遵循 'http://jabber.org/protocol/muc#unique' 名字空间:
  
 +
'''例子 153. 实体请求唯一房间名'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='unique1'
 
     id='unique1'
 
+
     to='chat.shakespeare.lit'
     to='macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <unique xmlns='http://jabber.org/protocol/muc#unique'/>
 
   <unique xmlns='http://jabber.org/protocol/muc#unique'/>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
如果服务支持这个特性, 它应该 SHOULD 以 XML 字符数据的方式返回一个唯一房间名,包含一个 <unique/> 元素 (但不创建该房间):
  
 +
'''例子 154. 服务返回唯一房间名'''
  
 
+
<source lang="xml">
If the service supports this feature, it SHOULD return a unique room name as the XML character data of the <unique/> element:
+
<iq from='chat.shakespeare.lit'
 
+
 
+
 
+
Example 144. Service Returns Unique Room Name
+
 
+
 
+
 
+
<iq from='macbeth.shakespeare.lit'
+
 
+
 
     id='unique1'
 
     id='unique1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'>
 
     type='result'>
 
 
   <unique xmlns='http://jabber.org/protocol/muc#unique'>
 
   <unique xmlns='http://jabber.org/protocol/muc#unique'>
 
 
     6d9423a55f499b29ad20bf7b2bdea4f4b885ead1
 
     6d9423a55f499b29ad20bf7b2bdea4f4b885ead1
 
 
   </unique>
 
   </unique>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
服务可以 MAY 拒绝返回一个唯一房间名给一个没有资格创建房间的实体, 或那些发送请求唯一房间名过多次数的实体, 等等.
  
 +
服务可以 MAY 使用算法保证房间名的创建在服务上下文中是唯一的 (例如, 对发出请求的JID,datetime,和random salt的SHA-1 哈希运算).
  
 +
房间创建者将接着使用 XML 字符数据 <unique/> 元素作为它请求的房间JID的节点标识符(ID):
  
The service MAY refuse to return a unique room name to entities that are not entitled to create rooms, entities that have sent an excessive number of requests for unique room names, etc.
+
'''例子 155. 所有者以唯一名创建房间'''
 
+
 
+
 
+
The service MAY use any algorithm that ensures the creation of a room name that will be permanently unique in the context of the service (e.g., a SHA-1 hash of the requesting JID, datetime, and random salt).
+
 
+
 
+
 
+
The room creator would then use the XML character data of the <unique/> element as the node identifier portion of the room JID it requests:
+
 
+
 
+
 
+
Example 145. Owner Creates Room With Unique Name
+
 
+
 
+
  
 +
<source lang="xml">
 
<presence  
 
<presence  
 
 
     from='crone1@shakespeare.lit/desktop'
 
     from='crone1@shakespeare.lit/desktop'
 
+
     to='6d9423a55f499b29ad20bf7b2bdea4f4b885ead1@chat.shakespeare.lit/firstwitch'>
     to='6d9423a55f499b29ad20bf7b2bdea4f4b885ead1@macbeth.shakespeare.lit/firstwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
===随后的房间配置===
 
+
 
+
 
+
10.2 Subsequent Room Configuration
+
 
+
 
+
 
+
At any time after specifying the initial configuration of the room, a room owner may want to change the configuration. In order to initiate this process, a room owner MUST request a new configuration form from the room by sending an IQ to <room@service> containing an empty <query/> element qualified by the 'http://jabber.org/protocol/muc#owner' namespace.
+
 
+
 
+
 
+
Example 146. Owner Requests Configuration Form
+
  
 +
在指定房间的初始配置之后的任何时间, 房间所有者可能想修改房间配置. 为此, 房间所有者必须 MUST 向房间发出一个新的配置表单请求,通过发送一个 IQ 到 <room@service> ,包含一个空的 <query/> 元素,遵循 'http://jabber.org/protocol/muc#owner' 名字空间.
  
 +
'''例子 156. 所有者请求配置表单'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='config1'
 
     id='config1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果'from'地址的 <user@host> 部分和房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者:
  
 +
'''例子 157. 服务禁止非所有者的访问配置'''
  
 
+
<source lang="xml">
If the <user@host> of the 'from' address does not match the bare JID of a room owner, the service MUST return a <forbidden/> error to the sender:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 147. Service Denies Configuration Access to Non-Owner
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='configures'
 
     id='configures'
 
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'/>
 
+
   <error type='auth'>
   <error code='403' type='auth'>
+
 
+
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
另外, 服务必须 MUST 以当前使用的选项组作为缺省值发送一个配置表单给房间所有者:
  
 +
'''例子 158. 服务发送配置表单给所有者'''
  
 
+
<source lang="xml">
Otherwise, the service MUST send a configuration form to the room owner with the current options set as defaults:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 148. Service Sends Configuration Form to Owner
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='config1'
 
     id='config1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
 
     <x xmlns='jabber:x:data' type='form'>
 
     <x xmlns='jabber:x:data' type='form'>
 
 
       <title>Configuration for "darkcave" Room</title>
 
       <title>Configuration for "darkcave" Room</title>
 
 
       <instructions>
 
       <instructions>
 
 
         Complete this form to make changes to
 
         Complete this form to make changes to
 
 
         the configuration of your room.
 
         the configuration of your room.
 
 
       </instructions>
 
       </instructions>
 
 
       <field
 
       <field
 
 
           type='hidden'
 
           type='hidden'
 
 
           var='FORM_TYPE'>
 
           var='FORM_TYPE'>
 
 
         <value>http://jabber.org/protocol/muc#roomconfig</value>
 
         <value>http://jabber.org/protocol/muc#roomconfig</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Natural-Language Room Name'
 
           label='Natural-Language Room Name'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#roomconfig_roomname'>
 
           var='muc#roomconfig_roomname'>
 
 
         <value>A Dark Cave</value>
 
         <value>A Dark Cave</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Short Description of Room'
 
           label='Short Description of Room'
 
 
           type='text-single'
 
           type='text-single'
 
 
           var='muc#roomconfig_roomdesc'>
 
           var='muc#roomconfig_roomdesc'>
 
 
         <value>The place for all good witches!</value>
 
         <value>The place for all good witches!</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Enable Public Logging?'
 
           label='Enable Public Logging?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_enablelogging'>
 
           var='muc#roomconfig_enablelogging'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Allow Occupants to Change Subject?'
 
           label='Allow Occupants to Change Subject?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_changesubject'>
 
           var='muc#roomconfig_changesubject'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Allow Occupants to Invite Others?'
 
           label='Allow Occupants to Invite Others?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_allowinvites'>
 
           var='muc#roomconfig_allowinvites'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Maximum Number of Occupants'
 
           label='Maximum Number of Occupants'
 
 
           type='list-single'
 
           type='list-single'
 
 
           var='muc#roomconfig_maxusers'>
 
           var='muc#roomconfig_maxusers'>
 
 
         <value>10</value>
 
         <value>10</value>
 
 
         <option label='10'><value>10</value></option>
 
         <option label='10'><value>10</value></option>
 
 
         <option label='20'><value>20</value></option>
 
         <option label='20'><value>20</value></option>
 
 
         <option label='30'><value>30</value></option>
 
         <option label='30'><value>30</value></option>
 
 
         <option label='50'><value>50</value></option>
 
         <option label='50'><value>50</value></option>
 
 
         <option label='100'><value>100</value></option>
 
         <option label='100'><value>100</value></option>
 
 
         <option label='None'><value>none</value></option>
 
         <option label='None'><value>none</value></option>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Roles for which Presence is Broadcast'
 
           label='Roles for which Presence is Broadcast'
 
 
           type='list-multi'
 
           type='list-multi'
 
 
           var='muc#roomconfig_presencebroadcast'>
 
           var='muc#roomconfig_presencebroadcast'>
 
 
         <value>moderator</value>
 
         <value>moderator</value>
 
 
         <value>participant</value>
 
         <value>participant</value>
 
 
         <value>visitor</value>
 
         <value>visitor</value>
 
 
         <option label='Moderator'><value>moderator</value></option>
 
         <option label='Moderator'><value>moderator</value></option>
 
 
         <option label='Participant'><value>participant</value></option>
 
         <option label='Participant'><value>participant</value></option>
 
 
         <option label='Visitor'><value>visitor</value></option>
 
         <option label='Visitor'><value>visitor</value></option>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
+
          label='Roles and Affiliations that May Retrieve Member List'
 +
          type='list-multi'
 +
          var='muc#roomconfig_getmemberlist'>
 +
        <value>moderator</value>
 +
        <value>participant</value>
 +
        <value>visitor</value>
 +
        <option label='Moderator'><value>moderator</value></option>
 +
        <option label='Participant'><value>participant</value></option>
 +
        <option label='Visitor'><value>visitor</value></option>
 +
      </field>
 +
      <field
 
           label='Make Room Publicly Searchable?'
 
           label='Make Room Publicly Searchable?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_publicroom'>
 
           var='muc#roomconfig_publicroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Make Room Persistent?'
 
           label='Make Room Persistent?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_persistentroom'>
 
           var='muc#roomconfig_persistentroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Make Room Moderated?'
 
           label='Make Room Moderated?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_moderatedroom'>
 
           var='muc#roomconfig_moderatedroom'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Make Room Members Only?'
 
           label='Make Room Members Only?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_membersonly'>
 
           var='muc#roomconfig_membersonly'>
 
 
         <value>0</value>
 
         <value>0</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Password Required for Entry?'
 
           label='Password Required for Entry?'
 
 
           type='boolean'
 
           type='boolean'
 
 
           var='muc#roomconfig_passwordprotectedroom'>
 
           var='muc#roomconfig_passwordprotectedroom'>
 
 
         <value>1</value>
 
         <value>1</value>
 
 
       </field>
 
       </field>
 
 
       <field type='fixed'>
 
       <field type='fixed'>
 
 
         <value>
 
         <value>
 
 
           If a password is required to enter this room,
 
           If a password is required to enter this room,
 
 
           you must specify the password below.
 
           you must specify the password below.
 
 
         </value>
 
         </value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Password'
 
           label='Password'
 
 
           type='text-private'
 
           type='text-private'
 
 
           var='muc#roomconfig_roomsecret'>
 
           var='muc#roomconfig_roomsecret'>
 
 
         <value>cauldronburn</value>
 
         <value>cauldronburn</value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Who May Discover Real JIDs?'
 
           label='Who May Discover Real JIDs?'
 
 
           type='list-single'
 
           type='list-single'
 
 
           var='muc#roomconfig_whois'>
 
           var='muc#roomconfig_whois'>
 
 
         <value>moderators</value>
 
         <value>moderators</value>
 
 
         <option label='Moderators Only'>
 
         <option label='Moderators Only'>
 
 
           <value>moderators</value>
 
           <value>moderators</value>
 
 
         </option>
 
         </option>
 
 
         <option label='Anyone'>
 
         <option label='Anyone'>
 
 
           <value>anyone</value>
 
           <value>anyone</value>
 
 
         </option>
 
         </option>
 
 
       </field>
 
       </field>
 
 
       <field type='fixed'>
 
       <field type='fixed'>
 
 
         <value>
 
         <value>
 
 
           You may specify additional people who have
 
           You may specify additional people who have
 
 
           administrative privileges in the room. Please
 
           administrative privileges in the room. Please
 
 
           provide one Jabber ID per line.
 
           provide one Jabber ID per line.
 
 
         </value>
 
         </value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Room Admins'
 
           label='Room Admins'
 
 
           type='jid-multi'
 
           type='jid-multi'
 
 
           var='muc#roomconfig_roomadmins'>
 
           var='muc#roomconfig_roomadmins'>
 
 
         <value>wiccarocks@shakespeare.lit</value>
 
         <value>wiccarocks@shakespeare.lit</value>
 
 
         <value>hecate@shakespeare.lit</value>
 
         <value>hecate@shakespeare.lit</value>
 
 
       </field>
 
       </field>
 
 
       <field type='fixed'>
 
       <field type='fixed'>
 
 
         <value>
 
         <value>
 
 
           You may specify additional owners for this
 
           You may specify additional owners for this
 
 
           room. Please provide one Jabber ID per line.
 
           room. Please provide one Jabber ID per line.
 
 
         </value>
 
         </value>
 
 
       </field>
 
       </field>
 
 
       <field
 
       <field
 
 
           label='Room Owners'
 
           label='Room Owners'
 
 
           type='jid-multi'
 
           type='jid-multi'
 
 
           var='muc#roomconfig_roomowners'/>
 
           var='muc#roomconfig_roomowners'/>
 
 
     </x>
 
     </x>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果没有配置选项可用, 服务必须 MUST 返回一个空的 query 元素给房间所有者,如前面的用例所示.
  
 +
该房间所有者应该 SHOULD 接着以更新的配置信息提交表单.
  
 +
另外, 房间所有者可以 MAY 取消这次配置过程:
  
If there are no configuration options available, the service MUST return an empty query element to the room owner as shown in the previous use case.
+
'''例子 159. 所有者取消随后的配置'''
 
+
 
+
 
+
The room owner SHOULD then submit the form with updated configuration information.
+
 
+
 
+
 
+
Alternatively, the room owner MAY cancel the configuration process:
+
 
+
 
+
 
+
Example 149. Owner Cancels Subsequent Configuration
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='config2'
 
     id='config2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
 
     <x xmlns='jabber:x:data' type='cancel'/>
 
     <x xmlns='jabber:x:data' type='cancel'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果房间所有者取消随后的配置, 服务必须 MUST 让该房间的配置保持和房间所有者请求这次配置之前一样.
 
+
 
+
 
+
If the room owner cancels the subsequent configuration, the service MUST leave the configuration of the room as it was before the room owner initiated the subsequent configuration process.
+
 
+
 
+
 
+
If as a result of a change in the room configuration a room admin loses administrative privileges while the admin is in the room, the room MUST send updated presence for that individual to all occupants, denoting the change in status by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "member" and the 'role' attribute set to a value of "participant" or "visitor" as appropriate for the affiliation level and the room type:
+
 
+
 
+
 
+
Example 150. Service Notes Loss of Admin Affiliation
+
  
 +
如果一次房间配置变更导致一个房间管理员失去管理权限,而这个管理员正在房间里, 该房间必须 MUST 为那个管理员发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "member" 或 'role' 属性值为 "participant" 或 "visitor" ,以适当地表达岗位级别和房间类型:
  
 +
'''例子 160. 服务通知失去管理员岗位'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 
+
</source>
.
+
 
+
.
+
 
+
   
+
 
+
 
+
 
+
If as a result of a change in the room configuration a user gains administrative privileges while the user is in the room, the room MUST send updated presence for that individual to all occupants, denoting the change in status by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "admin" and the 'role' attribute set to a value of "admin":
+
 
+
 
+
 
+
Example 151. Service Notes Gain of Admin Affiliation to All Users
+
  
 +
如果一次房间配置变更导致一个用户获得管理员权限,而这个用户正在房间里, 房间必须 MUST 为那个用户发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin" 或 'role' 属性值为 "admin" :
  
 +
'''例子 161. 服务通知所有用户有人获得管理员岗位'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 
+
</source>
.
+
 
+
.
+
 
+
   
+
 
+
 
+
 
+
If as a result of a change in the room configuration a room owner loses owner privileges while that owner is in the room, the room MUST send updated presence for that individual to all occupants, denoting the change in status by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "admin" and the 'role' attribute set to an appropriate value given the affiliation and room type ("moderator" is recommended).
+
 
+
 
+
 
+
Example 152. Service Notes Loss of Owner Affiliation
+
  
 +
如果一次房间配置变更导致一个房间所有者失去所有者权限,而这个所有者正在房间里, 该房间必须 MUST 为那个所有者发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin" 或 'role' 属性值为根据岗位和房间类型确定的适当的值(推荐为"moderator").
  
 +
'''例子 162. 服务通知失去所有者岗位'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果没有其他所有者,服务不能 MUST NOT 允许一个所有者撤销他或她自己的所有权; 如果一个所有者企图这么干, 服务必须 MUST 返回一个 <conflict/> 错误给这个所有者. 然而, 如果有其他所有者,服务应该 SHOULD 允许一个所有者撤销自己的所有者权限.
 
+
.
+
 
+
   
+
 
+
 
+
 
+
A service MUST NOT allow an owner to revoke his or her own ownership privileges if there are no other owners; if an owner attempts to do this, the service MUST return a <conflict/> error to the owner. However, a service SHOULD allow an owner to revoke his or her own ownership privileges if there are other owners.
+
 
+
 
+
 
+
If as a result of a change in the room configuration a user gains ownership privileges while the user is in the room, the room MUST send updated presence for that individual to all occupants, denoting the change in status by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "owner" and the 'role' attribute set to an appropriate value given the affiliation and room type ("moderator" is recommended).
+
 
+
 
+
 
+
Example 153. Service Notes Gain of Owner Affiliation to All Users
+
  
 +
如果一次房间配置变更导致一个用户获得所有者权限,而这个用户正在房间里, 房间必须 MUST 为那个用户发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "owner" 或 'role' 属性值为根据岗位和房间类型确定的适当的值(推荐为"moderator").
  
 +
'''例子 163. 服务通知所有用户有人获得所有者权限'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='owner'
 
     <item affiliation='owner'
 
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
           jid='wiccarocks@shakespeare.lit/laptop'
 
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果一次房间配置变更导致房间类型变成仅限会员,但还有非成员在房间里, 服务必须 MUST 从房间移除任何非成员,并在发送给那些剩余的房客的 '不可用' 出席信息节里包含状态码 322.
  
.
+
====配置变更通知====
  
   
+
当一个房间的配置变更会对房间的隐私和安全策略产生影响时,该房间必须 MUST 发送通知给所有房客. 这个通知将包括一个 <message/> 节,包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的 <x/> 元素,  <x/> 元素则只有一个 <status/> 子元素,其 'code' 属性为一个适当的值. 这是例子:
  
 +
'''例子 164. 配置状态码'''
  
 
+
<source lang="xml">
If as a result of a change in the room configuration the room type is changed to members-only but there are non-members in the room, the service MUST remove any non-members from the room and include a status code of 322 in the presence unavailable stanzas sent to those users as well as any remaining occupants.
+
<message from='darkcave@chat.shakespeare.lit'
 
+
         to='crone1@shakespeare.lit/desktop'
10.2.1 Notification of Configuration Changes
+
        type='groupchat'>
 
+
 
+
 
+
A room MUST send notification to all occupants when the room configuration changes in a way that has an impact on the privacy or security profile of the room. This notification shall consist of a <message/> stanza containing an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace, which shall contain only a <status/> element with an appropriate value for the 'code' attribute. Here is an example:
+
 
+
 
+
 
+
Example 154. Configuration Status Code
+
 
+
 
+
 
+
<message from='darkcave@macbeth.shakespeare.lit'
+
 
+
         to='crone1@shakespeare.lit/desktop'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <status code='170'/>
 
     <status code='170'/>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
     
+
房间配置中和隐私相关的策略变更导致生成这些状态码,如下:
  
 +
* 如果房间日志功能可用了, 状态码 170.
 +
* 如果房间日志现在禁止了, 状态码 171.
 +
* 如果房间现在是非匿名的了, 状态码 172.
 +
* 如果房间现在是半匿名的了, 状态码 173.
 +
* 如果房间现在是全匿名的了, 状态码 174.
  
 +
对更多其他配置变更, 房间应该 SHOULD 发送状态码 104 这样感兴趣的房客如果想要的话可以接受到更新的房间配置.
  
The codes to be generated as a result of a privacy-related change in room configuration are as follows:
+
===授予所有者权限===
 
+
 
+
 
+
    * If room logging is now enabled, status code 170.
+
 
+
    * If room logging is now disabled, status code 171.
+
 
+
    * If the room is now non-anonymous, status code 172.
+
 
+
    * If the room is now semi-anonymous, status code 173.
+
 
+
    * If the room is now fully-anonymous, status code 174.
+
 
+
 
+
 
+
For any other configuration change, the room SHOULD send status code 104 so that interested occupants can retrieve the updated room configuration if desired.
+
 
+
10.3 Granting Ownership Privileges
+
 
+
 
+
 
+
If allowed by an implementation, an owner MAY grant ownership privileges to another user; this is done by changing the user's affiliation to "owner":
+
 
+
 
+
 
+
Example 155. Owner Grants Ownership Privileges
+
  
 +
如果实现允许, 一个所有者可以 MAY 授予所有权给其他用户; 只要把用户的岗位改成"owner":
  
 +
'''例子 165. 所有者授予所有权'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='owner1'
 
     id='owner1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='owner'
 
     <item affiliation='owner'
 
 
           jid='hecate@shakespeare.lit'/>
 
           jid='hecate@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/> 元素是可选的 OPTIONAL.
  
 +
'''例子 166. 所有者授予所有权(饱含一个原因 Reason)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='owner1'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item affiliation='owner'
 +
          jid='hecate@shakespeare.lit'>
 +
      <reason>A worthy witch indeed!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST add the user to the owner list and then inform the owner of success:
+
服务必须 MUST 把用户添加到所有者列表并通知所有者成功了:
  
 +
'''例子 167. 服务通知所有者成功了'''
  
 
+
<source lang="xml">
Example 156. Service Informs Owner of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='owner1'
 
     id='owner1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已授予所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "owner" 并且 'role' 属性值为根据岗位和房间类型确定的适当的值(推荐为"moderator").  
 
+
 
+
 
+
If the user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the granting of ownership privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "owner" and the 'role' attribute set to an appropriate value given the affiliation and room type ("moderator" is recommended).
+
 
+
 
+
 
+
Example 157. Service Sends Notice of Ownership Privileges to All Occupants
+
 
+
  
 +
'''例子 168. 服务发送所有权通知给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/hecate'
     from='darkcave@macbeth.shakespeare.lit/hecate'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='owner'
 
     <item affiliation='owner'
 
+
           jid='hecate@shakespeare.lit'
           jid='hecate@shakespeare.lit/broom'
+
 
+
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已授予所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "owner" .  
  
.
+
'''例子 169. 服务发送所有权通知给所有房客'''
  
      
+
<source lang="xml">
 +
<message
 +
     from='chat.shakespeare.lit'
 +
    to='crone1@shakespeare.lit/desktop'>
 +
  <x xmlns='http://jabber.org/protocol/muc#user'>
 +
    <item affiliation='member'
 +
          jid='hecate@shakespeare.lit'
 +
          role='none'/>
 +
  </x>
 +
</message>
  
 +
[ ... ]
 +
</source>
  
 +
===撤销所有者权限===
  
10.4 Revoking Ownership Privileges
+
实现可以 MAY 允许一个所有者撤销其他用户的所有权; 只要把用户的岗位改成非"owner":
 
+
 
+
 
+
An implementation MAY allow an owner to revoke another user's ownership privileges; this is done by changing the user's affiliation to something other than "owner":
+
 
+
 
+
 
+
Example 158. Owner Revokes Ownership Privileges
+
 
+
  
 +
'''例子 170. 所有者撤销所有权'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='owner2'
 
     id='owner2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='hecate@shakespeare.lit'/>
 
           jid='hecate@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/>元素是可选的 OPTIONAL.
  
 +
'''例子 171. 所有者撤销所有权(包含一个原因)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='owner2'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item affiliation='admin'
 +
          jid='hecate@shakespeare.lit'>
 +
      <reason>Not so worthy after all!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
A service MUST NOT allow an owner to revoke his or her own ownership privileges if there are no other owners; if an owner attempts to do this, the service MUST return a <conflict/> error to the owner. However, a service SHOULD allow an owner to revoke his or her own ownership privileges if there are other owners.
+
如果没有其它所有者,服务不能 MUST NOT 允许一个所有者撤销他或她自己的所有权; 如果一个所有者尝试这么干, 服务必须 MUST 返回一个 <conflict/> 错误给该所有者. 然而, 如果有其他所有者,服务应该 SHOULD 允许一个所有者撤销自己的所有权.
  
 +
如果一个实现不允许所有者撤销另一个用户的所有权, 实现必须 MUST 返回一个 <not-authorized/> 错误给做出这个请求的所有者.
  
 +
注意: 允许一个所有者移除其它用户的所有权能给房间管理一个折衷的控制模式; 所以这个特性是可选的 OPTIONAL, 并且鼓励实现支持通过一个只有拥有服务范围管理权限的用户使用的接口来移除所有者.
  
If an implementation does not allow one owner to revoke another user's ownership privileges, the implementation MUST return a <not-authorized/> error to the owner who made the request.
+
其它情况下, 服务必须 MUST 把用户从所有者列表移除并通知所有者成功了:
  
 +
'''例子 172. 服务通知所有者成功了'''
  
 
+
<source lang="xml">
In all other cases, the service MUST remove the user from the owner list and then inform the owner of success:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 159. Service Informs Owner of Success
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='owner2'
 
     id='owner2'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已失去所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非 "owner" 并且 'role' 属性值为根据岗位和房间类型确定的适当的值:
 
+
 
+
 
+
If the user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the loss of ownership privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "owner" and the 'role' attribute set to an appropriate value:
+
 
+
 
+
 
+
Example 160. Service Notes Loss of Owner Affiliation
+
 
+
  
 +
'''例子 173. 服务通知失去所有权'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
+
           jid='hecate@shakespeare.lit'
           jid='hecate@shakespeare.lit/broom'
+
 
+
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已失去所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user'  名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非 "owner" .
  
.
+
'''例子 174. 服务发送失去所有权通知给所有房客 '''
  
      
+
<source lang="xml">
 +
<message
 +
     from='chat.shakespeare.lit'
 +
    to='crone1@shakespeare.lit/desktop'>
 +
  <x xmlns='http://jabber.org/protocol/muc#user'>
 +
    <item affiliation='admin'
 +
          jid='hecate@shakespeare.lit'
 +
          role='none'/>
 +
  </x>
 +
</message>
  
 +
[ ... ]
 +
</source>
  
 +
===修改所有者列表===
  
Note: Allowing an owner to remove another user's ownership privileges can compromise the control model for room management; therefore this feature is OPTIONAL, and implementations are encouraged to support owner removal through an interface that is open only to individuals with service-wide administrative privileges.
+
如果实现允许, 一个房间所有者可能想修改所有者列表. 为此, 所有者首先请求所有者列表,通过向房间请求所有岗位为 'owner'的用户.
 
+
10.5 Modifying the Owner List
+
 
+
 
+
 
+
If allowed by an implementation, a room owner may want to modify the owner list. To do so, the owner first requests the owner list by querying the room for all users with an affiliation of 'owner'.
+
 
+
 
+
 
+
Example 161. Owner Requests Owner List
+
 
+
  
 +
'''例子 175. 所有者请求所有者列表'''
  
 +
<source lang="xml">
 
<iq from='bard@shakespeare.lit/globe'
 
<iq from='bard@shakespeare.lit/globe'
 
 
     id='owner3'
 
     id='owner3'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='owner'/>
 
     <item affiliation='owner'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果'from'地址的 <user@host> 部分和房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者.
  
 +
否则, 服务必须 MUST 接着返回所有者列表给所有者; 每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性,对任何正是一名房客(也就是正在房间里)的所有者可以 MAY 包含 'nick' 和 'role' 属性:
  
 +
'''例子 176. 服务发送所有者列表给所有者'''
  
If the <user@host> of the 'from' address does not match the bare JID of a room owner, the service MUST return a <forbidden/> error to the sender.
+
<source lang="xml">
 
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
Otherwise, the service MUST then return the owner list to the owner; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for any owner that is currently an occupant:
+
 
+
 
+
 
+
Example 162. Service Sends Owner List to Owner
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='owner3'
 
     id='owner3'
 
 
     to='bard@shakespeare.lit/globe'
 
     to='bard@shakespeare.lit/globe'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='owner'
 
     <item affiliation='owner'
 
 
           jid='crone1@shakespeare.lit'/>
 
           jid='crone1@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
所有者可以 MAY 接着修改所有者列表. 为此, 所有者必须 MUST 发送修改的条目 (, "delta") 给服务; [[XEP-0045#附录G:备注|21]]每个条目必须 MUST 包含 'affiliation' 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,不能 MUST NOT 包含 'role' 属性 (它用于管理参与者之类的角色,而不是所有者之类的岗位):
 
+
 
+
 
+
The owner MAY then modify the owner list. In order to do so, the owner MUST send the changed items (i.e., only the "delta") back to the service; [20] each item MUST include the 'affiliation' and 'jid' attributes but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'role' attribute (which is used to manage roles such as participant rather than the owner affiliation):
+
 
+
 
+
 
+
Example 163. Owner Sends Modified Owner List to Service
+
 
+
  
 +
'''例子 177. 所有者发送修改过的所有者列表给服务'''
  
 +
<source lang="xml">
 
<iq from='bard@shakespeare.lit/globe'
 
<iq from='bard@shakespeare.lit/globe'
 
 
     id='owner4'
 
     id='owner4'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='owner'
 
     <item affiliation='owner'
 
 
           jid='hecate@shakespeare.lit'/>
 
           jid='hecate@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
只有所有者被允许修改所有者列表. 如果一个非所有者试图察看或修改所有者列表, 服务必须 MUST 拒绝这个请求并返回一个 <forbidden/> 错误给发送者:
  
 +
'''例子 178. 服务对于非所有者试图修改所有者列表返回错误'''
  
 
+
<source lang="xml">
Only owners shall be allowed to modify the owner list. If a non-owner attempts to view or modify the owner list, the service MUST deny the request and return a <forbidden/> error to the sender:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 164. Service Returns Error on Attempt by Non-Owner to Modify Owner List
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='ownertest'
 
     id='ownertest'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='owner'  
 
     <item affiliation='owner'  
 
 
           jid='hecate@shakespeare.lit'/>
 
           jid='hecate@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
+
   <error type='auth'>
   <error code='403' type='auth'>
+
 
+
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果没有别的所有者,服务不能 MUST NOT 允许一个所有者撤销自己的所有权; 如果一个所有者尝试这么干, 服务必须 MUST 返回一个 <conflict/> 错误给该所有者. 然而, 如果有其他所有者,服务应该 SHOULD 允许一个所有者撤销自己的所有权.
  
 +
其它情况下, 服务必须 MUST 修改所有者列表并通知所有者成功了:
  
 +
'''例子 179. 服务通知所有者成功了'''
  
A service MUST NOT allow an owner to revoke his or her own ownership privileges if there are no other owners; if an owner attempts to do this, the service MUST return a <conflict/> error to the owner. However, a service SHOULD allow an owner to revoke his or her own ownership privileges if there are other owners.
+
<source lang="xml">
 
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
In all other cases, the service MUST modify owner list and then inform the owner of success:
+
 
+
 
+
 
+
Example 165. Service Informs Owner of Success
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='owner4'
 
     id='owner4'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 也为任何因前述所有者列表修改而导致的岗位变化而发送出席信息通知.
  
 +
===授予管理员权限===
  
 +
一个所有者可以授予管理员权限给一个成员或无岗位的用户; 只要把用户的岗位改成"admin":
  
The service MUST also send presence notifications related to any affiliation changes that result from modifying the owner list as previously described.
+
'''例子 180. 所有者授予管理员权限'''
 
+
10.6 Granting Administrative Privileges
+
 
+
 
+
 
+
An owner can grant administrative privileges to a member or unaffiliated user; this is done by changing the user's affiliation to "admin":
+
 
+
 
+
 
+
Example 166. Owner Grants Admin Privileges
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='admin1'
 
     id='admin1'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='wiccarocks@shakespeare.lit'/>
 
           jid='wiccarocks@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/> 元素是可选的 OPTIONAL.
  
 +
'''例子 181. 所有者授予管理员权限(包含一个原因 Reason)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='admin1'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item affiliation='admin'
 +
          jid='wiccarocks@shakespeare.lit'>
 +
      <reason>A worthy witch indeed!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST add the user to the admin list and then inform the owner of success:
+
服务必须 MUST 把用户添加到管理员列表并通知所有者成功了:
  
 +
'''例子 182. 服务通知所有者成功了'''
  
 
+
<source lang="xml">
Example 167. Service Informs Owner of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='admin1'
 
     id='admin1'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已授予管理员权限,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin" 并且 'role' 属性值为根据岗位和房间类型确定的适当的值.  
 
+
 
+
 
+
If the user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the granting of administrative privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "admin" and the 'role' attribute set to an appropriate value given the affiliation and room type.
+
 
+
 
+
 
+
Example 168. Service Sends Notice of Administrative Privileges to All Occupants
+
 
+
  
 +
'''例子 183. 服务发送管理员权限通知给所有房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
+
           jid='wiccarocks@shakespeare.lit'
           jid='wiccarocks@shakespeare.lit/laptop'
+
 
+
 
           role='moderator'/>
 
           role='moderator'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已授予管理员权限,通过包含一个遵循 'http://jabber.org/protocol/muc#user'  名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin".
  
.
+
'''例子 184. 服务发送管理员权限通知给所有房客'''
  
      
+
<source lang="xml">
 +
<message
 +
     from='chat.shakespeare.lit'
 +
    to='crone1@shakespeare.lit/desktop'>
 +
  <x xmlns='http://jabber.org/protocol/muc#user'>
 +
    <item affiliation='admin'
 +
          jid='wiccarocks@shakespeare.lit'
 +
          role='none'/>
 +
  </x>
 +
</message>
  
 +
[ ... ]
 +
</source>
  
 +
===撤销管理员权限===
  
10.7 Revoking Administrative Privileges
+
一个所有者可能想撤销一个用户的管理员权限; 只要把用户的岗位改成非"admin"和非"owner":
 
+
 
+
 
+
An owner may want to revoke a user's administrative privileges; this is done by changing the user's affiliation to something other than "admin" or "owner":
+
 
+
 
+
 
+
Example 169. Owner Revokes Administrative Privileges
+
 
+
  
 +
'''例子 185. 所有者撤销管理员权限'''
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='admin2'
 
     id='admin2'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
 
           jid='wiccarocks@shakespeare.lit'/>
 
           jid='wiccarocks@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
<reason/>元素是可选的 OPTIONAL.
  
 +
'''例子 186. 所有者撤销管理员权限(包含一个原因)'''
  
 +
<source lang="xml">
 +
<iq from='crone1@shakespeare.lit/desktop'
 +
    id='admin2'
 +
    to='darkcave@chat.shakespeare.lit'
 +
    type='set'>
 +
  <query xmlns='http://jabber.org/protocol/muc#admin'>
 +
    <item affiliation='member'
 +
          jid='wiccarocks@shakespeare.lit'>
 +
      <reason>Not so worthy after all!</reason>
 +
    </item>
 +
  </query>
 +
</iq>
 +
</source>
  
The service MUST remove the user from the admin list and then inform the owner of success:
+
服务必须 MUST 把该用户从管理员列表移除并接着通知所有者成功了:
  
 +
'''例子 187. 服务通知所有者成功了'''
  
 
+
<source lang="xml">
Example 170. Service Informs Owner of Success
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='admin2'
 
     id='admin2'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已失去管理员权限,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非"admin""owner", 并且 'role' 属性值为根据岗位和房间类型确定的适当的值:  
 
+
 
+
 
+
The service MUST then send updated presence from this individual to all occupants, indicating the loss of administrative privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "admin" or "owner" and the 'role' attribute set to an appropriate value given the affiliation level and the room type:
+
 
+
 
+
 
+
Example 171. Service Notes Loss of Admin Affiliation
+
 
+
  
 +
'''例子 188. 服务通知失去管理员权限'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='darkcave@chat.shakespeare.lit/secondwitch'
     from='darkcave@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'>
 
     to='crone1@shakespeare.lit/desktop'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='member'
 
     <item affiliation='member'
 
+
           jid='wiccarocks@shakespeare.lit'
           jid='wiccarocks@shakespeare.lit/laptop'
+
 
+
 
           role='participant'/>
 
           role='participant'/>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
  
.
+
[ ... ]
 +
</source>
  
.
+
如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已失去所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user'  名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非 "admin" .  
  
.
+
'''例子 189. 服务通知失去管理员权限'''
  
      
+
<source lang="xml">
 +
<message
 +
     from='chat.shakespeare.lit'
 +
    to='crone1@shakespeare.lit/desktop'>
 +
  <x xmlns='http://jabber.org/protocol/muc#user'>
 +
    <item affiliation='member'
 +
          jid='wiccarocks@shakespeare.lit'
 +
          role='none'/>
 +
  </x>
 +
</message>
  
 +
[ ... ]
 +
</source>
  
 +
===修改管理员列表===
  
10.8 Modifying the Admin List
+
一个房间所有者可能想修改管理员列表. 为此, 所有者首先请求管理员列表,通过向房间请求所有岗位为 'admin'的用户.  
 
+
 
+
 
+
A room owner may want to modify the admin list. To do so, the owner first requests the admin list by querying the room for all users with an affiliation of 'admin'.
+
 
+
 
+
 
+
Example 172. Owner Requests Admin List
+
 
+
  
 +
'''例子 190. 所有者请求管理员列表'''
  
 +
<source lang="xml">
 
<iq from='bard@shakespeare.lit/desktopaffiliation
 
<iq from='bard@shakespeare.lit/desktopaffiliation
 
 
     id='admin3'
 
     id='admin3'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='admin'/>
 
     <item affiliation='admin'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
如果'from'地址的 <user@host> 部分和房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者.
  
 +
否则, 服务必须 MUST 接着返回管理员列表给所有者; 每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性,对任何正是一名房客(也就是正在房间里)的管理员可以 MAY 包含 'nick' 和 'role' 属性:
  
 +
'''例子 191. 服务发送管理员列表给所有者'''
  
If the <user@host> of the 'from' address does not match the bare JID of a room owner, the service MUST return a <forbidden/> error to the sender.
+
<source lang="xml">
 
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
Otherwise, the service MUST then return the admin list to the owner; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for any admin that is currently an occupant:
+
 
+
 
+
 
+
Example 173. Service Sends Admin List to Owner
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='admin3'
 
     id='admin3'
 
 
     to='bard@shakespeare.lit/globe'
 
     to='bard@shakespeare.lit/globe'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='wiccarocks@shakespeare.lit'
 
           jid='wiccarocks@shakespeare.lit'
 
 
           nick='secondwitch'/>
 
           nick='secondwitch'/>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='hag66@shakespeare.lit'/>
 
           jid='hag66@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
所有者可以 MAY 接着修改管理员列表. 为此, 所有者必须 MUST 发送修改的条目 (, "delta") 给服务; [[XEP-0045#附录G:备注|22]] 每个条目必须 MUST 包含 'affiliation'属性(通常值为 "admin" "none") 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,不能 MUST NOT 包含 'role' 属性 (它用于管理参与者之类的角色,而不是管理员之类的岗位):  
 
+
 
+
 
+
The owner MAY then modify the admin list. In order to do so, the owner MUST send the changed items (i.e., only the "delta") back to the service; [21] each item MUST include the 'affiliation' attribute (normally set to a value of "admin" or "none") and 'jid' attribute but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'role' attribute (which is used to manage roles such as participant rather than the admin affiliation):
+
 
+
 
+
 
+
Example 174. Owner Sends Modified Admin List to Service
+
 
+
  
 +
'''例子 192. 所有者发送修改的管理员列表给服务'''
  
 +
<source lang="xml">
 
<iq from='bard@shakespeare.lit/globe'
 
<iq from='bard@shakespeare.lit/globe'
 
 
     id='admin4'
 
     id='admin4'
 
+
     to='darkcave@chat.shakespeare.lit'
     to='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='none'
 
     <item affiliation='none'
 
 
           jid='hag66@shakespeare.lit'>
 
           jid='hag66@shakespeare.lit'>
 
 
     </item>
 
     </item>
 
 
     <item affiliation='admin'
 
     <item affiliation='admin'
 
 
           jid='hecate@shakespeare.lit'>
 
           jid='hecate@shakespeare.lit'>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
只有所有者被允许修改管理员列表. 如果一个非所有者试图察看或修改所有者列表, 服务必须 MUST 拒绝这个请求并返回一个 <forbidden/> 错误给发送者:
  
 +
'''例子 193. 服务对于非所有者试图修改管理员列表返回错误'''
  
 
+
<source lang="xml">
Only owners shall be allowed to modify the admin list. If a non-owner attempts to view or modify the admin list, the service MUST deny the request and return a <forbidden/> error to the sender:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 175. Service Returns Error on Attempt by Non-Owner to Modify Admin List
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='admintest'
 
     id='admintest'
 
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='admin'  
 
     <item affiliation='admin'  
 
 
           jid='hecate@shakespeare.lit'/>
 
           jid='hecate@shakespeare.lit'/>
 
 
   </query>
 
   </query>
 
+
   <error type='auth'>
   <error code='403' type='auth'>
+
 
+
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
否则, 服务必须 MUST 修改管理员列表并通知所有者成功了:
  
 +
'''例子 194. 服务通知所有者成功了'''
  
 
+
<source lang="xml">
Otherwise, the service MUST modify the admin list and then inform the owner of success:
+
<iq from='darkcave@chat.shakespeare.lit'
 
+
 
+
 
+
Example 176. Service Informs Owner of Success
+
 
+
 
+
 
+
<iq from='darkcave@macbeth.shakespeare.lit'
+
 
+
 
     id='admin4'
 
     id='admin4'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
服务必须 MUST 也为任何因前述管理员列表修改而导致的岗位变化而发送出席信息通知.
  
 +
===销毁房间===
  
 +
房间所有者必须 MUST 能够销毁一个房间, 特别是如果这个房间不是持久房间的时候. 流程如下:
  
The service MUST also send presence notifications related to any affiliation changes that result from modifying the admin list as previously described.
+
# 房间所有者请求销毁房间, 如果必要的话指出一个原因 reason 和一个备用场地.
 +
# 该房间移除所有房客(包含适当的关于备用场地和被移除的原因的信息) 并销毁房间, 即使它被定义为持久房间.
  
10.9 Destroying a Room
+
不像前述的, 本文不指定一个MUC服务实现收到一个销毁房间请求之后将会如何做. 例如, 如果房间定义为持久地, 一个实现可以 MAY 选择锁定房间I,这样它不能被重用, 把加入该房间的请求重定向到替代场地, 或邀请当前的参与者到新的房间; 无论如何, 这些行为是可选的 OPTIONAL.
  
 +
为了销毁一个房间, 房间所有者必须 MUST 发送一个 IQ set 指令到要销毁的房间的地址. 这个 <iq/> 节将包含一个遵循 'http://jabber.org/protocol/muc#owner' 名字空间的 <query/> 元素,它将包含一个 <destroy/> 元素. 替代场地的地址可以 MAY 用这个 <destroy/> 元素的 'jid' 属性来提供. 一个密码保护的替代场地可以 MAY 通过 <destroy/> 元素的 <password/> 子元素的 XML 字符数据来提供. 摧毁房间的原因可以 MAY 通过 <destroy/> 元素的 <reason/> 子元素的 XML 字符数据来提供.
  
 +
以下例子展示了协议发送和接收的元素:
  
A room owner MUST be able to destroy a room, especially if the room is persistent. The workflow is as follows:
+
'''例子 195. 所有者提交房间摧毁请求'''
 
+
 
+
 
+
  1.
+
 
+
 
+
 
+
      The room owner requests that the room be destroyed, specifying a reason and an alternate venue if desired.
+
 
+
  2.
+
 
+
 
+
 
+
      The room removes all users from the room (including appropriate information about the alternate location and the reason for being removed) and destroys the room, even if it was defined as persistent.
+
 
+
 
+
 
+
Other than the foregoing, this document does not specify what (if anything) a MUC service implementation shall do as a result of a room destruction request. For example, if the room was defined as persistent, an implementation MAY choose to lock the room ID so that it cannot be re-used, redirect enter requests to the alternate venue, or invite the current participants to the new room; however, such behavior is OPTIONAL.
+
 
+
 
+
 
+
In order to destroy a room, the room owner MUST send an IQ set to the address of the room to be destroyed. The <iq/> stanza shall contain a <query/> element qualified by the 'http://jabber.org/protocol/muc#owner' namespace, which in turn shall contain a <destroy/> element. The address of the alternate venue MAY be provided as the value of the <destroy/> element's 'jid' attribute. A password for the alternate venue MAY be provided as the XML character data of a <password/> child element of the <destroy/> element. The reason for the room destruction MAY be provided as the XML character data of a <reason/> child element of the <destroy/> element.
+
 
+
 
+
 
+
The following examples illustrate the protocol elements to be sent and received:
+
 
+
 
+
 
+
Example 177. Owner Submits Room Destruction Request
+
 
+
 
+
  
 +
<source lang="xml">
 
<iq from='crone1@shakespeare.lit/desktop'
 
<iq from='crone1@shakespeare.lit/desktop'
 
 
     id='begone'
 
     id='begone'
 
+
     to='heath@chat.shakespeare.lit'
     to='heath@macbeth.shakespeare.lit'
+
 
+
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
+
     <destroy jid='darkcave@chat.shakespeare.lit'>
     <destroy jid='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
       <reason>Macbeth doth come.</reason>
 
       <reason>Macbeth doth come.</reason>
 
 
     </destroy>
 
     </destroy>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
服务负责移除所有房客. 它不应该 SHOULD NOT 广播类型为"unavailable"的出席信息节给所有房客, 只需要发送一个"unavailable"类型的出席信息节给每个房客,这样该用户知道他或她已经从房间移除了. 如果所有者的扩展出席信息指定了一个替代场地的 JID 以及房间销毁的原因, 这个出席信息节必须 MUST 包含那些信息.
 
+
 
+
 
+
The service is responsible for removing all the occupants. It SHOULD NOT broadcast presence stanzas of type "unavailable" from all occupants, instead sending only one presence stanza of type "unavailable" to each occupant so that the user knows he or she has been removed from the room. If extended presence information specifying the JID of an alternate location and the reason for the room destruction was provided by the room owner, the presence stanza MUST include that information.
+
 
+
 
+
 
+
Example 178. Service Removes Each Occupant
+
 
+
  
 +
'''例子 196. 服务移除每个房客'''
  
 +
<source lang="xml">
 
<presence
 
<presence
 
+
     from='heath@chat.shakespeare.lit/firstwitch'
     from='heath@macbeth.shakespeare.lit/firstwitch'
+
 
+
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none' role='none'/>
 
     <item affiliation='none' role='none'/>
 
+
     <destroy jid='darkcave@chat.shakespeare.lit'>
     <destroy jid='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
       <reason>Macbeth doth come.</reason>
 
       <reason>Macbeth doth come.</reason>
 
 
     </destroy>
 
     </destroy>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
+
     from='heath@chat.shakespeare.lit/secondwitch'
     from='heath@macbeth.shakespeare.lit/secondwitch'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none' role='none'/>
 
     <item affiliation='none' role='none'/>
 
+
     <destroy jid='darkcave@chat.shakespeare.lit'>
     <destroy jid='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
       <reason>Macbeth doth come.</reason>
 
       <reason>Macbeth doth come.</reason>
 
 
     </destroy>
 
     </destroy>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
 
  
 
<presence
 
<presence
 
+
     from='heath@chat.shakespeare.lit/thirdwitch'
     from='heath@macbeth.shakespeare.lit/thirdwitch'
+
 
+
 
     to='hag66@shakespeare.lit/pda'
 
     to='hag66@shakespeare.lit/pda'
 
 
     type='unavailable'>
 
     type='unavailable'>
 
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <item affiliation='none' role='none'/>
 
     <item affiliation='none' role='none'/>
 
+
     <destroy jid='darkcave@chat.shakespeare.lit'>
     <destroy jid='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
       <reason>Macbeth doth come.</reason>
 
       <reason>Macbeth doth come.</reason>
 
 
     </destroy>
 
     </destroy>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
   
+
'''例子 197. 服务通知所有者成功销毁房间'''
 
+
 
+
 
+
Example 179. Service Informs Owner of Successful Destruction
+
 
+
 
+
 
+
<iq from='heath@macbeth.shakespeare.lit'
+
  
 +
<source lang="xml">
 +
<iq from='heath@chat.shakespeare.lit'
 
     id='begone'
 
     id='begone'
 
 
     to='crone1@shakespeare.lit/desktop'
 
     to='crone1@shakespeare.lit/desktop'
 
 
     type='result'/>
 
     type='result'/>
 +
</source>
  
   
+
如果在一个销毁请求中接收到的'from'地址的 <user@host> 和一个房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者:
  
 +
'''例子 198. 服务拒绝由非所有者提交的销毁请求'''
  
 
+
<source lang="xml">
If the <user@host> of the 'from' address received on a destroy request does not match the bare JID of a room owner, the service MUST return a <forbidden/> error to the sender:
+
<iq from='heath@chat.shakespeare.lit'
 
+
 
+
 
+
Example 180. Service Denies Destroy Request Submitted by Non-Owner
+
 
+
 
+
 
+
<iq from='heath@macbeth.shakespeare.lit'
+
 
+
 
     id='destroytest'
 
     id='destroytest'
 
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
   <query xmlns='http://jabber.org/protocol/muc#owner'>
 
+
     <destroy jid='darkcave@chat.shakespeare.lit'>
     <destroy jid='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
       <reason>Macbeth doth come.</reason>
 
       <reason>Macbeth doth come.</reason>
 
 
     </destroy>
 
     </destroy>
 
 
   </query>
 
   </query>
 
+
   <error type='auth'>
   <error code='403' type='auth'>
+
 
+
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
   
+
==错误和状态码==
 +
===错误码===
  
 +
和'http://jabber.org/protocol/muc#user' 名字空间相关的错误码相当简单, 总结于下表之中. 关于传统的错误码到XMPP格式的错误之间的映射的详细信息, 参见 [http://xmpp.org/extensions/xep-0086.html 错误条件映射] [[XEP-0045#附录G:备注|23]]; 实现应该 SHOULD 支持传统和XMPP错误处理两者.
  
 +
'''表9: http://jabber.org/protocol/muc#user 名字空间的错误码'''
  
11. Error and Status Codes
+
{|border="1" cellspacing="0"
 +
!码 !!类型 !!元素 !!上下文 !!目的
 +
|-
 +
|401 ||Error ||Presence  ||进入一个房间 ||通知用户需要密码
 +
|-
 +
|403 ||Error ||Presence  ||进入一个房间 ||通知用户他或她被房间禁止了
 +
|-
 +
|404 ||Error ||Presence  ||进入一个房间 ||通知用户房间不存在
 +
|-
 +
|405 ||Error ||Presence  ||进入一个房间 ||通知用户限制创建房间
 +
|-
 +
|406 ||Error ||Presence  ||进入一个房间 ||通知用户必须使用保留的房间昵称
 +
|-
 +
|407 ||Error ||Presence  ||进入一个房间 ||通知用户他或她不在成员列表中
 +
|-
 +
|409 ||Error ||Presence  ||进入一个房间 ||通知用户他或她的房间昵称正在使用或被别的用户注册了
 +
|-
 +
|503 ||Error ||Presence  ||进入一个房间 ||通知用户已经达到最大用户数
 +
|}
  
11.1 Error Codes
+
本文不规定和上述错误条件相关的文本字符串(即, XMPP <text/> 元素值).
  
 +
===状态码===
  
 +
多用户聊天的使用一个 <status/> 元素(特指, <status/> 元素的的 'code' 属性  ) 来传达关于用户在一个房间里的状态的信息. 随着时间的推移, 状态码的数量已经增加了很多, 而新的状态码继续被作者申请. 所以, 这些状态码现在记录在一个由XMPP登记处维护的注册表里. 细节可参考本文的 [[XEP-0045#状态码注册表|状态码注册表]].
  
The error codes associated with the 'http://jabber.org/protocol/muc#user' namespace are fairly straightforward, as summarized in the following table. For detailed information about mapping legacy error codes to XMPP-style error types and conditions, refer to Error Condition Mappings [22]; implementations SHOULD support both legacy and XMPP error handling.
+
注意: 通常, MUC 状态码倾向于沿用[http://tools.ietf.org/html/rfc2616 RFC 2616] [[XEP-0045#附录G:备注|24]] 和 [http://tools.ietf.org/html/rfc1893 RFC 1893] [[XEP-0045#附录G:备注|25]] (1xx 码表示信息, 2xx 码说明情况良好可继续, 3xx 码指定重定向被踢或被禁止的用户, x3x 码指系统状态, x7x 码指安全或策略事务, 等等) 里面的状态码的 "抽象"含义.
  
 +
注意: 如果今天来定义 MUC 协议, 它将指定一个更有弹性的, XML-友好的 途径而不是硬编码的状态数字; 然而, 现在修改状态汇报系统带来的痛苦将远大于好处, 这是为什么状态码数字保持使用至今. 本文的未来版本可能定义一个更 类XMPP 的途径来表示状态条件, 保留状态码数字但是给它们补充更多的描述性的子元素,就像 '''RFC 3920 '''里那样.
  
 +
==国际化事项==
  
Table 8: Error Codes for http://jabber.org/protocol/muc#user Namespace
+
如 '''RFC 3920''' 中所定义的, XMPP 实体 (包括 MUC 房间和 MUC 服务) 应该 SHOULD 遵守任何给定的节提供的 'xml:lang' 属性. 然而, 群聊消息的同声翻译超出了本文的范围.
  
Code Type Element Context Purpose
+
这里定义的状态和错误码允许一个客户端实现展示一个本地化的界面; 然而, 任何给定语言社区的本地化文本字符串的定义超出了本文范围.
  
401 Error Presence Entering a room Inform user that a password is required
+
尽管这里的很多数据表单字段的标签显示为英文, MUC 客户端应该 SHOULD 把这些字段展示为本地化的文本而不是英文文本.
  
403 Error Presence Entering a room Inform user that he or she is banned from the room
+
==安全事项==
 +
===用户验证和授权===
  
404 Error Presence Entering a room Inform user that the room does not exist
+
本文没有定义或要求比明文密码更安全的房间准入验证或授权方法. 然而, 这些潜在的风险可能使用 '''RFC 3920''' 描述的通过使用 TLS 和 SASL 加密通道来减轻.
  
405 Error Presence Entering a room Inform user that room creation is restricted
+
===端到端加密===
  
406 Error Presence Entering a room Inform user that the reserved roomnick must be used
+
这里没有定义没有端到端消息或会话加密方法. 用户不应该 SHOULD NOT 相信一个服务能保持通过房间发送的任何文本的安全.
  
407 Error Presence Entering a room Inform user that he or she is not on the member list
+
===隐私===
  
409 Error Presence Entering a room Inform user that his or her desired room nickname is in use or registered by another user
+
取决于房间配置, 一个房间可以公开地记录房间里发生的所有讨论. 服务必须 MUST 警告用户该房间是公开记录的,通过在该用户的初始出席信息中返回一个状态码 "170" , 并且如果房间讨论被记录 (用户的客户端也应该 SHOULD 在允许用户进入之前查询房间的配置,以"预先发现"房间是否被记录),该用户的客户端也必须 MUST 警告用户. 如果房间的配置随后修改成允许房间记录(当房间发送状态码 170 时客户端将发现),客户端也必须 MUST 警告用户 . 注意: 房间内的历史和公开房间记录是不同的, 并且很自然的一个房间不能有效地阻止房客独立维护的自有的房间记录, 它可能被公开; 用户应该 SHOULD 谨慎操作并认识到任何房间讨论可能被有效地公开.
  
503 Error Presence Entering a room Inform user that the maximum number of users has been reached
+
===匿名===
  
 +
取决于房间配置, 一个房间可以 MAY 暴光每个房客的真实 JID 给其他房客 (如果该房间是非匿名的) 并且将几乎肯定地暴光每个房客的真实 JID 给该房间的所有者和管理员(如果该房间不是全匿名的).服务必须 MUST 警告用户真实 JIDs 在房间被暴光,通过在该用户的初始出席信息中包含状态码 "100" , 并且用户的客户端必须 MUST 警告该用户 (一个用户的客户端应该 SHOULD 也在允许用户进入房间之前查询房间配置以 "预先发现" 是否真实 JIDs 会在房间中暴光). 如果房间配置随后从半匿名或全匿名修改成非匿名(当房间发送状态码 172 时客户端将发现) ,客户端必须 MUST 也警告用户,如果房间的配置随后从全匿名改成半匿名时(当房间发送状态码 173 时客户端将发现),客户端也应该 SHOULD 警告用户.
  
 +
===拒绝服务===
  
This document does not stipulate text strings (i.e., values of the XMPP <text/> element) associated with the foregoing error conditions.
+
公开的 MUC 房间能承受一定数量的攻击, 大部分能减少拒绝服务攻击. 这些攻击包括但不限于:
  
11.2 Status Codes
+
# 向房间里塞进大量的非法房客从而阻止合法用户加入房间.
 +
# 发送侮辱性的消息接着在被踢或被禁止之前离开房间; 这些侮辱性的消息包含但不限于,大量消息以阻止参与者正常跟踪会话线索或房间历史, 对参与者的人身攻击 (特别是房间管理员和主持人), 攻击性的文字, 以及垃圾网站链接.
 +
# 高频率的制造出席信息变更.
 +
# 使用过长的昵称导致无法看到完整的发言.
 +
# 辱骂房间管理员或其他房间房客.
 +
# 在一个服务里注册很多昵称然后禁止这些昵称的使用.
 +
# 模仿别的房客的昵称(例如, 通过在尾部增加一个空格或看起来相似的字符串), 然后以那个房间昵称发送消息用于欺骗房客.
  
 +
这些攻击可能被减轻不能完全被阻止,通过灵活地使用管理员操作。例如禁止用户, 有管理员权限的自动的房间机器人出席信息, 智能内容过滤的实现, 检查连接的用户的 IP 地址(在分布式的系统里不一定能实现), 应用发言规则到出席信息以及消息, 使用比Resourceprep profile of stringprep更严格的规则匹配房间昵称, 等等. 然而, 经验表明无法完全阻止这类攻击.
  
 +
===其它事项===
  
Multi-User Chat uses a <status/> element (specifically, the 'code' attribute of the <status/> element) to communicate information about a user's status in a room. Over time, the number of status codes has grown quite large, and new status codes continue to be requested of the author. Therefore, these codes are now documented in a registry maintained by the XMPP Registrar. For details, refer to the Status Codes Registry section of this document.
+
关于延迟递送符号的列入和流程的更多安全事项参见 '''XEP-0203'''.
  
 +
==IANA事项==
  
 +
本文档与[http://www.iana.org/ 互联网编号分配授权机构] [[XEP-0045#附录G:备注|26]]无关。
  
Note: In general, MUC status codes tend to follow the "philosophy" of status codes that is implicit in RFC 2616 [23] and RFC 1893 [24] (1xx codes are informational, 2xx codes specify that it is fine to continue, 3xx codes specify redirects such as being kicked or banned, x3x codes refer to system status, x7x codes refer to security or policy matters, etc.).
+
==XMPP登记事项==
  
 +
[http://xmpp.org/registrar/ XMPP登记处] [[XEP-0045#附录G:备注|27]]在它的登记处包含了以下信息.
  
 +
===协议名字空间===
  
Note: If the MUC protocol were being designed today, it would specify a more flexible, XML-friendly approach rather than hardcoded status numbers; however, at this point the pain of changing the status reporting system would be greater than the benefit of doing so, which is why the status code numbers remain in use. A future version of this document may define a more XMPP-like approach to status conditions, retaining the code numbers but supplementing them with more descriptive child elements as is done in RFC 3920.
+
XMPP登记处在它的协议名字空间注册表里包含了以下 MUC相关的名字空间:
  
12. Internationalization Considerations
+
* http://jabber.org/protocol/muc
 +
* http://jabber.org/protocol/muc#admin
 +
* http://jabber.org/protocol/muc#owner
 +
* http://jabber.org/protocol/muc#user
  
 +
===服务发现种类/类型===
  
 +
一个多用户聊天服务或房间在服务发现里是用 "conference" 种类categary 和 "text" 类型type 来标识的.
  
As specified in RFC 3920, XMPP entities (including MUC rooms and MUC services) SHOULD respect the value of the 'xml:lang' attribute provided with any given stanza. However, simultaneous translation of groupchat messages is out of scope for this document.
+
===服务发现特性===
 
+
 
+
 
+
The status and error codes defined herein enable a client implementation to present a localized interface; however, definition of the localized text strings for any given language community is out of scope for this document.
+
 
+
 
+
 
+
Although the labels for various data form fields are shown here in English, MUC clients SHOULD present localized text for these fields rather than the English text.
+
 
+
13. Security Considerations
+
 
+
13.1 User Authentication and Authorization
+
 
+
 
+
 
+
No room entrance authentication or authorization method more secure than cleartext passwords is defined or required by this document. However, the risks involved can mitigated by the use of channel encryption and strong authentication via TLS and SASL as described in RFC 3920.
+
 
+
13.2 End-to-End Encryption
+
 
+
 
+
 
+
No end-to-end message or session encryption method is specified herein. Users SHOULD NOT trust a service to keep secret any text sent through a room.
+
 
+
13.3 Privacy
+
 
+
 
+
 
+
Depending on room configuration, a room may publicly log all discussions held in the room. A service MUST warn the user that the room is publicly logged by returning a status code of "170" with the user's initial presence, and user's the client MUST so warn the user if the room discussion is logged (a user's client SHOULD also query the room for its configuration prior to allowing the user to enter in order to "pre-discover" whether the room is logged). A client MUST also warn the user if the room's configuration is subsequently modified to allow room logging (which the client will discover when the room sends status code 170). Note: In-room history is different from public room logging, and naturally a room cannot effectively prevent occupants from separately maintaining their own room logs, which may become public; users SHOULD exercise due caution and consider any room discussions to be effectively public.
+
 
+
13.4 Anonymity
+
 
+
 
+
 
+
Depending on room configuration, a room MAY expose each occupant's real JID to other occupants (if the room is non-anonymous) and will almost certainly expose each occupant's real JID to the room owners and administrators (if the room is not fully-anonymous). A service MUST warn the user that real JIDs are exposed in the room by returning a status code of "100" with the user's initial presence, and the user's client MUST so warn the user (a user's client SHOULD also query the room for its configuration prior to allowing the user to enter in order to "pre-discover" whether real JIDs are exposed in the room). A client MUST also warn the user if the room's configuration is subsequently modified from semi-anonymous or fully-anonymous to non-anonymous (which the client will discover when the room sends status code 172) and SHOULD warn the user if the room's configuration is subsequently modified from fully-anonymous to semi-anonymous (which the client will discover when the room sends status code 173).
+
 
+
14. IANA Considerations
+
 
+
 
+
 
+
This document requires no interaction with the Internet Assigned Numbers Authority (IANA) [25].
+
 
+
15. XMPP Registrar Considerations
+
 
+
 
+
 
+
The XMPP Registrar [26] includes the following information in its registries.
+
 
+
15.1 Protocol Namespaces
+
 
+
 
+
 
+
The XMPP Registrar includes the following MUC-related namespaces in its registry of protocol namespaces:
+
 
+
 
+
 
+
    * http://jabber.org/protocol/muc
+
 
+
    * http://jabber.org/protocol/muc#admin
+
 
+
    * http://jabber.org/protocol/muc#owner
+
 
+
    * http://jabber.org/protocol/muc#unique
+
 
+
    * http://jabber.org/protocol/muc#user
+
 
+
 
+
 
+
15.2 Service Discovery Category/Type
+
 
+
 
+
 
+
A Multi-User Chat service or room is identified by the "conference" category and the "text" type within Service Discovery.
+
 
+
15.3 Service Discovery Features
+
 
+
 
+
 
+
There are many features related to a MUC service or room that can be discovered by means of Service Discovery. The most fundamental of these is the 'http://jabber.org/protocol/muc' namespace. In addition, a MUC room SHOULD provide information about the specific room features it implements, such as password protection and room moderation.
+
 
+
 
+
 
+
Registry Submission
+
  
 +
有很多和MUC相关的服务或房间相关的特性可以被"服务发现"来发现. 这里面最基本的是 'http://jabber.org/protocol/muc' 名字空间. 另外, 一个MUC房间应该 SHOULD 提供关于它实现的特定房间特性的信息, 例如密码保护和房间主持.
  
 +
'''注册提交'''
  
 +
<source lang="xml">
 
<var>
 
<var>
 
 
   <name>http://jabber.org/protocol/muc#register</name>
 
   <name>http://jabber.org/protocol/muc#register</name>
 
 
   <desc>Support for the muc#register FORM_TYPE</desc>
 
   <desc>Support for the muc#register FORM_TYPE</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>http://jabber.org/protocol/muc#roomconfig</name>
 
   <name>http://jabber.org/protocol/muc#roomconfig</name>
 
 
   <desc>Support for the muc#roomconfig FORM_TYPE</desc>
 
   <desc>Support for the muc#roomconfig FORM_TYPE</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>http://jabber.org/protocol/muc#roominfo</name>
 
   <name>http://jabber.org/protocol/muc#roominfo</name>
 
 
   <desc>Support for the muc#roominfo FORM_TYPE</desc>
 
   <desc>Support for the muc#roominfo FORM_TYPE</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_hidden</name>
 
   <name>muc_hidden</name>
 
 
   <desc>Hidden room in Multi-User Chat (MUC)</desc>
 
   <desc>Hidden room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_membersonly</name>
 
   <name>muc_membersonly</name>
 
 
   <desc>Members-only room in Multi-User Chat (MUC)</desc>
 
   <desc>Members-only room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_moderated</name>
 
   <name>muc_moderated</name>
 
 
   <desc>Moderated room in Multi-User Chat (MUC)</desc>
 
   <desc>Moderated room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_nonanonymous</name>
 
   <name>muc_nonanonymous</name>
 
 
   <desc>Non-anonymous room in Multi-User Chat (MUC)</desc>
 
   <desc>Non-anonymous room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_open</name>
 
   <name>muc_open</name>
 
 
   <desc>Open room in Multi-User Chat (MUC)</desc>
 
   <desc>Open room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_passwordprotected</name>
 
   <name>muc_passwordprotected</name>
 
 
   <desc>Password-protected room in Multi-User Chat (MUC)</desc>
 
   <desc>Password-protected room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_persistent</name>
 
   <name>muc_persistent</name>
 
 
   <desc>Persistent room in Multi-User Chat (MUC)</desc>
 
   <desc>Persistent room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_public</name>
 
   <name>muc_public</name>
 
 
   <desc>Public room in Multi-User Chat (MUC)</desc>
 
   <desc>Public room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_rooms</name>
 
   <name>muc_rooms</name>
 
 
   <desc>List of MUC rooms (each as a separate item)</desc>
 
   <desc>List of MUC rooms (each as a separate item)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_semianonymous</name>
 
   <name>muc_semianonymous</name>
 
 
   <desc>Semi-anonymous room in Multi-User Chat (MUC)</desc>
 
   <desc>Semi-anonymous room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_temporary</name>
 
   <name>muc_temporary</name>
 
 
   <desc>Temporary room in Multi-User Chat (MUC)</desc>
 
   <desc>Temporary room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_unmoderated</name>
 
   <name>muc_unmoderated</name>
 
 
   <desc>Unmoderated room in Multi-User Chat (MUC)</desc>
 
   <desc>Unmoderated room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 
 
<var>
 
<var>
 
 
   <name>muc_unsecured</name>
 
   <name>muc_unsecured</name>
 
 
   <desc>Unsecured room in Multi-User Chat (MUC)</desc>
 
   <desc>Unsecured room in Multi-User Chat (MUC)</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
</var>
 
</var>
 +
</source>
  
   
+
===知名服务发现节点===
  
 +
知名服务发现节点 'http://jabber.org/protocol/muc#rooms' 允许发现一个用户是哪个房间的房客.
  
 +
知名服务发现节点 'x-roomuser-item' 允许一个用户从房间外发现自己的已注册房间昵称.
  
15.4 Well-Known Service Discovery Nodes
+
知名服务发现节点 'http://jabber.org/protocol/muc#traffic' 允许发现通过一个房间能发送哪些名字空间的通讯(参见本文允许的 [[XEP-0045#允许的通讯|允许的通讯]]章节).
  
 +
===字段标准化===
  
 +
[http://xmpp.org/extensions/xep-0068.html 数据表单的字段标准化] [[XEP-0045#附录G:备注|28]] 定义了用于遵循特定名字空间的数据表单的字段标准化的过程. 在 MUC 里面, 使用了四种这类表单: 房间注册 ( "muc#register" FORM_TYPE), 请求发言权和批准请求 ("muc#request"), 房间配置 ("muc#roomconfig"), 以及用于房间信息的服务发现扩展 ("muc#roominfo"). 这些保留的字段定义如下.
  
The well-known Service Discovery node 'http://jabber.org/protocol/muc#rooms' enables discovery of the rooms in which a user is an occupant.
+
====muc#register FORM_TYPE====
 
+
 
+
 
+
The well-known Service Discovery node 'x-roomuser-item' enables a user to discover his or her registered roomnick from outside the room.
+
 
+
 
+
 
+
The well-known Service Discovery node 'http://jabber.org/protocol/muc#traffic' enables discovery of the namespaces that are allowed in traffic sent through a room (see the Allowable Traffic section of this document).
+
 
+
15.5 Field Standardization
+
 
+
 
+
 
+
Field Standardization for Data Forms [27] defines a process for standardizing the fields used within Data Forms qualified by a particular namespace. Within MUC, there are four uses of such forms: room registration (the "muc#register" FORM_TYPE), requesting voice and approving voice requests ("muc#request"), room configuration ("muc#roomconfig"), and service discovery extensions for room information ("muc#roominfo"). The reserved fields are defined below.
+
 
+
15.5.1 muc#register FORM_TYPE
+
 
+
 
+
 
+
Registry Submission
+
 
+
  
 +
'''注册处提交'''
  
 +
<source lang="xml">
 
<form_type>
 
<form_type>
 
 
   <name>http://jabber.org/protocol/muc#register</name>
 
   <name>http://jabber.org/protocol/muc#register</name>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
   <desc>
 
   <desc>
 
 
     Forms enabling user registration with a
 
     Forms enabling user registration with a
 
 
     Multi-User Chat (MUC) room or admin approval
 
     Multi-User Chat (MUC) room or admin approval
 
 
     of user registration requests.
 
     of user registration requests.
 
 
   </desc>
 
   </desc>
 
 
   <field  
 
   <field  
 
 
     var='muc#register_allow'
 
     var='muc#register_allow'
 
 
     type='boolean'
 
     type='boolean'
 
 
     label='Allow this person to register with the room?'/>
 
     label='Allow this person to register with the room?'/>
 
 
   <field
 
   <field
 
 
       var='muc#register_email'
 
       var='muc#register_email'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Email Address'/>
 
       label='Email Address'/>
 
 
   <field
 
   <field
 
 
       var='muc#register_faqentry'
 
       var='muc#register_faqentry'
 
 
       type='text-multi'
 
       type='text-multi'
 
 
       label='FAQ Entry'/>
 
       label='FAQ Entry'/>
 
 
   <field
 
   <field
 
 
       var='muc#register_first'
 
       var='muc#register_first'
 
 
       type='text-single'
 
       type='text-single'
 
+
       label='Given Name'/>
       label='First Name'/>
+
 
+
 
   <field
 
   <field
 
 
       var='muc#register_last'
 
       var='muc#register_last'
 
 
       type='text-single'
 
       type='text-single'
 
+
       label='Family Name'/>
       label='Last Name'/>
+
 
+
 
   <field
 
   <field
 
 
       var='muc#register_roomnick'
 
       var='muc#register_roomnick'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Desired Nickname'/>
 
       label='Desired Nickname'/>
 
 
   <field
 
   <field
 
 
       var='muc#register_url'
 
       var='muc#register_url'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Your URL'/>
 
       label='Your URL'/>
 
 
</form_type>
 
</form_type>
 +
</source>
  
     
+
====muc#request FORM_TYPE====
 
+
 
+
 
+
15.5.2 muc#request FORM_TYPE
+
 
+
 
+
 
+
Registry Submission
+
 
+
  
 +
'''注册处提交'''
  
 +
<source lang="xml">
 
<form_type>
 
<form_type>
 
 
   <name>http://jabber.org/protocol/muc#request</name>
 
   <name>http://jabber.org/protocol/muc#request</name>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
   <desc>
 
   <desc>
 
 
     Forms enabling voice requests in a  
 
     Forms enabling voice requests in a  
 
 
     Multi-User Chat (MUC) room or admin
 
     Multi-User Chat (MUC) room or admin
 
 
     approval of such requests.
 
     approval of such requests.
 
 
   </desc>
 
   </desc>
 
 
   <field var='muc#role'
 
   <field var='muc#role'
 
 
         type='text-single'
 
         type='text-single'
 
 
         label='Requested role'/>
 
         label='Requested role'/>
 
 
   <field var='muc#jid'
 
   <field var='muc#jid'
 
 
         type='text-single'
 
         type='text-single'
 
 
         label='User ID'/>
 
         label='User ID'/>
 
 
   <field var='muc#roomnick'
 
   <field var='muc#roomnick'
 
 
         type='text-single'
 
         type='text-single'
 
 
         label='Room Nickname'/>
 
         label='Room Nickname'/>
 
 
   <field var='muc#request_allow'
 
   <field var='muc#request_allow'
 
 
         type='boolean'
 
         type='boolean'
 
 
         label='Whether to grant voice'/>
 
         label='Whether to grant voice'/>
 
 
</form_type>
 
</form_type>
 +
</source>
  
     
+
====muc#roomconfig FORM_TYPE====
 
+
 
+
 
+
15.5.3 muc#roomconfig FORM_TYPE
+
 
+
 
+
 
+
Registry Submission
+
 
+
  
 +
'''注册处提交'''
  
 +
<source lang="xml">
 
<form_type>
 
<form_type>
 
 
   <name>http://jabber.org/protocol/muc#roomconfig</name>
 
   <name>http://jabber.org/protocol/muc#roomconfig</name>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
   <desc>
 
   <desc>
 
 
     Forms enabling creation and configuration of
 
     Forms enabling creation and configuration of
 
 
     a Multi-User Chat (MUC) room.
 
     a Multi-User Chat (MUC) room.
 
 
   </desc>
 
   </desc>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_allowinvites'
 
       var='muc#roomconfig_allowinvites'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether to Allow Occupants to Invite Others'/>
 
       label='Whether to Allow Occupants to Invite Others'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_changesubject'
 
       var='muc#roomconfig_changesubject'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether to Allow Occupants to Change Subject'/>
 
       label='Whether to Allow Occupants to Change Subject'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_enablelogging'
 
       var='muc#roomconfig_enablelogging'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether to Enable Public Logging of Room Conversations'/>
 
       label='Whether to Enable Public Logging of Room Conversations'/>
 
 
   <field
 
   <field
 
+
      var='muc#roomconfig_getmemberlist'
 +
      type='list-multi'
 +
      label='Roles and Affiliations that May Retrieve Member List'/>
 +
  <field
 
       var='muc#roomconfig_lang'
 
       var='muc#roomconfig_lang'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Natural Language for Room Discussions'/>
 
       label='Natural Language for Room Discussions'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_pubsub'
 
       var='muc#roomconfig_pubsub'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='XMPP URI of Associated Publish-Subcribe Node'/>
 
       label='XMPP URI of Associated Publish-Subcribe Node'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_maxusers'
 
       var='muc#roomconfig_maxusers'
 
 
       type='list-single'
 
       type='list-single'
 
 
       label='Maximum Number of Room Occupants'/>
 
       label='Maximum Number of Room Occupants'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_membersonly'
 
       var='muc#roomconfig_membersonly'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether an Make Room Members-Only'/>
 
       label='Whether an Make Room Members-Only'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_moderatedroom'
 
       var='muc#roomconfig_moderatedroom'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether to Make Room Moderated'/>
 
       label='Whether to Make Room Moderated'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_passwordprotectedroom'
 
       var='muc#roomconfig_passwordprotectedroom'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether a Password is Required to Enter'/>
 
       label='Whether a Password is Required to Enter'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_persistentroom'
 
       var='muc#roomconfig_persistentroom'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether to Make Room Persistent'/>
 
       label='Whether to Make Room Persistent'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_presencebroadcast'
 
       var='muc#roomconfig_presencebroadcast'
 
 
       type='list-multi'
 
       type='list-multi'
 
 
       label='Roles for which Presence is Broadcast'/>
 
       label='Roles for which Presence is Broadcast'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_publicroom'
 
       var='muc#roomconfig_publicroom'
 
 
       type='boolean'
 
       type='boolean'
 
 
       label='Whether to Allow Public Searching for Room'/>
 
       label='Whether to Allow Public Searching for Room'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_roomadmins'
 
       var='muc#roomconfig_roomadmins'
 
 
       type='jid-multi'
 
       type='jid-multi'
 
 
       label='Full List of Room Admins'/>
 
       label='Full List of Room Admins'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_roomdesc'
 
       var='muc#roomconfig_roomdesc'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Short Description of Room'/>
 
       label='Short Description of Room'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_roomname'
 
       var='muc#roomconfig_roomname'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Natural-Language Room Name'/>
 
       label='Natural-Language Room Name'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_roomowners'
 
       var='muc#roomconfig_roomowners'
 
 
       type='jid-multi'
 
       type='jid-multi'
 
 
       label='Full List of Room Owners'/>
 
       label='Full List of Room Owners'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_roomsecret'
 
       var='muc#roomconfig_roomsecret'
 
 
       type='text-private'
 
       type='text-private'
 
 
       label='The Room Password'/>
 
       label='The Room Password'/>
 
 
   <field
 
   <field
 
 
       var='muc#roomconfig_whois'
 
       var='muc#roomconfig_whois'
 
 
       type='list-single'
 
       type='list-single'
 
 
       label='Affiliations that May Discover Real JIDs of Occupants'/>
 
       label='Affiliations that May Discover Real JIDs of Occupants'/>
 
 
</form_type>
 
</form_type>
 +
</source>
  
     
+
====muc#roominfo FORM_TYPE====
 
+
 
+
 
+
15.5.4 muc#roominfo FORM_TYPE
+
 
+
 
+
 
+
Registry Submission
+
 
+
  
 +
'''注册处提交'''
  
 +
<source lang="xml">
 
<form_type>
 
<form_type>
 
 
   <name>http://jabber.org/protocol/muc#roominfo</name>
 
   <name>http://jabber.org/protocol/muc#roominfo</name>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
   <desc>
 
   <desc>
 
 
     Forms enabling the communication of extended service discovery
 
     Forms enabling the communication of extended service discovery
 
 
     information about a Multi-User Chat (MUC) room.
 
     information about a Multi-User Chat (MUC) room.
 
 
   </desc>
 
   </desc>
 
 
   <field
 
   <field
 
 
       var='muc#roominfo_contactjid'
 
       var='muc#roominfo_contactjid'
 
 
       type='jid-multi'
 
       type='jid-multi'
 
 
       label='Contact Addresses (normally, room owner or owners)'/>
 
       label='Contact Addresses (normally, room owner or owners)'/>
 
 
   <field
 
   <field
 
 
       var='muc#roominfo_description'
 
       var='muc#roominfo_description'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Short Description of Room'/>
 
       label='Short Description of Room'/>
 
 
   <field
 
   <field
 
 
       var='muc#roominfo_lang'
 
       var='muc#roominfo_lang'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Natural Language for Room Discussions'/>
 
       label='Natural Language for Room Discussions'/>
 
 
   <field
 
   <field
 
+
      var='muc#roominfo_ldapgroup'
 +
      type='text-single'
 +
      label='An associated LDAP group that defines room membership;
 +
            this should be an LDAP Distinguished Name according to an
 +
            implementation-specific or deployment-specific definition
 +
            of a group.'/>
 +
  <field
 
       var='muc#roominfo_logs'
 
       var='muc#roominfo_logs'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='URL for Archived Discussion Logs'/>
 
       label='URL for Archived Discussion Logs'/>
 
 
   <field
 
   <field
 
 
       var='muc#roominfo_occupants'
 
       var='muc#roominfo_occupants'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Current Number of Occupants in Room'/>
 
       label='Current Number of Occupants in Room'/>
 
 
   <field
 
   <field
 
 
       var='muc#roominfo_subject'
 
       var='muc#roominfo_subject'
 
 
       type='text-single'
 
       type='text-single'
 
 
       label='Current Subject or Discussion Topic in Room'/>
 
       label='Current Subject or Discussion Topic in Room'/>
 
+
  <field
 +
      var='muc#roominfo_subjectmod'
 +
      type='boolean'
 +
      label='The room subject can be modified by participants'/>
 
</form_type>
 
</form_type>
 +
</source>
  
     
+
===状态码登记处===
 
+
====过程====
 
+
 
+
15.6 Status Codes Registry
+
 
+
15.6.1 Process
+
 
+
 
+
 
+
The XMPP Registrar maintains a registry of values for the 'code' attribute of the <status/> element when qualified by the 'http://jabber.org/protocol/muc#user' namespace.
+
 
+
 
+
 
+
In order to submit new values to this registry, the registrant must define an XML fragment of the following form and either include it in the relevant XMPP Extension Protocol or send it to the email address <registrar@xmpp.org>:
+
  
 +
XMPP注册员为遵循 'http://jabber.org/protocol/muc#user' 名字空间的<status/> 元素的 'code' 属性维护注册表中的值 .
  
 +
为了提交新值给这个注册表, 注册人将按以下格式定义一个XML段并把它包含在相关的XMPP扩展协议中,或者发到<registrar@xmpp.org>:
  
 +
<source lang="xml">
 
<statuscode>
 
<statuscode>
 
 
   <number>the three-digit code number</number>
 
   <number>the three-digit code number</number>
 
+
   <stanza>the stanza type of which it is a child (message or presence)</stanza>
   <stanza>the stanza type of which it is a child (message or presence)</desc>
+
 
+
 
   <context>the use case or situation in which the status is used</context>
 
   <context>the use case or situation in which the status is used</context>
 
 
   <purpose>a natural-language description of the meaning</purpose>
 
   <purpose>a natural-language description of the meaning</purpose>
 
 
   <child>the descriptive child element (reserved for future use)</child>
 
   <child>the descriptive child element (reserved for future use)</child>
 
 
</statuscode>
 
</statuscode>
 +
</source>
  
     
+
注册人可一次注册多个状态码,每个状态码包含在独立的<statuscode/>元素中。
 
+
 
+
 
+
The registrant may register more than one status code at a time, each contained in a separate <statuscode/> element.
+
 
+
15.6.2 Initial Submission
+
 
+
 
+
 
+
As part of this document, the following status codes are registered:
+
  
 +
====初始提交====
  
 +
作为本文的一部分, 以下状态码已被注册了:
  
 +
<source lang="xml">
 
<statuscode>
 
<statuscode>
 
 
   <number>100</number>
 
   <number>100</number>
 
 
   <stanza>message or presence</stanza>
 
   <stanza>message or presence</stanza>
 
 
   <context>Entering a room</context>
 
   <context>Entering a room</context>
 
 
   <purpose>Inform user that any occupant is allowed to see the user's full JID</purpose>
 
   <purpose>Inform user that any occupant is allowed to see the user's full JID</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>101</number>
 
   <number>101</number>
 
 
   <stanza>message (out of band)</stanza>
 
   <stanza>message (out of band)</stanza>
 
 
   <context>Affiliation change</context>
 
   <context>Affiliation change</context>
 
 
   <purpose>Inform user that his or her affiliation changed while not in the room</purpose>
 
   <purpose>Inform user that his or her affiliation changed while not in the room</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>102</number>
 
   <number>102</number>
 
 
   <stanza>message</stanza>
 
   <stanza>message</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>Inform occupants that room now shows unavailable members</purpose>
 
   <purpose>Inform occupants that room now shows unavailable members</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>103</number>
 
   <number>103</number>
 
 
   <stanza>message</stanza>
 
   <stanza>message</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>Inform occupants that room now does not show unavailable members</purpose>
 
   <purpose>Inform occupants that room now does not show unavailable members</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>104</number>
 
   <number>104</number>
 
 
   <stanza>message</stanza>
 
   <stanza>message</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>
 
   <purpose>
 
 
     Inform occupants that a non-privacy-related room configuration change has occurred
 
     Inform occupants that a non-privacy-related room configuration change has occurred
 
 
   </purpose>
 
   </purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>110</number>
 
   <number>110</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Any room presence</context>
 
   <context>Any room presence</context>
 
 
   <purpose>Inform user that presence refers to one of its own room occupants</purpose>
 
   <purpose>Inform user that presence refers to one of its own room occupants</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>170</number>
 
   <number>170</number>
 
 
   <stanza>message or initial presence</stanza>
 
   <stanza>message or initial presence</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>Inform occupants that room logging is now enabled</purpose>
 
   <purpose>Inform occupants that room logging is now enabled</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>171</number>
 
   <number>171</number>
 
 
   <stanza>message</stanza>
 
   <stanza>message</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>Inform occupants that room logging is now disabled</purpose>
 
   <purpose>Inform occupants that room logging is now disabled</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>172</number>
 
   <number>172</number>
 
 
   <stanza>message</stanza>
 
   <stanza>message</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>Inform occupants that the room is now non-anonymous</purpose>
 
   <purpose>Inform occupants that the room is now non-anonymous</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>173</number>
 
   <number>173</number>
 
 
   <stanza>message</stanza>
 
   <stanza>message</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>Inform occupants that the room is now semi-anonymous</purpose>
 
   <purpose>Inform occupants that the room is now semi-anonymous</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>174</number>
 
   <number>174</number>
 
 
   <stanza>message</stanza>
 
   <stanza>message</stanza>
 
 
   <context>Configuration change</context>
 
   <context>Configuration change</context>
 
 
   <purpose>Inform occupants that the room is now fully-anonymous</purpose>
 
   <purpose>Inform occupants that the room is now fully-anonymous</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>201</number>
 
   <number>201</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Entering a room</context>
 
   <context>Entering a room</context>
 
 
   <purpose>Inform user that a new room has been created</purpose>
 
   <purpose>Inform user that a new room has been created</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>210</number>
 
   <number>210</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Entering a room</context>
 
   <context>Entering a room</context>
 
 
   <purpose>Inform user that service has assigned or modified occupant's roomnick</purpose>
 
   <purpose>Inform user that service has assigned or modified occupant's roomnick</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>301</number>
 
   <number>301</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Removal from room</context>
 
   <context>Removal from room</context>
 
 
   <purpose>Inform user that he or she has been banned from the room</purpose>
 
   <purpose>Inform user that he or she has been banned from the room</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>303</number>
 
   <number>303</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Exiting a room</context>
 
   <context>Exiting a room</context>
 
 
   <purpose>Inform all occupants of new room nickname</purpose>
 
   <purpose>Inform all occupants of new room nickname</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>307</number>
 
   <number>307</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Removal from room</context>
 
   <context>Removal from room</context>
 
 
   <purpose>Inform user that he or she has been kicked from the room</purpose>
 
   <purpose>Inform user that he or she has been kicked from the room</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>321</number>
 
   <number>321</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Removal from room</context>
 
   <context>Removal from room</context>
 
 
   <purpose>Inform user that he or she is being removed from the room  
 
   <purpose>Inform user that he or she is being removed from the room  
 
 
     because of an affiliation change</purpose>
 
     because of an affiliation change</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>322</number>
 
   <number>322</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Removal from room</context>
 
   <context>Removal from room</context>
 
 
   <purpose>Inform user that he or she is being removed from the room  
 
   <purpose>Inform user that he or she is being removed from the room  
 
 
     because the room has been changed to members-only and the user  
 
     because the room has been changed to members-only and the user  
 
 
     is not a member</purpose>
 
     is not a member</purpose>
 
 
</statuscode>
 
</statuscode>
 
 
<statuscode>
 
<statuscode>
 
 
   <number>332</number>
 
   <number>332</number>
 
 
   <stanza>presence</stanza>
 
   <stanza>presence</stanza>
 
 
   <context>Removal from room</context>
 
   <context>Removal from room</context>
 
 
   <purpose>Inform user that he or she is being removed from the room  
 
   <purpose>Inform user that he or she is being removed from the room  
 
 
     because of a system shutdown</purpose>
 
     because of a system shutdown</purpose>
 
 
</statuscode>
 
</statuscode>
 +
</source>
  
     
+
===URI查询类型===
  
 +
作为由[http://www.xmpp.org/extensions/xep-0147.html XMPP URI Query Components] [[XEP-00450#附录G:备注|29]]授权的机构,XMPP注册员维护着一个用于 XMPP URIs 的查询和键-值对的注册表(见<[http://www.xmpp.org/registrar/querytypes.html http://www.xmpp.org/registrar/querytypes.html]>)。
  
 +
====join====
  
15.7 URI Query Types
+
"join" 查询类型被注册为一个 MUC相关的动作, 伴随一个可选的键 "password".
  
 +
'''例子 199. Join动作: IRI/URI'''
  
 +
<source lang="xml">
 +
xmpp:darkcave@chat.shakespeare.lit?join
 +
</source>
  
As authorized by XMPP URI Query Components [28], the XMPP Registrar maintains a registry of queries and key-value pairs for use in XMPP URIs (see <http://www.xmpp.org/registrar/querytypes.html>).
+
应用必须 MUST 要么展示一个界面允许用户提供一个房间昵称,要么基于配置好的选项或昵称发现来获取这个房间昵称.
  
15.7.1 join
+
'''例子 200. Join动作: 结果节'''
 
+
 
+
 
+
The "join" querytype is registered as a MUC-related action, with an optional key of "password".
+
 
+
 
+
 
+
Example 181. Join Action: IRI/URI
+
 
+
 
+
 
+
xmpp:darkcave@macbeth.shakespeare.lit?join
+
 
+
     
+
 
+
 
+
 
+
The application MUST either present an interface enabling the user to provide a room nickname or populate the room nickname based on configured preferences or nickname discovery.
+
 
+
 
+
 
+
Example 182. Join Action: Resulting Stanza
+
 
+
 
+
 
+
<presence to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
  
 +
<source lang="xml">
 +
<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
join 动作可以 MAY 为这房间包含一个密码. 自然的, 对一个包含了房间密码的 URI 的访问必须 MUST 得到适当的控制.
  
 +
'''例子 201. Join动作包含密码: IRI/URI'''
  
 +
<source lang="xml">
 +
xmpp:darkcave@chat.shakespeare.lit?join;password=cauldronburn
 +
</source>
  
The join action MAY include a password for the room. Naturally, access to a URI that includes a room password MUST be appropriately controlled.
+
'''例子 202. Join动作包含密码: 结果节'''
 
+
 
+
 
+
Example 183. Join Action with Password: IRI/URI
+
 
+
 
+
 
+
xmpp:darkcave@macbeth.shakespeare.lit?join;password=cauldronburn
+
 
+
     
+
 
+
 
+
 
+
Example 184. Join Action with Password: Resulting Stanza
+
 
+
 
+
 
+
<presence to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
  
 +
<source lang="xml">
 +
<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
   <x xmlns='http://jabber.org/protocol/muc'>
 
 
     <password>cauldronburn</password>
 
     <password>cauldronburn</password>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 +
</source>
  
     
+
以下提交注册 "join" 查询类型.
 
+
 
+
 
+
The following submission registers the "join" querytype.
+
 
+
 
+
  
 +
<source lang="xml">
 
<querytype>
 
<querytype>
 
 
   <name>join</name>
 
   <name>join</name>
 
 
   <proto>http://jabber.org/protocol/muc</proto>
 
   <proto>http://jabber.org/protocol/muc</proto>
 
 
   <desc>enables joining a multi-user chat room</desc>
 
   <desc>enables joining a multi-user chat room</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
   <keys>
 
   <keys>
 
 
     <key>
 
     <key>
 
 
       <name>password</name>
 
       <name>password</name>
 
 
       <desc>the password required to enter a multi-user chat room</desc>
 
       <desc>the password required to enter a multi-user chat room</desc>
 
 
     </key>
 
     </key>
 
 
   </keys>
 
   </keys>
 
 
</querytype>
 
</querytype>
 +
</source>
  
     
+
====invite====
  
 +
"invite" 查询类型被注册为一个 MUC相关的动作, 伴随一个可选的键 "jid".
  
 +
'''例子 203. Invite动作: IRI/URI'''
  
15.7.2 invite
+
<source lang="xml">
 +
xmpp:darkcave@chat.shakespeare.lit?invite;jid=hecate@shakespeare.lit
 +
</source>
  
 +
如果加入中的用户还未在房间里, 应用必须 MUST 发送两个节: 第一个加入房间,第二个邀请另一个人. 如果加入中的用户已经在房间里, 应用将只发送邀请节.
  
 +
'''例子 204. Invite动作: 结果节(s)'''
  
The "invite" querytype is registered as a MUC-related action, with an optional key of "jid".
+
<source lang="xml">
 
+
<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
 
+
 
+
Example 185. Invite Action: IRI/URI
+
 
+
 
+
 
+
xmpp:darkcave@macbeth.shakespeare.lit?invite;jid=hecate@shakespeare.lit
+
 
+
     
+
 
+
 
+
 
+
If the joining user is not yet in the room, the application MUST send two stanzas: the first to join the room and the second to invite the other individual. If the joining user is in the room already, the application shall send only the invitation stanza.
+
 
+
 
+
 
+
Example 186. Invite Action: Resulting Stanza(s)
+
 
+
 
+
 
+
<presence to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
 
</presence>
 
</presence>
  
 
+
<message to='darkcave@chat.shakespeare.lit'>
 
+
<message to='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite to='hecate@shakespeare.lit'/>
 
     <invite to='hecate@shakespeare.lit'/>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
     
+
URI 可以包含多个邀请:
  
 +
'''例子 205. Invite动作包含多个邀请: IRI/URI'''
  
 +
<source lang="xml">
 +
xmpp:darkcave@chat.shakespeare.lit?invite;jid=hecate@shakespeare.lit;jid=bard@shakespeare.lit
 +
</source>
  
The URI may include multiple invitees:
+
'''例子 206. Invite动作包含多个邀请: 结果节'''
 
+
 
+
 
+
Example 187. Invite Action With Multiple Invitees: IRI/URI
+
 
+
 
+
 
+
xmpp:darkcave@macbeth.shakespeare.lit?invite;jid=hecate@shakespeare.lit;jid=bard@shakespeare.lit
+
 
+
     
+
 
+
 
+
 
+
Example 188. Invite Action With Multiple Invitees: Resulting Stanza
+
 
+
 
+
 
+
<message to='darkcave@macbeth.shakespeare.lit'>
+
  
 +
<source lang="xml">
 +
<message to='darkcave@chat.shakespeare.lit'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite to='hecate@shakespeare.lit'/>
 
     <invite to='hecate@shakespeare.lit'/>
 
 
     <invite to='bard@shakespeare.lit'/>
 
     <invite to='bard@shakespeare.lit'/>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
     
+
URI 也可以包含一个密码:
  
 +
'''例子 207. Invite动作包含密码: IRI/URI'''
  
 +
<source lang="xml">
 +
xmpp:darkcave@chat.shakespeare.lit?invite;jid=hecate@shakespeare.lit;password=cauldronburn
 +
</source>
  
The URI may also include a password:
+
如果加入中的用户还未在房间里, 应用必须 MUST 发送两个节: 第一个加入房间,第二个邀请另一个人. 如果加入中的用户已经在房间里, 应用将只发送邀请节.
  
 +
'''例子 208. Invite动作包含密码: 结果节(s)'''
  
 
+
<source lang="xml">
Example 189. Invite Action With Password: IRI/URI
+
<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
 
+
 
+
 
+
xmpp:darkcave@macbeth.shakespeare.lit?invite;jid=hecate@shakespeare.lit;password=cauldronburn
+
 
+
     
+
 
+
 
+
 
+
If the joining user is not yet in the room, the application MUST send two stanzas: the first to join the room and the second to invite the other individual. If the joining user is in the room already, the application shall send only the invitation stanza.
+
 
+
 
+
 
+
Example 190. Invite Action With Password: Resulting Stanza(s)
+
 
+
 
+
 
+
<presence to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
   <x xmlns='http://jabber.org/protocol/muc'/>
 
 
</presence>
 
</presence>
  
 
+
<message to='darkcave@chat.shakespeare.lit'>
 
+
<message to='darkcave@macbeth.shakespeare.lit'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
+
     <invite to='hecate@shakespeare.lit'/>
     <invite to='hecate@shakespeare.lit'>
+
    <password>cauldronburn</password>
 
+
      <password>cauldronburn</password>
+
 
+
    </invite>
+
 
+
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 +
</source>
  
     
+
以下提交注册 "invite" 查询类型.
 
+
 
+
 
+
 
+
 
+
The following submission registers the "invite" querytype.
+
 
+
 
+
  
 +
<source lang="xml">
 
<querytype>
 
<querytype>
 
 
   <name>invite</name>
 
   <name>invite</name>
 
 
   <proto>http://jabber.org/protocol/muc</proto>
 
   <proto>http://jabber.org/protocol/muc</proto>
 
 
   <desc>enables simultaneously joining a groupchat room and inviting others</desc>
 
   <desc>enables simultaneously joining a groupchat room and inviting others</desc>
 
 
   <doc>XEP-0045</doc>
 
   <doc>XEP-0045</doc>
 
 
   <keys>
 
   <keys>
 
 
     <key>
 
     <key>
 
 
       <name>jid</name>
 
       <name>jid</name>
 
 
       <desc>the Jabber ID of the invitee</desc>
 
       <desc>the Jabber ID of the invitee</desc>
 
 
     </key>
 
     </key>
 
 
     <key>
 
     <key>
 
 
       <name>password</name>
 
       <name>password</name>
 
 
       <desc>the password required to enter a multi-user chat room</desc>
 
       <desc>the password required to enter a multi-user chat room</desc>
 
 
     </key>
 
     </key>
 
 
   </keys>
 
   </keys>
 
 
</querytype>
 
</querytype>
 +
</source>
  
     
+
==商业规则==
 +
===Addresses===
  
 +
为了提供关于从房间JIDs抓获的地址的一致性, Room IDs 必须 MUST 遵循 Stringprep 的 Nodeprep 规范并且 Room Nicknames 必须 MUST 符合 Stringprep (这些都定义在 '''RFC 3920''') 的 Resourceprep 规范. 尽管在 '''RFC 3920''' 中没有显式的说明 , 一个 Room JID 的 Room ID (node) 和 Room Nickname (resource) 部分都必须 MUST 长度不为零. 另外, 一个 MUC 服务不能 MUST NOT 允许空的或不可见的房间昵称 Room Nicknames (即, 房间昵称Room Nicknames 只包含一个或多个空格).
  
 +
取决于服务实现,是否更多地限制房间昵称 (例如, 通过应用情景例程, stringprep的Nodeprep规范, 或其他限制).
  
16. Business Rules
+
===Message===
  
16.1 Addresses
+
# 如果一个房客想发送一个消息给所有其他房客, MUC 客户端必须 MUST 把 'type' 属性值设为 "groupchat". 服务可以 MAY 忽略不正确的消息类型, 或用 <bad-request/> 错误弹回.
 +
# 如果一个MUC服务从一个角色为"none"的Jabber用户收到一个发送给该房间的消息或给某个房客的消息, 服务不能 MUST NOT 递送这个消息并应该 SHOULD 返回给这个消息给发送者并伴随一个 <forbidden/> 错误.
 +
# 如果一个MUC服务 接收到一个发送给不存在的或尚未解锁的房间的消息, 服务应该 SHOULD 返回这个消息给发送者并伴随一个 <item-not-found/> 错误.
 +
# 一个MUC服务应该 SHOULD 不做修改地传递扩展的消息 (例如, 一个消息主体的 XHTML 版本) 给房客; 然而, 一个 MUC 服务可以 MAY 不允许消息的特定扩展(参见本文的[[XEP-0045#允许的通讯|允许的通讯]]章节).
 +
# 一个MUC客户端可以 MAY 生成扩展以满足 [http://xmpp.org/extensions/xep-0022.html 消息事件] [[XEP-0045#附录G:备注|30]] 或 [http://xmpp.org/extensions/xep-0085.html 聊天状态通知] [[XEP-0045#附录G:备注|31]] 规范; 然而, 一个 MUC 服务可以 MAY 不允许这些扩展 (参见本文的[[XEP-0045#允许的通讯|允许的通讯]]章节).
  
 +
===Presence===
  
 +
# 一个房间必须 MUST 安静地忽略从一个角色为"none"的用户发来的不可用出席信息信息.
 +
# 只有MUC服务自身应该 SHOULD 生成关于角色,岗位,全JIDs或遵循 'http://jabber.org/protocol/muc#user' 名字空间的状态码的扩展的出席信息 (基于服务所知道的关于房客的信息, 例如, 角色, 或由一个主持人或房间管理员的动作所产生的结果). 一个客户端不应该 SHOULD NOT 推定生成这类信息. 如果一个 MUC 服务从一个房客接收到这类扩展的出席信息, 它不能 MUST NOT 反射它给其他房客们. (一个客户端可以 MAY 为了提供一个密码而生成遵循 'http://jabber.org/protocol/muc#user' 名字空间的扩展的出席信息, 但自然的这是不反射给其他房客的.)
 +
# 一个MUC服务应该 SHOULD 允许所有其他出席信息通过, 尽管它可以 MAY 选择阻塞扩展的出席信息; 参见本文的 [[XEP-0045#允许的通讯|允许的通讯]]章节.
 +
# 为了适当地通知房客角色和岗位, 并使之更易于Jabber客户端跟踪房间里所有用户的当前状态, MUC服务实现必须 MUST 在所有出席信息节里提供关于角色和岗位的扩展的出席信息, 包括一个用户因为任何原因退出该房间时被发送的类型为"unavailable"的出席信息节.
 +
# 如果一个权限被撤销, 服务必须 MUST 通知这件事,通过发送一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的 <x/> 元素并包含一个 <item/> 子元素,该<item/> 子元素的 'role' 和/或 'affiliation' 属性值的设定指明是去了有关的权限. 所有将来的为这个房客发出的出席信息节必须 MUST 包含这个更新的角色和岗位, 直到除非它们再次改变.
 +
# 一个MUC服务必须 MUST 发送扩展的出席信息给一个客户端,即使客户端在进入该房间时没有发送一个空的遵循 'http://jabber.org/protocol/muc' 名字空间的 <x/> 元素 ; 自然的, 一个客户端必须 MUST 忽略这类信息,如果它不懂得它的话(根据 '''RFC 3920''').
 +
# 在 muc#user 名字空间中被发送的关于角色和岗位的扩展的出席信息必须 MUST 包含全JID (不是纯JID) 作为 'jid' 属性的值.
 +
# 如果想要,一个客户端可以 MAY 发送一个客户化的退出消息 (就像 IRC 频道里经常出现的那样) ,通过在退出时被发送的"unavailable"类型的出席信息节里包含一个 <status/> 元素.
  
In order to provide consistency regarding the addresses captured in room JIDs, Room IDs MUST match the Nodeprep profile of Stringprep and Room Nicknames MUST match the Resourceprep profile of Stringprep (both of these are defined in RFC 3920). Although not explicitly stated in RFC 3920, both the Room ID (node) and Room Nickname (resource) portions of a Room JID MUST be of non-zero length. In addition, a MUC service MUST NOT allow empty or invisible Room Nicknames (i.e., Room Nicknames that consist only of one or more space characters).
+
===IQ===
  
16.2 Message
+
# MUC被设计用于分享消息和出席信息, 而不是 IQs. 一个被发送的到房间本身JID的 IQ 由房间本身来处理并且不反射给所有房客.
 +
# 如果一个房客想在一个非匿名房间发送一个 IQ 节给其他用户, 发送者应该 SHOULD 直接发送请求给接收者的纯JID或全JID, 而不是试图通过房间发送请求(即, 通过接收者的房间JID).
 +
# 如果一个房客想在一个半匿名房间发送一个 IQ 节给其他用户, 发送者能直接发送这个节给接受者的房间JID并且服务可以 MAY 转发这个节给接收者的真实JID. 然而, 任何时候一个MUC服务不能 MUST NOT 泄露这个发送者的真实JID给接收者, 也不能泄露接收者的真实JID给发送者.
 +
# 一个MUC客户端必须 MUST 在IQ set 中的遵循 'http://jabber.org/protocol/muc#admin' <item/> 子元素中只发送 'affiliation' 属性或 'role' 属性; 如果一个主持人, 管理员, 或所有者试图在相同的IQ set中修改相同条目的岗位或角色, 服务必须 MUST 返回一个 <bad-request/> 错误给发送者. 无论如何, 一个MUC服务可以 MAY 基于一个岗位的变更来修改一个角色,从而可以 MAY 发送出席信息更新,同时包含一个修改的角色和一个修改的岗位.
 +
# 在关于角色的 IQ sets中, 一个MUC客户端必须 MUST 只包含 'nick' 属性; 在关于角色的 IQ results中, 一个 MUC 服务必须 MUST 包含 'nick', 'role', 'affiliation', 和'jid' 属性 (值为后来设置的用户的全JID).
 +
# 在关于岗位的 IQ sets中, 一个MUC客户端必须 MUST 只包含 'jid' 属性(值为纯JID); 在关于岗位的 IQ results中, 一个MUC服务不能 MUST NOT 包含 'role' 属性, 必须MUST 包含 'affiliation' 属性和 'jid' 属性 (值为纯JID), 并且应该 SHOULD 包含 'nick' 属性 (除非岗位为 "outcast", 以为被排斥者不应该 SHOULD NOT 有保留的房间昵称).
  
 +
==实现注意事项==
  
 +
以下方针有助于客户端和组件开发者建立 MUC 实现.
  
  1.
+
===服务端===
  
 +
# 在处理一个被主持的房间里游客发送的消息时, 一个MUC服务可以 MAY 通过一个主持人让每个消息排队等待批准并且可以 MAY 通知发送者消息正在等待批准; 然而, 这一行为是可选的 OPTIONAL, 并且一个消息批准协议的定义 (例如, 使用'''XEP-0004'''定义的数据表单) 超出了本文的范围.
 +
# 对于一个 MUC 服务来说,在特定事件发生时提供房间内的消息是很常见的, 例如当标题变更时, 当一个房客加入或退出时, 或当一个房间被销毁时. 这类消息完全是可选的 OPTIONAL 并且留给实现或布署来决定, 但如果使用了,则必须 MUST 是从房间JID本身(<room@service>) 而不是从一个特定的房客(<room@service/nick>)发送的类型为 "groupchat" 类型的消息. 无论如何, 通常接收的客户端倾向于基于房间的事件以及MUC提供的特定状态码来生成类似的消息(例如, 用户加入或退出) ; 这将帮助确保这类消息的正确的本地化.
 +
# 出于礼貌, 一个MUC服务可以 MAY 发送一个房间外的 <message/> 给一个被踢的或被禁止的房客, 并且可以 MAY 广播一个房间内的 <message/> 给所有剩余的房客通知他们该房客已被该房间踢出或禁止. 无论如何, 这类消息是可选的 OPTIONAL, 并且事实上是多余的,因为接收的客户端生成这类消息所必需的信息已经通过MUC服务发送的出席信息节(特别是状态码)得到了.
 +
# 出于礼貌, 如果一个用户的岗位变更了而该用户不在房间里,一个MUC服务可以MAY发送一个房间外的 <message/> ; 这消息应该 SHOULD 被从房间发送给该用户的纯JID, 可以 MAY 包含一个 <body/> 元素描述岗位变更, 并且必须 MUST 包含一个状态码 101.
 +
# 没有需求要一个MUC服务将为旧的"groupchat 1.0"用户提供特别的治疗, 例如包含等价于扩展的遵循 'http://jabber.org/protocol/muc#user' 名字空间的出席信息的消息.
 +
# 房间类型可以 MAY 被配置成任何组合. 一个MUC服务可以 MAY 支持或允许任何想要的房间类型或它们的组合.
 +
# 一个MUC服务可以 MAY 限制在初始配置完成之后配置选项展示给一个所有者的次数, 例如因为特定的选项除非重启服务无法生效.
 +
# 一个MUC服务可以 MAY 提供一个接口给房间创建和配置(例如, 以一个特定的Jabber表单或一个网页), 这样表面上房间所有者是一个应用而不是一个自然人用户.
 +
# 一个MUC服务可以 MAY 选择让一个特定的房间内资源提供接口给管理功能 (例如, 一个 "user" 名的机器人 "ChatBot"), 房客们可以和它直接互动, 从而允许管理员在一个私有消息里键入命令参数 '/command parameter' 给那个机器人 "user". 显然这种服务要求服务在房间创建时添加一个 'ChatBot' 用户到房间, 并且阻止任何房客在该房间使用房间昵称 'ChatBot' . 这可能在一些实现或布署中比较难以保证. 任何情况下, 任何这类接口是可选的 OPTIONAL.
 +
# 如果服务接收到它之前发送给该用户的节相关的递送类错误,一个MUC服务应该 SHOULD 移除一个用户; 递送相关的错误即 <gone/>, <item-not-found/>, <recipient-unavailable/>, <redirect/>, <remote-server-not-found/>, 和 <remote-server-timeout/>.
 +
# 一个MUC服务可以 MAY 选择在反射出席信息变更给一个房间的房客们之前,抛弃附加在<presence/> 节上的扩展的出席信息. 也就是, 一个实现可以 MAY 选择只反射该出席信息节的 <show/>, <status/>, 和 <priority/> 子元素,如 'jabber:client' 名字空间描述的 XML 架构之中, 结果导致那个在扩展的名字空间中的出席信息变更 "changes" (例如, gabber:x:music:info) 不被传递给房客. 如果一个服务禁止特定的扩展名字空间, 它应该 SHOULD 在本文 [[XEP-0045#允许的通讯|允许的通讯]]章节描述的知名的服务发现节点 'http://jabber.org/protocol/muc#traffic' 提供一个允许的通讯的描述.
 +
# 一个MUC服务可以 MAY 在反射消息给一个房间的房客之前选择抛弃附加在 <message/> 节的扩展信息. 一个这类扩展信息的例子是轻量级文本标记,定义于 [http://xmpp.org/extensions/xep-0071.html XHTML-IM]  [XEP-0045#附录G:备注|32]]. 如果一个服务禁止特定的扩展名字空间, 它应该 SHOULD 在本文 [[XEP-0045#允许的通讯|允许的通讯]]章节描述的知名的服务发现节点 'http://jabber.org/protocol/muc#traffic' 提供一个允许的通讯的描述.
 +
# 一个MUC服务可以 MAY 选择锁定 "lock down" 房间昵称 (例如, 硬编码房间昵称给该房客的纯JID). 如果这么干, 该服务必须 MUST 把被锁定的昵称看作一个保留的房间昵称并且必须 MUST 支持本文[[XEP-0045#发现保留的房间昵称|发现保留的房间昵称]]章节定义的协议.
  
 +
====允许的通讯====
  
      If an occupant wants to send a message to all other occupants, a MUC client MUST set the 'type' attribute to a value of "groupchat". A service MAY ignore messages that are improperly typed, or reject them with a <bad-request/> error.
+
大家知道, 一个服务 (更准确地说, 一个正确配置的房间)可以 MAY 抛弃一些或所有的扩展的附加在从发送者通过房间反射给所有房客的 <message/> <presence/> 节的名字空间. 如果房间这么干, 它应该 SHOULD 允许发送者通过发送 disco#info 查询知名的服务发现节点 'http://jabber.org/protocol/muc#traffic' 来发现允许的扩展的列表, 在结果中返回支持的名字空间每个用一个 <feature/> 元素表示. 如果该房间不允许任何扩展的名字空间, 它必须 MUST '''XEP-0030''' 所述返回一个空的 query . 如果该房间不支持 "#traffic" 节点, 它必须 MUST 返回一个 <feature-not-implemented/> 错误应答给查询发送到 'http://jabber.org/protocol/muc#traffic' 节点的查询.
 
+
  2.
+
 
+
 
+
 
+
      If a MUC service receives a message directed to the room or to a single occupant from a Jabber user who has a role of "none", the service MUST NOT deliver the message and SHOULD return the message to the sender with a <forbidden/> error.
+
 
+
  3.
+
 
+
 
+
 
+
      If a MUC service receives a message directed to a room that does not exist or is not yet unlocked, the service SHOULD return the message to the sender with an <item-not-found/> error.
+
 
+
  4.
+
 
+
 
+
 
+
      A MUC service SHOULD pass extended information (e.g., an XHTML version of the message body) through to occupants unchanged; however, a MUC service MAY disallow message specific extensions (see the Allowable Traffic section of this document).
+
 
+
  5.
+
 
+
 
+
 
+
      A MUC client MAY generate extensions that conform to the Message Events [29] or Chat State Notifications [30] specification; however, a MUC service MAY disallow these extensions (see the Allowable Traffic section of this document).
+
 
+
 
+
 
+
16.3 Presence
+
 
+
 
+
 
+
  1.
+
 
+
 
+
 
+
      A room MUST silently ignore unavailable presence received from a user who has a role of "none".
+
 
+
  2.
+
 
+
 
+
 
+
      Only the MUC service itself SHOULD generate extended presence information about roles, affiliations, full JIDs, or status codes qualified by the 'http://jabber.org/protocol/muc#user' namespace (based on information the service knows about occupants, e.g., roles, or as a result of actions taken by a moderator or room administrator). A client SHOULD NOT presume to generate such information. If a MUC service receives such extended presence information from an occupant, it MUST NOT reflect it to other occupants. (A client MAY generate extended presence information qualified by the 'http://jabber.org/protocol/muc#user' namespace in order to supply a password, but naturally this is not reflected to other occupants.)
+
 
+
  3.
+
 
+
 
+
 
+
      A MUC service SHOULD allow all other presence information to pass through, although it MAY choose to block extended presence information; see the Allowable Traffic section of this document.
+
 
+
  4.
+
 
+
 
+
 
+
      In order to appropriately inform occupants of room roles and affiliations, and to make it easier for Jabber clients to track the current state of all users in the room, MUC service implementations MUST provide extended presence information about roles and affiliations in all presence stanzas, including presence stanzas of type "unavailable" sent when a user exits the room for any reason.
+
 
+
  5.
+
 
+
 
+
 
+
      If a privilege is revoked, the service MUST note that by sending an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child element with the 'role' and/or 'affiliation' attributes set to a value that indicates the loss of the relevant privilege. All future presence stanzas for the occupant MUST include the updated role and affiliation, until and unless they change again.
+
 
+
  6.
+
 
+
 
+
 
+
      A MUC service MUST send extended presence to a client even if the client did not send an empty <x/> element qualified by the 'http://jabber.org/protocol/muc' namespace on entering the room; naturally, a client MUST ignore such information if it does not understand it (in accordance with RFC 3920).
+
 
+
  7.
+
 
+
 
+
 
+
      Extended presence about roles and affiliations sent in the muc#user namespace MUST include the full JID (not the bare JID) as the value of the 'jid' attribute.
+
 
+
  8.
+
 
+
 
+
 
+
      A client MAY send a custom exit message if desired (as is often done in IRC channels) by including a <status/> element in the presence stanza of type "unavailable" sent when exiting a room.
+
 
+
 
+
 
+
16.4 IQ
+
 
+
 
+
 
+
  1.
+
 
+
 
+
 
+
      If an occupant wants to send an IQ stanza to another user in a non-anonymous room, the sender SHOULD send the request directly to the recipient's bare JID or full JID, rather than attempting to send the request through the room (i.e., via the recipient's room JID).
+
 
+
  2.
+
 
+
 
+
 
+
      If an occupant wants to send an IQ stanza to another user in a semi-anonymous room, the sender can direct the stanza to the recipient's room JID and the service MAY forward the stanza to the recipient's real JID. However, a MUC service MUST NOT reveal the sender's real JID to the recipient at any time, nor reveal the recipient's real JID to the sender.
+
 
+
  3.
+
 
+
 
+
 
+
      A MUC client MUST send only the 'affiliation' attribute or the 'role' attribute in the <item/> element contained within an IQ set qualified by the 'http://jabber.org/protocol/muc#admin' namespace; if a moderator, admin, or owner attempts to modify both the affiliation and role of the same item in the same IQ set, the service MUST return a <bad-request/> error to the sender. However, a MUC service MAY modify a role based on a change to an affiliation and thus MAY send presence updates that include both a modified role and a modified affiliation.
+
 
+
  4.
+
 
+
 
+
 
+
      In IQ sets regarding roles, a MUC client MUST include the 'nick' attribute only; in IQ results regarding roles, a MUC service MUST include the 'nick', 'role', 'affiliation', and 'jid' attributes (with the value of the latter set to the user's full JID).
+
 
+
  5.
+
 
+
 
+
 
+
      In IQ sets regarding affiliations, a MUC client MUST include the 'jid' attribute only (with the value set to the bare JID); in IQ results regarding affiliations, a MUC service MUST NOT include the 'role' attribute, MUST include the 'affiliation' attribute and the 'jid' attribute (with the value set to the bare JID), and SHOULD include the 'nick' attribute (except if the affiliation is "outcast", since outcasts SHOULD NOT have reserved nicknames).
+
 
+
 
+
 
+
17. Implementation Notes
+
 
+
 
+
 
+
The following guidelines may assist client and component developers in creating MUC implementations.
+
 
+
17.1 Services
+
 
+
 
+
 
+
  1.
+
 
+
 
+
 
+
      In handling messages sent by visitors in a moderated room, a MUC service MAY queue each message for approval by a moderator and MAY inform the sender that the message is being held for approval; however, such behavior is OPTIONAL, and definition of a message approval protocol (e.g., using Data Forms as defined in XEP-0004) is out of scope for this document.
+
 
+
  2.
+
 
+
 
+
 
+
      It is common for MUC services to provide in-room messages when certain events occur, such as when the subject changes, when an occupant enters or exits, or when a room is destroyed. Such messages are entirely OPTIONAL and are left up to the implementation or deployment, but if used MUST be messages of type "groupchat" sent from the room JID itself (<room@service>) rather than a specific occupant (<room@service/nick>). However, in general it is preferable for the receiving client to generate such messages based on events in the room (e.g., user entrances and exits) as well as specific status codes provided in MUC; this will help ensure correct localization of such messages.
+
 
+
  3.
+
 
+
 
+
 
+
      Out of courtesy, a MUC service MAY send an out-of-room <message/> to an occupant who is kicked or banned, and MAY broadcast an in-room <message/> to all remaining occupants informing them that the occupant has been kicked or banned from the room. However, such messages are OPTIONAL, and indeed are unnecessary since the information required for a receiving client to generate such messages is communicated in the presence stanzas (specifically the status codes) sent by a MUC service.
+
 
+
  4.
+
 
+
 
+
 
+
      Out of courtesy, a MUC service MAY send an out-of-room <message/> if a user's affiliation changes while the user is not in the room; the message SHOULD be sent from the room to the user's bare JID, MAY contain a <body/> element describing the affiliation change, and MUST contain a status code of 101.
+
 
+
  5.
+
 
+
 
+
 
+
      There is no requirement that a MUC service shall provide special treatment for users of the older "groupchat 1.0" protocol, such as messages that contain equivalents to the extended presence information that is qualified by the 'http://jabber.org/protocol/muc#user' namespace.
+
 
+
  6.
+
 
+
 
+
 
+
      Room types MAY be configured in any combination. A MUC service MAY support or allow any desired room types or combinations thereof.
+
 
+
  7.
+
 
+
 
+
 
+
      A MUC service MAY limit the number of configuration options presented to an owner after initial configuration has been completed, e.g. because certain options cannot take effect without restarting the service.
+
 
+
  8.
+
 
+
 
+
 
+
      A MUC service MAY provide an interface to room creation and configuration (e.g., in the form of a special Jabber user or a Web page), so that the ostensible room owner is actually the application instead of a human user.
+
 
+
  9.
+
 
+
 
+
 
+
      A MUC service MAY choose to make available a special in-room resource that provides an interface to administrative functionality (e.g., a "user" named "ChatBot"), which occupants could interact with directly, thus enabling admins to type '/command parameter' in a private message to that "user". Obviously this kind of implementation would require the service to add a 'ChatBot' user to the room when it is created, and to prevent any occupant from having the nickname 'ChatBot' in the room. This might be difficult to ensure in some implementations or deployments. In any case, any such interface is OPTIONAL.
+
 
+
  10.
+
 
+
 
+
 
+
      A MUC service SHOULD remove a user if the service receives a delivery-related error in relation to a stanza it has previously sent to the user (remote server unreachable, user not found, etc.).
+
 
+
  11.
+
 
+
 
+
 
+
      A MUC service MAY choose to discard extended presence information that is attached to a <presence/> stanza before reflecting the presence change to the occupants of a room. That is, an implementation MAY choose to reflect only the <show/>, <status/>, and <priority/> child elements of the presence element as specified in the XML schema for the 'jabber:client' namespace, with the result that presence "changes" in extended namespaces (e.g., gabber:x:music:info) are not passed through to occupants. If a service prohibits certain extended namespaces, it SHOULD provide a description of allowable traffic at the well-known Service Discovery node 'http://jabber.org/protocol/muc#traffic' as described in the Allowable Traffic section of this document.
+
 
+
  12.
+
 
+
 
+
 
+
      A MUC service MAY choose to discard extended information attached to <message/> stanzas before reflecting the message to the occupants of a room. An example of such extended information is the lightweight text markup specified by XHTML-IM [31]. If a service prohibits certain extended namespaces, it SHOULD provide a description of allowable traffic at the well-known Service Discovery node 'http://jabber.org/protocol/muc#traffic' as described in the Allowable Traffic section of this document.
+
 
+
  13.
+
 
+
 
+
 
+
      A MUC service MAY choose to "lock down" room nicknames (e.g., hardcoding the room nickname to the bare JID of the occupant). If so, the service MUST treat the locked down nickname as a reserved room nickname and MUST support the protocol specified in the Discovering Reserved Room Nickname section of this document.
+
 
+
 
+
 
+
17.1.1 Allowable Traffic
+
 
+
 
+
 
+
As noted, a service (more precisely, a properly-configured room) MAY discard some or all extended namespaces attached to <message/> and <presence/> stanzas that are intended for reflection from the sender through the room to all of the room occupants. If the room does so, it SHOULD enable senders to discover the list of allowable extensions by sending a disco#info query to the well-known Service Discovery node 'http://jabber.org/protocol/muc#traffic', returning one <feature/> element for each namespace supported in the result. If the room does not allow any extended namespaces, it MUST return an empty query as specified in XEP-0030. If the room does not support the "#traffic" node, it MUST return a <feature-not-implemented/> error in response to queries sent to the 'http://jabber.org/protocol/muc#traffic' node.
+
 
+
 
+
 
+
The following example shows a room that allows the 'http://jabber.org/protocol/xhtml-im' and 'http://jabber.org/protocol/rosterx' namespaces only, but no other extended namespaces.
+
 
+
 
+
 
+
Example 191. User Queries Service Regarding Allowable Namespaces
+
  
 +
以下例子展示一个只允许 'http://jabber.org/protocol/xhtml-im' 和 'http://jabber.org/protocol/rosterx' 名字空间的房间, 而不包括其他的名字空间.
  
 +
'''例子 209. 用户查询服务关于允许的名字空间'''
  
 +
<source lang="xml">
 
<iq from='wiccarocks@shakespeare.lit/laptop'
 
<iq from='wiccarocks@shakespeare.lit/laptop'
 
+
     to='heath@chat.shakespeare.lit'
     to='heath@macbeth.shakespeare.lit'
+
 
+
 
     id='allow1'
 
     id='allow1'
 
 
     type='get'>
 
     type='get'>
 
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
 
         node='http://jabber.org/protocol/muc#traffic'/>
 
         node='http://jabber.org/protocol/muc#traffic'/>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
'''例子 210. 服务返回允许的名字空间'''
 
+
 
+
 
+
Example 192. Service Returns Allowable Namespaces
+
 
+
 
+
 
+
<iq from='heath@macbeth.shakespeare.lit'
+
  
 +
<source lang="xml">
 +
<iq from='heath@chat.shakespeare.lit'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     id='allow1'
 
     id='allow1'
 
 
     type='result'>
 
     type='result'>
 
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
 
         node='http://jabber.org/protocol/muc#traffic'>
 
         node='http://jabber.org/protocol/muc#traffic'>
 
 
     <feature var='http://jabber.org/protocol/xhtml-im'/>
 
     <feature var='http://jabber.org/protocol/xhtml-im'/>
 
 
     <feature var='http://jabber.org/protocol/rosterx'/>
 
     <feature var='http://jabber.org/protocol/rosterx'/>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
如果一个服务不抛弃任何名字空间或不实现这个特性, 它必须 MUST 返回一个 <service-unavailable/> 错误:
  
 +
'''例子 211. 服务返回服务不可用错误'''
  
 
+
<source lang="xml">
If a service does not discard any namespaces or does not implement this feature, it MUST return a <service-unavailable/> error:
+
<iq from='heath@chat.shakespeare.lit'
 
+
 
+
 
+
Example 193. Service Returns Service Unavailable
+
 
+
 
+
 
+
<iq from='heath@macbeth.shakespeare.lit'
+
 
+
 
     to='wiccarocks@shakespeare.lit/laptop'
 
     to='wiccarocks@shakespeare.lit/laptop'
 
 
     id='allow1'
 
     id='allow1'
 
 
     type='error'>
 
     type='error'>
 
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
   <query xmlns='http://jabber.org/protocol/disco#info'
 
 
         node='http://jabber.org/protocol/muc#traffic'/>
 
         node='http://jabber.org/protocol/muc#traffic'/>
 
+
   <error type='cancel'>
   <error code='503' type='cancel'>
+
 
+
 
     <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
     <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 
 
   </error>
 
   </error>
 
 
</iq>
 
</iq>
 +
</source>
  
     
+
===客户端===
  
 +
# Jabber客户端可以 MAY 展示房间角色,通过在一个房间名册里为每个角色显示特定的群. 这将使房客清楚图形化的知道哪个房客是主持人, 参与者, 和游客. 无论如何, 这样一个展示是可选的 OPTIONAL.
 +
# Jabber客户端可以 MAY 实现多样化的界面以提供快捷方式 "shortcuts" 给功能,例如修改某人昵称, 踢人或禁止用户, 发现一个房客的全JID, 或修改主题. 一个选项包含了类IRC 的命令例如 '/nick', '/kick', '/ban', 和 '/whois'; 另一个是使用户能用鼠标右击房间名册里的项目. 所有这些界面形式是可选的 OPTIONAL. 然而, 为方便起见, 下面提供了一个 IRC 命令到 MUC 协议的映射.
  
 +
====IRC命令映射====
  
17.2 Clients
+
IRC 客户端使用大量常用的快捷方式 "shortcut" 命令,以一个斜杠开始, 例如 '/nick' and '/ban'. 下表提供一个 类IRC 命令到 MUC 协议的映射, 用于希望支持类似功能的 Jabber 客户端.
  
 +
'''表10: IRC命令映射'''
  
 
+
{|border="1" cellspacing="0"  
  1.
+
!命令 !!功能 !!MUC协议
 
+
|-
 
+
|/ban <roomnick> [comment] ||在房间里以房间昵称禁止用户(客户端翻译房间昵称为纯JID) ||<source lang="xml"><iq id='someid'
 
+
      Jabber clients MAY present room roles by showing ad-hoc groups for each role within a room roster. This will enable occupants to clearly visualize which occupants are moderators, participants, and visitors. However, such a representation is OPTIONAL.
+
 
+
  2.
+
 
+
 
+
 
+
      Jabber clients MAY implement a variety of interface styles that provide "shortcuts" to functionality such as changing one's nickname, kicking or banning users, discovering an occupant's full JID, or changing the subject. One option consists of IRC-style commands such as '/nick', '/kick', '/ban', and '/whois'; another is to enable a user to right-click items in a room roster. All such interface styles are OPTIONAL. However, for convenience, a mapping of IRC commands to MUC protocols is provided below.
+
 
+
 
+
 
+
17.2.1 IRC Command Mapping
+
 
+
 
+
 
+
Internet Relay Chat clients use a number of common "shortcut" commands that begin with a forward slash, such as '/nick' and '/ban'. The following table provides a mapping of IRC-style commands to MUC protocols, for use by Jabber clients that wish to support such functionality.
+
 
+
 
+
 
+
Table 9: IRC Command Mapping
+
 
+
Command Function MUC protocol
+
 
+
/ban <roomnick> [comment] bans user with that roomnick from this room (client translates roomnick to bare JID)
+
 
+
 
+
 
+
<iq id='someid'
+
 
+
 
     to='room@service'
 
     to='room@service'
 
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item affiliation='outcast'
 
     <item affiliation='outcast'
 
 
           jid='bare-jid-of-user'>
 
           jid='bare-jid-of-user'>
 
 
       <reason>comment</reason>
 
       <reason>comment</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 
+
</source>
         
+
|-
 
+
|/invite <jid> [comment] ||以JID邀请用户到此房间 ||<source lang="xml"><message to='room@service'>
 
+
 
+
/invite <jid> [comment] invites user with that JID to this room
+
 
+
 
+
 
+
<message to='room@service'>
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <invite to='jid'>
 
     <invite to='jid'>
 
 
       <reason>comment</reason>
 
       <reason>comment</reason>
 
 
     </invite>
 
     </invite>
 
 
   </x>
 
   </x>
 
 
</message>
 
</message>
 
+
</source> 
         
+
|-
 
+
|/join <roomname> [pass] ||在服务里加入房间(房间昵称同本房间内的昵称) ||<source lang="xml"><presence to='room@service/nick'>
 
+
 
+
/join <roomname> [pass] joins room on this service (roomnick is same as nick in this room)
+
 
+
 
+
 
+
<presence to='room@service/nick'>
+
 
+
 
+
 
+
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
   <x xmlns='http://jabber.org/protocol/muc#user'>
 
 
     <password>pass</password>
 
     <password>pass</password>
 
 
   </x>
 
   </x>
 
 
</presence>
 
</presence>
 
+
</source>
         
+
|-
 
+
|/kick <roomnick> [comment] ||以房间昵称从房间里踢人 ||<source lang="xml"><iq id='someid'
 
+
 
+
/kick <roomnick> [comment] kicks user with that roomnick from this room
+
 
+
 
+
 
+
<iq id='someid'
+
 
+
 
     to='room@service'
 
     to='room@service'
 
 
     type='set'>
 
     type='set'>
 
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
   <query xmlns='http://jabber.org/protocol/muc#admin'>
 
 
     <item nick='roomnick' role='none'>
 
     <item nick='roomnick' role='none'>
 
 
       <reason>comment</reason>
 
       <reason>comment</reason>
 
 
     </item>
 
     </item>
 
 
   </query>
 
   </query>
 
 
</iq>
 
</iq>
 
+
</source>
         
+
|-
 
+
|/msg <roomnick> <foo> ||发送私有消息"foo"给房间昵称 ||<source lang="xml"><message to='room@service/nick' type='chat'>
 
+
 
+
/msg <roomnick> <foo> sends private message "foo" to roomnick
+
 
+
 
+
 
+
<message to='room@service/nick' type='chat'>
+
 
+
 
   <body>foo</body>
 
   <body>foo</body>
 
 
</message>
 
</message>
 
+
</source>
         
+
|-
 
+
|/nick <newnick> ||变更在此房间内的昵称为"newnick" ||<source lang="xml"><presence to='room@service/newnick'/>
 
+
</source>
 
+
|-
/nick <newnick> changes nick in this room to "newnick"
+
|/part [comment] ||退出本房间(一些 IRC 客户端也支持 /leave) ||<source lang="xml"><presence to='room@service/nick'
 
+
 
+
 
+
<presence to='room@service/newnick'/>
+
 
+
         
+
 
+
 
+
 
+
/part [comment] exits this room (some IRC clients also support /leave)
+
 
+
 
+
 
+
<presence to='room@service/nick'
+
 
+
 
           type='unavailable'>
 
           type='unavailable'>
 
 
   <status>comment</status>
 
   <status>comment</status>
 
 
</presence>
 
</presence>
 
+
</source>
         
+
|-
 
+
|/topic <foo> ||变更此房间主题为"foo" ||<source lang="xml"><message to='room@service' type='groupchat'>
 
+
 
+
/topic <foo> changes subject of this room to "foo"
+
 
+
 
+
 
+
<message to='room@service' type='groupchat'>
+
 
+
 
   <subject>foo</subject>
 
   <subject>foo</subject>
 
 
</message>
 
</message>
 +
</source>
 +
|}
  
         
 
  
 +
注意: 因为 MUC 房间昵称遵循stringprep的Resourceprep脚本, 它们被允许包含一个空格字符, 而 IRC 昵称不允许. 尽管一个给定的客户端可以 MAY 支持引用字符串用于这个目的 (导致命令类似 '/ban "king lear" insanity is no defense'), 最常见的引用字符(类似 " 和 ') 也是被Resourceprep允许的 , 从而导致增加了复杂性和包含空格和引号的房间昵称中引号的潜在问题. 所以不建议 NOT RECOMMENDED Jabber客户端支持包含了空格符的房间昵称的类IRC的快捷方式命令.
  
 +
注意: 很多Jabber客户端也实现了 '/me ' 命令,如 [http://xmpp.org/extensions/xep-0245.html The /me Command] [[XEP-0045#附录G:备注|33]] 所述. 这个命令不会导致任何 MUC 或 IRC 协议的动作所以不显式在上表中.
  
Note: Because MUC roomnicks follow the Resourceprep profile of stringprep, they are allowed to contain a space character, whereas IRC nicknames do not. Although a given client MAY support quotation characters for this purpose (resulting in commands such as '/ban "king lear" insanity is no defense'), most common quotation characters (such as " and ') are also allowed by Resourceprep, thus leading to added complexity and potential problems with quotation of roomnicks that contain both spaces and quotation characters. Therefore it is NOT RECOMMENDED for Jabber clients to support IRC-style shortcut commands with roomnicks that contain space characters.
+
==XML架构==
 
+
===http://jabber.org/protocol/muc===
 
+
 
+
Note: Many Jabber clients also implement a '/me ' command, where the command is followed by a verb or verb phrase (e.g., '/me laughs'). This command does not result in any MUC or IRC protocol action and is therefore not shown in the foregoing table. Instead, the message is sent as-is (e.g., <body>/me laughs</body>) and the receiving client performs string-matching on the character data of the <body/> element to determine if the message begins with the string '/me '; if it does the receiving client will show the message in a special format, usually italicized text sometimes prepended by the "*" character:
+
 
+
 
+
 
+
* stpeter laughs
+
 
+
18. XML Schemas
+
 
+
18.1 http://jabber.org/protocol/muc
+
 
+
 
+
  
 +
<source lang="xml">
 
<?xml version='1.0' encoding='UTF-8'?>
 
<?xml version='1.0' encoding='UTF-8'?>
 
 
  
 
<xs:schema
 
<xs:schema
 
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
 
     targetNamespace='http://jabber.org/protocol/muc'
 
     targetNamespace='http://jabber.org/protocol/muc'
 
 
     xmlns='http://jabber.org/protocol/muc'
 
     xmlns='http://jabber.org/protocol/muc'
 
 
     elementFormDefault='qualified'>
 
     elementFormDefault='qualified'>
 
 
  
 
   <xs:annotation>
 
   <xs:annotation>
 
 
     <xs:documentation>
 
     <xs:documentation>
 
 
       The protocol documented by this schema is defined in
 
       The protocol documented by this schema is defined in
 
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
 
     </xs:documentation>
 
     </xs:documentation>
 
 
   </xs:annotation>
 
   </xs:annotation>
 
 
  
 
   <xs:element name='x'>
 
   <xs:element name='x'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element ref='history' minOccurs='0'/>
 
         <xs:element ref='history' minOccurs='0'/>
 
 
         <xs:element name='password' type='xs:string' minOccurs='0'/>
 
         <xs:element name='password' type='xs:string' minOccurs='0'/>
 
 
       </xs:sequence>
 
       </xs:sequence>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='history'>
 
   <xs:element name='history'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:simpleContent>
 
       <xs:simpleContent>
 
 
         <xs:extension base='empty'>
 
         <xs:extension base='empty'>
 
 
           <xs:attribute name='maxchars' type='xs:int' use='optional'/>
 
           <xs:attribute name='maxchars' type='xs:int' use='optional'/>
 
 
           <xs:attribute name='maxstanzas' type='xs:int' use='optional'/>
 
           <xs:attribute name='maxstanzas' type='xs:int' use='optional'/>
 
 
           <xs:attribute name='seconds' type='xs:int' use='optional'/>
 
           <xs:attribute name='seconds' type='xs:int' use='optional'/>
 
 
           <xs:attribute name='since' type='xs:dateTime' use='optional'/>
 
           <xs:attribute name='since' type='xs:dateTime' use='optional'/>
 
 
         </xs:extension>
 
         </xs:extension>
 
 
       </xs:simpleContent>
 
       </xs:simpleContent>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:simpleType name='empty'>
 
   <xs:simpleType name='empty'>
 
 
     <xs:restriction base='xs:string'>
 
     <xs:restriction base='xs:string'>
 
 
       <xs:enumeration value=''/>
 
       <xs:enumeration value=''/>
 
 
     </xs:restriction>
 
     </xs:restriction>
 
 
   </xs:simpleType>
 
   </xs:simpleType>
 
 
  
 
</xs:schema>
 
</xs:schema>
 +
</source>
  
   
+
===http://jabber.org/protocol/muc#user===
 
+
 
+
 
+
18.2 http://jabber.org/protocol/muc#user
+
 
+
 
+
  
 +
<source lang="xml">
 
<?xml version='1.0' encoding='UTF-8'?>
 
<?xml version='1.0' encoding='UTF-8'?>
 
 
  
 
<xs:schema
 
<xs:schema
 
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
 
     targetNamespace='http://jabber.org/protocol/muc#user'
 
     targetNamespace='http://jabber.org/protocol/muc#user'
 
 
     xmlns='http://jabber.org/protocol/muc#user'
 
     xmlns='http://jabber.org/protocol/muc#user'
 
 
     elementFormDefault='qualified'>
 
     elementFormDefault='qualified'>
 
 
  
 
   <xs:annotation>
 
   <xs:annotation>
 
 
     <xs:documentation>
 
     <xs:documentation>
 
 
       The protocol documented by this schema is defined in
 
       The protocol documented by this schema is defined in
 
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
 
     </xs:documentation>
 
     </xs:documentation>
 
 
   </xs:annotation>
 
   </xs:annotation>
 
 
  
 
   <xs:element name='x'>
 
   <xs:element name='x'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:choice minOccurs='0' maxOccurs='unbounded'>
 
       <xs:choice minOccurs='0' maxOccurs='unbounded'>
 
 
         <xs:element ref='decline' minOccurs='0'/>
 
         <xs:element ref='decline' minOccurs='0'/>
 
 
         <xs:element ref='destroy' minOccurs='0'/>
 
         <xs:element ref='destroy' minOccurs='0'/>
 
 
         <xs:element ref='invite' minOccurs='0' maxOccurs='unbounded'/>
 
         <xs:element ref='invite' minOccurs='0' maxOccurs='unbounded'/>
 
 
         <xs:element ref='item' minOccurs='0'/>
 
         <xs:element ref='item' minOccurs='0'/>
 
 
         <xs:element name='password' type='xs:string' minOccurs='0'/>
 
         <xs:element name='password' type='xs:string' minOccurs='0'/>
 
+
         <xs:element ref='status' minOccurs='0' maxOccurs='unbounded'/>
         <xs:element ref='status' minOccurs='0'/>
+
 
+
 
       </xs:choice>
 
       </xs:choice>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='decline'>
 
   <xs:element name='decline'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element ref='reason' minOccurs='0'/>
 
         <xs:element ref='reason' minOccurs='0'/>
 
 
       </xs:sequence>
 
       </xs:sequence>
 
 
       <xs:attribute name='from' type='xs:string' use='optional'/>
 
       <xs:attribute name='from' type='xs:string' use='optional'/>
 
 
       <xs:attribute name='to' type='xs:string' use='optional'/>
 
       <xs:attribute name='to' type='xs:string' use='optional'/>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='destroy'>
 
   <xs:element name='destroy'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element ref='reason' minOccurs='0'/>
 
         <xs:element ref='reason' minOccurs='0'/>
 
 
       </xs:sequence>
 
       </xs:sequence>
 
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='invite'>
 
   <xs:element name='invite'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element ref='reason' minOccurs='0'/>
 
         <xs:element ref='reason' minOccurs='0'/>
 
 
       </xs:sequence>
 
       </xs:sequence>
 
 
       <xs:attribute name='from' type='xs:string' use='optional'/>
 
       <xs:attribute name='from' type='xs:string' use='optional'/>
 
 
       <xs:attribute name='to' type='xs:string' use='optional'/>
 
       <xs:attribute name='to' type='xs:string' use='optional'/>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='item'>
 
   <xs:element name='item'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element ref='actor' minOccurs='0'/>
 
         <xs:element ref='actor' minOccurs='0'/>
 
 
         <xs:element ref='reason' minOccurs='0'/>
 
         <xs:element ref='reason' minOccurs='0'/>
 
+
         <xs:element ref='continue' minOccurs='0'/>
         <xs:element name='continue' type='empty' minOccurs='0'/>
+
 
+
 
       </xs:sequence>
 
       </xs:sequence>
 
 
       <xs:attribute name='affiliation' use='optional'>
 
       <xs:attribute name='affiliation' use='optional'>
 
 
         <xs:simpleType>
 
         <xs:simpleType>
 
 
           <xs:restriction base='xs:NCName'>
 
           <xs:restriction base='xs:NCName'>
 
 
             <xs:enumeration value='admin'/>
 
             <xs:enumeration value='admin'/>
 
 
             <xs:enumeration value='member'/>
 
             <xs:enumeration value='member'/>
 
 
             <xs:enumeration value='none'/>
 
             <xs:enumeration value='none'/>
 
 
             <xs:enumeration value='outcast'/>
 
             <xs:enumeration value='outcast'/>
 
 
             <xs:enumeration value='owner'/>
 
             <xs:enumeration value='owner'/>
 
 
           </xs:restriction>
 
           </xs:restriction>
 
 
         </xs:simpleType>
 
         </xs:simpleType>
 
 
       </xs:attribute>
 
       </xs:attribute>
 
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
 
       <xs:attribute name='nick' type='xs:string' use='optional'/>
 
       <xs:attribute name='nick' type='xs:string' use='optional'/>
 
 
       <xs:attribute name='role' use='optional'>
 
       <xs:attribute name='role' use='optional'>
 
 
         <xs:simpleType>
 
         <xs:simpleType>
 
 
           <xs:restriction base='xs:NCName'>
 
           <xs:restriction base='xs:NCName'>
 
 
             <xs:enumeration value='moderator'/>
 
             <xs:enumeration value='moderator'/>
 
 
             <xs:enumeration value='none'/>
 
             <xs:enumeration value='none'/>
 
 
             <xs:enumeration value='participant'/>
 
             <xs:enumeration value='participant'/>
 
 
             <xs:enumeration value='visitor'/>
 
             <xs:enumeration value='visitor'/>
 
 
           </xs:restriction>
 
           </xs:restriction>
 
 
         </xs:simpleType>
 
         </xs:simpleType>
 
 
       </xs:attribute>
 
       </xs:attribute>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='actor'>
 
   <xs:element name='actor'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:simpleContent>
 
       <xs:simpleContent>
 
 
         <xs:extension base='empty'>
 
         <xs:extension base='empty'>
 
 
           <xs:attribute name='jid' type='xs:string' use='required'/>
 
           <xs:attribute name='jid' type='xs:string' use='required'/>
 +
        </xs:extension>
 +
      </xs:simpleContent>
 +
    </xs:complexType>
 +
  </xs:element>
  
 +
  <xs:element name='continue'>
 +
    <xs:complexType>
 +
      <xs:simpleContent>
 +
        <xs:extension base='empty'>
 +
          <xs:attribute name='thread' type='xs:string' use='optional'/>
 
         </xs:extension>
 
         </xs:extension>
 
 
       </xs:simpleContent>
 
       </xs:simpleContent>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='status'>
 
   <xs:element name='status'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:attribute name='code' use='required'>
 
       <xs:attribute name='code' use='required'>
 
 
         <xs:simpleType>
 
         <xs:simpleType>
 
 
           <xs:restriction base='xs:int'>
 
           <xs:restriction base='xs:int'>
 
+
             <xs:minInclusive value='100'/>
             <xs:length value='3'/>
+
            <xs:maxInclusive value='999'/>
 
+
 
           </xs:restriction>
 
           </xs:restriction>
 
 
         </xs:simpleType>
 
         </xs:simpleType>
 
 
       </xs:attribute>
 
       </xs:attribute>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='reason' type='xs:string'/>
 
   <xs:element name='reason' type='xs:string'/>
 
 
  
 
   <xs:simpleType name='empty'>
 
   <xs:simpleType name='empty'>
 
 
     <xs:restriction base='xs:string'>
 
     <xs:restriction base='xs:string'>
 
 
       <xs:enumeration value=''/>
 
       <xs:enumeration value=''/>
 
 
     </xs:restriction>
 
     </xs:restriction>
 
 
   </xs:simpleType>
 
   </xs:simpleType>
 
 
  
 
</xs:schema>
 
</xs:schema>
 +
</source>
  
   
+
===http://jabber.org/protocol/muc#admin===
 
+
 
+
 
+
18.3 http://jabber.org/protocol/muc#admin
+
 
+
 
+
  
 +
<source lang="xml">
 
<?xml version='1.0' encoding='UTF-8'?>
 
<?xml version='1.0' encoding='UTF-8'?>
 
 
  
 
<xs:schema
 
<xs:schema
 
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
 
     targetNamespace='http://jabber.org/protocol/muc#admin'
 
     targetNamespace='http://jabber.org/protocol/muc#admin'
 
 
     xmlns='http://jabber.org/protocol/muc#admin'
 
     xmlns='http://jabber.org/protocol/muc#admin'
 
 
     elementFormDefault='qualified'>
 
     elementFormDefault='qualified'>
 
 
  
 
   <xs:annotation>
 
   <xs:annotation>
 
 
     <xs:documentation>
 
     <xs:documentation>
 
 
       The protocol documented by this schema is defined in
 
       The protocol documented by this schema is defined in
 
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
 
     </xs:documentation>
 
     </xs:documentation>
 
 
   </xs:annotation>
 
   </xs:annotation>
 
 
  
 
   <xs:element name='query'>
 
   <xs:element name='query'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element ref='item' maxOccurs='unbounded'/>
 
         <xs:element ref='item' maxOccurs='unbounded'/>
 
 
       </xs:sequence>
 
       </xs:sequence>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='item'>
 
   <xs:element name='item'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element ref='actor' minOccurs='0'/>
 
         <xs:element ref='actor' minOccurs='0'/>
 
 
         <xs:element ref='reason' minOccurs='0'/>
 
         <xs:element ref='reason' minOccurs='0'/>
 
 
       </xs:sequence>
 
       </xs:sequence>
 
 
       <xs:attribute name='affiliation' use='optional'>
 
       <xs:attribute name='affiliation' use='optional'>
 
 
         <xs:simpleType>
 
         <xs:simpleType>
 
 
           <xs:restriction base='xs:NCName'>
 
           <xs:restriction base='xs:NCName'>
 
 
             <xs:enumeration value='admin'/>
 
             <xs:enumeration value='admin'/>
 
 
             <xs:enumeration value='member'/>
 
             <xs:enumeration value='member'/>
 
 
             <xs:enumeration value='none'/>
 
             <xs:enumeration value='none'/>
 
 
             <xs:enumeration value='outcast'/>
 
             <xs:enumeration value='outcast'/>
 
 
             <xs:enumeration value='owner'/>
 
             <xs:enumeration value='owner'/>
 
 
           </xs:restriction>
 
           </xs:restriction>
 
 
         </xs:simpleType>
 
         </xs:simpleType>
 
 
       </xs:attribute>
 
       </xs:attribute>
 
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
 
       <xs:attribute name='nick' type='xs:string' use='optional'/>
 
       <xs:attribute name='nick' type='xs:string' use='optional'/>
 
 
       <xs:attribute name='role' use='optional'>
 
       <xs:attribute name='role' use='optional'>
 
 
         <xs:simpleType>
 
         <xs:simpleType>
 
 
           <xs:restriction base='xs:NCName'>
 
           <xs:restriction base='xs:NCName'>
 
 
             <xs:enumeration value='moderator'/>
 
             <xs:enumeration value='moderator'/>
 
 
             <xs:enumeration value='none'/>
 
             <xs:enumeration value='none'/>
 
 
             <xs:enumeration value='participant'/>
 
             <xs:enumeration value='participant'/>
 
 
             <xs:enumeration value='visitor'/>
 
             <xs:enumeration value='visitor'/>
 
 
           </xs:restriction>
 
           </xs:restriction>
 
 
         </xs:simpleType>
 
         </xs:simpleType>
 
 
       </xs:attribute>
 
       </xs:attribute>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='actor'>
 
   <xs:element name='actor'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:simpleContent>
 
       <xs:simpleContent>
 
 
         <xs:extension base='empty'>
 
         <xs:extension base='empty'>
 
 
           <xs:attribute name='jid' type='xs:string' use='required'/>
 
           <xs:attribute name='jid' type='xs:string' use='required'/>
 
 
         </xs:extension>
 
         </xs:extension>
 
 
       </xs:simpleContent>
 
       </xs:simpleContent>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='reason' type='xs:string'/>
 
   <xs:element name='reason' type='xs:string'/>
 
 
  
 
   <xs:simpleType name='empty'>
 
   <xs:simpleType name='empty'>
 
 
     <xs:restriction base='xs:string'>
 
     <xs:restriction base='xs:string'>
 
 
       <xs:enumeration value=''/>
 
       <xs:enumeration value=''/>
 
 
     </xs:restriction>
 
     </xs:restriction>
 
 
   </xs:simpleType>
 
   </xs:simpleType>
 
 
  
 
</xs:schema>
 
</xs:schema>
 +
</source>
  
   
+
===http://jabber.org/protocol/muc#owner===
 
+
 
+
 
+
18.4 http://jabber.org/protocol/muc#owner
+
 
+
 
+
  
 +
<source lang="xml">
 
<?xml version='1.0' encoding='UTF-8'?>
 
<?xml version='1.0' encoding='UTF-8'?>
 
 
  
 
<xs:schema
 
<xs:schema
 
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
 
     targetNamespace='http://jabber.org/protocol/muc#owner'
 
     targetNamespace='http://jabber.org/protocol/muc#owner'
 
 
     xmlns='http://jabber.org/protocol/muc#owner'
 
     xmlns='http://jabber.org/protocol/muc#owner'
 
 
     elementFormDefault='qualified'>
 
     elementFormDefault='qualified'>
 
 
  
 
   <xs:annotation>
 
   <xs:annotation>
 
 
     <xs:documentation>
 
     <xs:documentation>
 
 
       The protocol documented by this schema is defined in
 
       The protocol documented by this schema is defined in
 
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
 
     </xs:documentation>
 
     </xs:documentation>
 
 
   </xs:annotation>
 
   </xs:annotation>
 
 
  
 
   <xs:import  
 
   <xs:import  
 
 
       namespace='jabber:x:data'
 
       namespace='jabber:x:data'
 
 
       schemaLocation='http://www.xmpp.org/schemas/x-data.xsd'/>
 
       schemaLocation='http://www.xmpp.org/schemas/x-data.xsd'/>
 
 
  
 
   <xs:element name='query'>
 
   <xs:element name='query'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:choice xmlns:xdata='jabber:x:data' minOccurs='0'>
 
       <xs:choice xmlns:xdata='jabber:x:data' minOccurs='0'>
 
 
         <xs:element ref='xdata:x'/>
 
         <xs:element ref='xdata:x'/>
 
 
         <xs:element ref='destroy'/>
 
         <xs:element ref='destroy'/>
 
 
       </xs:choice>
 
       </xs:choice>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:element name='destroy'>
 
   <xs:element name='destroy'>
 
 
     <xs:complexType>
 
     <xs:complexType>
 
 
       <xs:sequence>
 
       <xs:sequence>
 
 
         <xs:element name='password' type='xs:string' minOccurs='0'/>
 
         <xs:element name='password' type='xs:string' minOccurs='0'/>
 
 
         <xs:element name='reason' type='xs:string' minOccurs='0'/>
 
         <xs:element name='reason' type='xs:string' minOccurs='0'/>
 
 
       </xs:sequence>
 
       </xs:sequence>
 
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
       <xs:attribute name='jid' type='xs:string' use='optional'/>
 
 
     </xs:complexType>
 
     </xs:complexType>
 
 
   </xs:element>
 
   </xs:element>
 
 
  
 
   <xs:simpleType name='empty'>
 
   <xs:simpleType name='empty'>
 
 
     <xs:restriction base='xs:string'>
 
     <xs:restriction base='xs:string'>
 
 
       <xs:enumeration value=''/>
 
       <xs:enumeration value=''/>
 
 
     </xs:restriction>
 
     </xs:restriction>
 
 
   </xs:simpleType>
 
   </xs:simpleType>
 
 
  
 
</xs:schema>
 
</xs:schema>
 +
</source>
  
   
+
===http://jabber.org/protocol/muc#unique===
 
+
 
+
 
+
18.5 http://jabber.org/protocol/muc#unique
+
 
+
 
+
  
 +
<source lang="xml">
 
<?xml version='1.0' encoding='UTF-8'?>
 
<?xml version='1.0' encoding='UTF-8'?>
 
 
  
 
<xs:schema
 
<xs:schema
 
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
     xmlns:xs='http://www.w3.org/2001/XMLSchema'
 
 
     targetNamespace='http://jabber.org/protocol/muc#unique'
 
     targetNamespace='http://jabber.org/protocol/muc#unique'
 
 
     xmlns='http://jabber.org/protocol/muc#unique'
 
     xmlns='http://jabber.org/protocol/muc#unique'
 
 
     elementFormDefault='qualified'>
 
     elementFormDefault='qualified'>
 
 
  
 
   <xs:annotation>
 
   <xs:annotation>
 
 
     <xs:documentation>
 
     <xs:documentation>
 
 
       The protocol documented by this schema is defined in
 
       The protocol documented by this schema is defined in
 
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
       XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
 
 
     </xs:documentation>
 
     </xs:documentation>
 
 
   </xs:annotation>
 
   </xs:annotation>
 
 
  
 
   <xs:element name='unique' type='xs:string'/>
 
   <xs:element name='unique' type='xs:string'/>
 
 
  
 
</xs:schema>
 
</xs:schema>
 +
</source>
  
   
+
==鸣谢==
  
 +
作者感谢以下个人,为他们很多对于本协议草案的帮助性的评论: David Sutton, Peter Millard, Joe Hildebrand, Craig Kaes, Alexey Shchepin, David Waite, Jean-Louis Seguineau, Jacek Konieczny, Gaston Dombiak, 以及其他在 jdev@conference.jabber.org 会议室和在 Standards 邮件列表里的人.
  
 +
==附录==
 +
===附录A:文档信息===
  
19. Acknowledgements
+
系列:[http://xmpp.org/extensions/ XEP]
  
 +
序号:0045
  
 +
发布者:[http://xmpp.org/xsf/ XMPP标准基金会]
  
The author would like to thank the following individuals for their many helpful comments on various drafts of this proposal: David Sutton, Peter Millard, Joe Hildebrand, Craig Kaes, Alexey Shchepin, David Waite, Jean-Louis Seguineau, Jacek Konieczny, Gaston Dombiak, and many others in the jdev@conference.jabber.org conference room and on the Standards mailing list.
+
状态:[http://xmpp.org/extensions/xep-0001.html#states-Draft 草案 ]
  
Notes
+
类型:[http://www.xmpp.org/extensions/xep-0001.html#types-Standards%20Track 标准跟踪]
  
 +
版本:1.24
  
 +
最后更新:2008-07-16
  
1. RFC 1459: Internet Relay Chat <http://tools.ietf.org/html/rfc1459>.
+
批准机构:[http://xmpp.org/council/ XMPP理事会]
  
 +
依赖标准:XMPP Core, XMPP IM, XEP-0004, XEP-0030, XEP-0068, XEP-0082, XEP-0128
  
 +
替代标准:无
  
2. RFC 2810: Internet Relay Chat: Architecture <http://tools.ietf.org/html/rfc2810>.
+
被替代标准:无
  
 +
缩略名:muc
  
 +
muc名字空间的XML方案: <http://www.xmpp.org/schemas/muc.xsd>
  
3. RFC 2811: Internet Relay Chat: Channel Management <http://tools.ietf.org/html/rfc2811>.
+
muc#admin名字空间的XML方案: <http://www.xmpp.org/schemas/muc-admin.xsd>
  
 +
muc#owner名字空间的XML方案: <http://www.xmpp.org/schemas/muc-owner.xsd>
  
 +
muc#unique名字空间的XML方案: <http://www.xmpp.org/schemas/muc-unique.xsd>
  
4. RFC 2812: Internet Relay Chat: Client Protocol <http://tools.ietf.org/html/rfc2812>.
+
muc#user名字空间的XML方案: <http://www.xmpp.org/schemas/muc-user.xsd>
  
 +
注册表: <http://www.xmpp.org/registrar/muc.html>
  
 +
原文控制: [http://svn.xmpp.org:18080/browse/XMPP/trunk/extensions/xep-0045.xml HTML] [http://svn.xmpp.org:18080//changelog/~rss/XMPP/trunk/extensions/xep-0045.xml/rss.xml RSS]
  
5. RFC 2813: Internet Relay Chat: Server Protocol <http://tools.ietf.org/html/rfc2813>.
+
本文的其它格式: [http://xmpp.org/extensions/xep-0045.xml XML] [http://xmpp.org/extensions/xep-0045.pdf PDF]
  
 +
===附录B:作者信息===
  
 +
'''Peter Saint-Andre'''
  
6. http://www.jabber.org/protocol/groupchat.html
+
Email: [mailto:stpeter@jabber.org stpeter@jabber.org]
  
 +
JabberID: stpeter@jabber.org
  
 +
URI: https://stpeter.im/
  
7. XEP-0030: Service Discovery <http://www.xmpp.org/extensions/xep-0030.html>.
+
{{Template:XEP附录CDEF}}
  
 +
===附录G:备注===
  
 +
# RFC 1459: Internet Relay Chat <http://tools.ietf.org/html/rfc1459>.
 +
# RFC 2810: Internet Relay Chat: Architecture <http://tools.ietf.org/html/rfc2810>.
 +
# RFC 2811: Internet Relay Chat: Channel Management <http://tools.ietf.org/html/rfc2811>.
 +
# RFC 2812: Internet Relay Chat: Client Protocol <http://tools.ietf.org/html/rfc2812>.
 +
# RFC 2813: Internet Relay Chat: Server Protocol <http://tools.ietf.org/html/rfc2813>.
 +
# XEP-0133: Service Administration <http://xmpp.org/extensions/xep-0133.html>.
 +
# XEP-0030: Service Discovery <http://xmpp.org/extensions/xep-0030.html>.
 +
# XEP-0059: Result Set Management <http://xmpp.org/extensions/xep-0059.html>.
 +
# XEP-0128: Service Discovery Extensions <http://xmpp.org/extensions/xep-0128.html>.
 +
# RFC 3920: 可扩展的消息和出席信息协议 (XMPP): Core <http://tools.ietf.org/html/rfc3920>.
 +
# XEP-0203: Delayed Delivery <http://xmpp.org/extensions/xep-0203.html>.
 +
# XEP-0091: Legacy Delayed Delivery <http://xmpp.org/extensions/xep-0091.html>.
 +
# XEP-0082: XMPP Date and Time Profiles <http://xmpp.org/extensions/xep-0082.html>.
 +
# RFC 3921: 可扩展的消息和出席信息协议 (XMPP): Instant Messaging and Presence <http://tools.ietf.org/html/rfc3921>.
 +
# XEP-0249: Direct MUC Invitations <http://xmpp.org/extensions/xep-0249.html>.
 +
# XEP-0077: In-Band Registration <http://xmpp.org/extensions/xep-0077.html>.
 +
# XEP-0004: Data Forms <http://xmpp.org/extensions/xep-0004.html>.
 +
# 一些评论者抱怨公开房间的所有者和管理员存在潜在的滥用; 很不幸的, 能力越大责任越大.
 +
# XEP-0050: Ad-Hoc Commands <http://xmpp.org/extensions/xep-0050.html>.
 +
# XEP-0060: Publish-Subscribe <http://xmpp.org/extensions/xep-0060.html>.
 +
# 这和房间配置的行为不同, 这里 'muc#roomconfig_roomowners' 字段指定房间所有者的完整列表, 不是delta.
 +
# 这和房间配置的行为不同, 这里 'muc#roomconfig_roomadmins' 字段指定房间管理眼的完整列表, 不是delta.
 +
# XEP-0086: Error Condition Mappings <http://xmpp.org/extensions/xep-0086.html>.
 +
# RFC 2616: Hypertext Transport Protocol -- HTTP/1.1 <http://tools.ietf.org/html/rfc2616>.
 +
# RFC 1893: Enhanced Mail System Status Codes <http://tools.ietf.org/html/rfc1893>.
 +
# 互联网编号分配机构 (IANA) 是用于互联网协议的唯一性参数值分配的核心协调者, 例如号码和URI计划. 更多信息, 见 <http://www.iana.org/>.
 +
# XMPP登记员 XMPP Registrar 维护着一个保留的协议名字空间以及用于由XMPP标准基金会批准的XMPP扩展协议的上下文参数的注册项的列表. 更多信息, 见 <http://xmpp.org/registrar/>.
 +
# XEP-0068: Field Data Standardization for Data Forms <http://xmpp.org/extensions/xep-0068.html>.
 +
# XEP-0147: XMPP URI Query Components <http://xmpp.org/extensions/xep-0147.html>.
 +
# XEP-0022: Message Events <http://xmpp.org/extensions/xep-0022.html>.
 +
# XEP-0085: Chat State Notifications <http://xmpp.org/extensions/xep-0085.html>.
 +
# XEP-0071: XHTML-IM <http://xmpp.org/extensions/xep-0071.html>.
 +
# XEP-0245: The /me Command <http://xmpp.org/extensions/xep-0245.html>.
  
8. XEP-0128: Service Discovery Extensions <http://www.xmpp.org/extensions/xep-0128.html>.
+
===附录H: 修订历史===
  
 +
注意: 本协议的旧版本可能在 http://xmpp.org/extensions/attic/ 还可用
  
 +
'''版本 1.24 (2008-07-16)'''
  
9. RFC 3920: Extensible Messaging and Presence Protocol (XMPP): Core <http://tools.ietf.org/html/rfc3920>.
+
增加了更多原因reason元素的例子; 移除了关于黑名单包含的昵称部分; 增加了拒绝服务注意事项.
  
 +
(psa)
  
 +
'''版本 1.23 (2008-01-14)'''
  
10. XEP-0203: Delayed Delivery <http://www.xmpp.org/extensions/xep-0203.html>.
+
* 定义了 getmemberlist 房间配置选项
 +
* 增加了直接邀请协议
 +
* 修正了当房间满的时候房间承认所有者/管理员的逻辑
 +
* 定义了和LDAP群关联的服务发现扩展字段
 +
* 指定了房间配置字段能被列入扩展的房间信息之中
 +
* 指定了消息格式用于用户不在房间时的岗位变更
 +
* 增加了例子展示结果集管理
 +
* 推荐出席信息错误中包含的MUC子元素
 +
* 为一对一聊天和多用户聊天的连续性描述了ThreadID的使用, 包括在邀请中为 continue 元素定义 thread 属性.
  
 +
(psa)
  
 +
'''版本 1.22 (2007-04-10)'''
  
11. XEP-0091: Delayed Delivery <http://www.xmpp.org/extensions/xep-0091.html>.
+
更新了延迟消息递送以反映 XEP-0203 演化到草案和 XEP-0091 的过时.
 
+
 
+
 
+
12. XEP-0082: XMPP Date and Time Profiles <http://www.xmpp.org/extensions/xep-0082.html>.
+
 
+
 
+
 
+
13. RFC 3921: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence <http://tools.ietf.org/html/rfc3921>.
+
 
+
 
+
 
+
14. XEP-0077: In-Band Registration <http://www.xmpp.org/extensions/xep-0077.html>.
+
 
+
 
+
 
+
15. XEP-0004: Data Forms <http://www.xmpp.org/extensions/xep-0004.html>.
+
 
+
 
+
 
+
16. Some commentors have complained that this opens room owners and administrators up to potential abuse; unfortunately, with great power comes great responsibility.
+
 
+
 
+
 
+
17. XEP-0133: Service Administration <http://www.xmpp.org/extensions/xep-0133.html>.
+
 
+
 
+
 
+
18. XEP-0050: Ad-Hoc Commands <http://www.xmpp.org/extensions/xep-0050.html>.
+
 
+
 
+
 
+
19. XEP-0060: Publish-Subscribe <http://www.xmpp.org/extensions/xep-0060.html>.
+
 
+
 
+
 
+
20. This is different from the behavior of room configuration, wherein the 'muc#roomconfig_roomowners' field specifies the full list of room owners, not the delta.
+
 
+
 
+
 
+
21. This is different from the behavior of room configuration, wherein the 'muc#roomconfig_roomadmins' field specifies the full list of room admins, not the delta.
+
 
+
 
+
 
+
22. XEP-0086: Error Condition Mappings <http://www.xmpp.org/extensions/xep-0086.html>.
+
 
+
 
+
 
+
23. RFC 2616: Hypertext Transport Protocol -- HTTP/1.1 <http://tools.ietf.org/html/rfc2616>.
+
 
+
 
+
 
+
24. RFC 1893: Enhanced Mail System Status Codes <http://tools.ietf.org/html/rfc1893>.
+
 
+
 
+
 
+
25. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.
+
 
+
 
+
 
+
26. The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see <http://www.xmpp.org/registrar/>.
+
 
+
 
+
 
+
27. XEP-0068: Field Data Standardization for Data Forms <http://www.xmpp.org/extensions/xep-0068.html>.
+
 
+
 
+
 
+
28. XEP-0147: XMPP URI Query Components <http://www.xmpp.org/extensions/xep-0147.html>.
+
 
+
 
+
 
+
29. XEP-0022: Message Events <http://www.xmpp.org/extensions/xep-0022.html>.
+
 
+
 
+
 
+
30. XEP-0085: Chat State Notifications <http://www.xmpp.org/extensions/xep-0085.html>.
+
 
+
 
+
 
+
31. XEP-0071: XHTML-IM <http://www.xmpp.org/extensions/xep-0071.html>.
+
 
+
Revision History
+
 
+
Version 1.22 (2007-04-10)
+
 
+
 
+
 
+
Updated delayed delivery reference to reflect advancement of XEP-0203 to Draft and deprecation of XEP-0091.
+
  
 
(psa)
 
(psa)
  
Version 1.21 (2006-09-13)
+
'''版本 1.21 (2006-09-13)'''
 
+
 
+
 
+
    * Clarified that inclusion of MUC extension in room join/create request triggers Data Forms flow but that absence of MUC extension leads to automatic room creation for backwards compatibility with older groupchat 1.0 protocol.
+
 
+
    * Specified use of <not-acceptable/> error on nickname change if nicks are locked down.
+
 
+
    * Required clients to discover room configuration prior to entering room and specified related security considerations, including use of privacy-related status codes 170, 171, 172, 173, and 174.
+
 
+
    * Specified use of <not-acceptable/> error if room configuration options cannot be processed or violate service policies.
+
 
+
    * Made explicit that roomnicks must not consist only of spaces.
+
 
+
    * Moved all service discovery use cases into dedicated section.
+
 
+
    * Changed urn:xmpp:delay support from SHOULD to MUST.
+
 
+
    * Clarified that _whois room configuration option specifies room type.
+
 
+
    * Defined XEP-0128 room information fields for discussion logs, associated pubsub node, and contact JID.
+
 
+
    * Specified that changing role to moderator upon affiliation change to admin or owner is recommended, not required.
+
 
+
    * Added internationalization consideration about localization of field labels for various data forms.
+
 
+
    * Specified that implementations may persist roles across visits and should do so for moderated rooms.
+
 
+
    * Added protocol and service discovery feature for requesting a unique room name prior to room creation.
+
 
+
    * Further clarified nature of reserved room nicknames and nickname lockdown.
+
 
+
    * Defined data forms for requesting voice and approving voice requests.
+
 
+
    * Added multiple invitee example for XMPP URI.
+
 
+
    * Clarified order of presence, discussion history, etc.
+
 
+
    * Added status codes for occupant's own roomnick, service-modified roomnick, and warning that room discussion is publicly logged.
+
 
+
    * Clarified privacy and anonymity considerations regarding room logging and non-anonymous rooms.
+
 
+
  
 +
* 澄清了MUC扩展的介入,在房间加入/创建请求触发数据表单流但没有MUC扩展可导致自动房间创建以向后兼容旧的 groupchat 1.0 协议.
 +
* 指定昵称变更时如果昵称被锁定则返回 <not-acceptable/> 错误.
 +
* 要求客户端在进入房间之前发现房间配置并指定相关的安全事项, 包括使用隐私相关的状态码 170, 171, 172, 173, 和 174.
 +
* 指定在房间配置选项不能被执行或违反服务策略时使用 <not-acceptable/> 错误.
 +
* 强制要求房间昵称不能只包含空格.
 +
* 移除所有服务发现用例到专用章节.
 +
* 修改 urn:xmpp:delay 支持从 SHOULD 改为 MUST.
 +
* 澄清 _whois 房间配置选项定义房间类型.
 +
* 定义 XEP-0128 房间信息字段用于讨论记录, 关联的 pubsub 节点, 以及联系人 JID.
 +
* 指出修改角色到主持人导致岗位变更为管理员或所有者成为推荐的, 而不是必需的.
 +
* 增加了国际化事项中关于数据表单的本地化的部分.
 +
* 指出实现可以持久化角色括月整个访问并且应该在被主持的房间里这样做.
 +
* 增加了协议和服务发现特性用于在新建房间之前请求唯一的房间名.
 +
* 更多澄清保留的房间昵称和昵称锁定的性质.
 +
* 定义数据表单用于请求发言权和批准发言申请.
 +
* 增加了多个邀请的例子用于XMPP URI.
 +
* 澄清了出席信息,讨论历史的顺序, 等等.
 +
* 增加了状态码用于房客拥有的房间昵称, 服务修改的房间昵称, 并警告房间讨论被公开记录.
 +
* 澄清关于房间记录和非匿名房间的隐私和匿名事项.
  
 
(psa)
 
(psa)
  
Version 1.20 (2005-09-08)
+
'''版本 1.20 (2005-09-08)'''
  
 
+
同意了踢人和禁止用户的能力, 并定义了一个用户不能被一个比自己岗位低的主持人或管理员踢或禁止.
 
+
Harmonized ability to kick and ban users, and clarified that a user cannot be kicked or banned by a moderator or admin with a lower affiliation.
+
  
 
(psa)
 
(psa)
  
Version 1.19 (2005-04-21)
+
'''版本 1.19 (2005-04-21)'''
 
+
 
+
  
Specified how to send multiple invitations simultaneously; corrected some errors regarding consistency of affiliation state changes; changed message events prohibition from MUST NOT to SHOULD NOT; corrected error handling related to the #traffic disco node; allowed <password/> as a child of <destroy/>; changed max users error from <not-allowed/> to <service-unavailable/>; specified that the maxchars attribute counts characters in complete XML stanzas; added disco features for FORM_TYPEs; defined registry for status codes; split Create Instant Room into separate use case for protocol compliance purposes; adjusted XML schemas to reflect the foregoing changes; re-wrote the introduction; clarified small textual matters throughout.
+
定义了怎样发送并发多邀请; 纠正了一些和岗位变更状态一致性的错误; 修改了消息事件禁令表单从 MUST NOT SHOULD NOT; 修正了和 #traffic disco 节点相关的错误处理; 允许了 <password/> 作为<destroy/>的一个子元素; 修改了最大用户数错误从 <not-allowed/> <service-unavailable/>; 指定了 maxchars 属性的字符数是指完整的 XML ; FORM_TYPEs;增加了 disco 特性 为状态码定义了注册表; 为遵守协议分开了新建即时房间的用例; 调整了 XML 架构以反映之前的修改; 重写了绪论; 澄清了小的文本错误.
  
 
(psa)
 
(psa)
  
 
Version 1.18 (2004-11-02)
 
Version 1.18 (2004-11-02)
 
 
  
 
Corrected several errors in the affiliation state chart and in the examples (wrong FORM_TYPE values); mentioned /me command.
 
Corrected several errors in the affiliation state chart and in the examples (wrong FORM_TYPE values); mentioned /me command.
 
 
(psa)
 
(psa)
 
 
Version 1.17 (2004-10-04)
 
Version 1.17 (2004-10-04)
 
 
  
 
Added text about allowable extension namespaces and related service discovery mechanisms; specified well-known service discovery nodes; added conformance terms to clarify some descriptions; modified affiliation state chart to allow more flexible state changes; per list dicussion, added ability to convert a one-to-one chat into a conference, including sending of history; specified error to use when max users limit is reached; specified form for admin approval of user registration requests and modified FORM_TYPE from http://jabber.org/protocol/muc#user to http://jabber.org/protocol/muc#register; modified FORM_TYPE for room configuration from http://jabber.org/protocol/muc#owner to http://jabber.org/protocol/muc#roomconfig.
 
Added text about allowable extension namespaces and related service discovery mechanisms; specified well-known service discovery nodes; added conformance terms to clarify some descriptions; modified affiliation state chart to allow more flexible state changes; per list dicussion, added ability to convert a one-to-one chat into a conference, including sending of history; specified error to use when max users limit is reached; specified form for admin approval of user registration requests and modified FORM_TYPE from http://jabber.org/protocol/muc#user to http://jabber.org/protocol/muc#register; modified FORM_TYPE for room configuration from http://jabber.org/protocol/muc#owner to http://jabber.org/protocol/muc#roomconfig.
 
 
(psa)
 
(psa)
 
 
Version 1.16 (2004-06-30)
 
Version 1.16 (2004-06-30)
 
 
  
 
Added example and registry submission for service discovery extension.
 
Added example and registry submission for service discovery extension.
 
 
(psa)
 
(psa)
 
 
Version 1.15 (2004-06-24)
 
Version 1.15 (2004-06-24)
 
 
  
 
Removed jabber:iq:browse references; clarified order of presence stanzas sent to new occupant on entering room; specified format of in-room messages (type='groupchat', from='room@service'); clarified allowable attributes in various list-related operations; made admin/owner revocation text and examples consistent with state chart; clarified ownership revocation conflict scenarios; changed the 'muc#roomconfig_inviteonly' field to 'muc#roomconfig_membersonly'; changed attribute order in examples to match XML canonicalization rules; corrected several errors in the schemas.
 
Removed jabber:iq:browse references; clarified order of presence stanzas sent to new occupant on entering room; specified format of in-room messages (type='groupchat', from='room@service'); clarified allowable attributes in various list-related operations; made admin/owner revocation text and examples consistent with state chart; clarified ownership revocation conflict scenarios; changed the 'muc#roomconfig_inviteonly' field to 'muc#roomconfig_membersonly'; changed attribute order in examples to match XML canonicalization rules; corrected several errors in the schemas.
 
 
(psa)
 
(psa)
 
 
Version 1.14 (2004-05-03)
 
Version 1.14 (2004-05-03)
 
 
  
 
Corrected discovery of registered roomnicks; added note about error to return if nicks are locked down.
 
Corrected discovery of registered roomnicks; added note about error to return if nicks are locked down.
 
 
(psa)
 
(psa)
 
 
Version 1.13 (2004-03-31)
 
Version 1.13 (2004-03-31)
 
 
  
 
Fixed an error in the muc#user schema.
 
Fixed an error in the muc#user schema.
 
 
(psa)
 
(psa)
 
 
Version 1.12 (2004-03-01)
 
Version 1.12 (2004-03-01)
 
 
  
 
Corrected a few errors in the examples; added IQ results in order to clarify workflows.
 
Corrected a few errors in the examples; added IQ results in order to clarify workflows.
 
 
(psa)
 
(psa)
 
 
Version 1.11 (2004-02-05)
 
Version 1.11 (2004-02-05)
 
 
  
 
Clarified JID matching rules (same as for privacy lists in XMPP IM).
 
Clarified JID matching rules (same as for privacy lists in XMPP IM).
 
 
(psa)
 
(psa)
 
 
Version 1.10 (2004-01-07)
 
Version 1.10 (2004-01-07)
 
 
  
 
Added XMPP error handling; fully specified all conformance terms.
 
Added XMPP error handling; fully specified all conformance terms.
 
 
(psa)
 
(psa)
 
 
Version 1.9 (2003-12-14)
 
Version 1.9 (2003-12-14)
 
 
  
 
Removed protocol for requesting voice in a moderated room (should be performed using Ad-Hoc Commands).
 
Removed protocol for requesting voice in a moderated room (should be performed using Ad-Hoc Commands).
 
 
(psa)
 
(psa)
 
 
Version 1.8 (2003-12-04)
 
Version 1.8 (2003-12-04)
 
 
  
 
Added protocol for requesting voice in a moderated room; added (informational) mapping of IRC commands to MUC protocols.
 
Added protocol for requesting voice in a moderated room; added (informational) mapping of IRC commands to MUC protocols.
 
 
(psa)
 
(psa)
 
 
Version 1.7 (2003-10-21)
 
Version 1.7 (2003-10-21)
 
 
  
 
Added room configuration option for restricting presence broadcast to certain roles.
 
Added room configuration option for restricting presence broadcast to certain roles.
 
 
(psa)
 
(psa)
 
 
Version 1.6 (2003-10-03)
 
Version 1.6 (2003-10-03)
 
 
  
 
Added history management protocol on entering a room.
 
Added history management protocol on entering a room.
 
 
(psa)
 
(psa)
 
 
Version 1.5 (2003-09-11)
 
Version 1.5 (2003-09-11)
 
 
  
 
Specified that ban occurs by JID, not roomnick; allowed privileged users to send messages to the room even if not present in the room; added note that service should remove occupant if a delivery-related stanza error occurs; enabled user to disco the room in order to discover registered roomnick; specified that "banning" by domain or regex is a service-level configuration matter and therefore out of scope for MUC; specified that role should be decremented as appropriate if affiliation is lowered; added some clarifying text to room creation workflow; added implementation note about sending an out-of-band message if a user's affiliation changes while the user is not in the room; fixed stringprep references (room nicks use Resourceprep); clarified relationship between Room ID (i.e., node identifier of Room JID, which may be opaque) and natural-language Room Name; specified Field Standardization profile per XEP-0068; defined XMPP Registrar submissions; added schema locations.
 
Specified that ban occurs by JID, not roomnick; allowed privileged users to send messages to the room even if not present in the room; added note that service should remove occupant if a delivery-related stanza error occurs; enabled user to disco the room in order to discover registered roomnick; specified that "banning" by domain or regex is a service-level configuration matter and therefore out of scope for MUC; specified that role should be decremented as appropriate if affiliation is lowered; added some clarifying text to room creation workflow; added implementation note about sending an out-of-band message if a user's affiliation changes while the user is not in the room; fixed stringprep references (room nicks use Resourceprep); clarified relationship between Room ID (i.e., node identifier of Room JID, which may be opaque) and natural-language Room Name; specified Field Standardization profile per XEP-0068; defined XMPP Registrar submissions; added schema locations.
 
 
(psa)
 
(psa)
 
 
Version 1.4 (2003-02-16)
 
Version 1.4 (2003-02-16)
 
 
  
 
Added XML schemas.
 
Added XML schemas.
 
 
(psa)
 
(psa)
 
 
Version 1.3 (2003-02-11)
 
Version 1.3 (2003-02-11)
 
 
  
 
Added reference to nodeprep Internet-Draft.
 
Added reference to nodeprep Internet-Draft.
 
 
(psa)
 
(psa)
 
 
Version 1.2 (2003-01-30)
 
Version 1.2 (2003-01-30)
 
 
  
 
Commented out revision history prior to version 1.0 (too long); clarified business rules regarding when nicks, full JIDs, and bare JIDs are used in reference to roles and affiliations; consistently specified that extended presence information in the muc#user namespace must include the full JID as the value of the 'jid' attribute in all cases; cleaned up text and examples throughout; added open issue regarding syntax of room nicknames.
 
Commented out revision history prior to version 1.0 (too long); clarified business rules regarding when nicks, full JIDs, and bare JIDs are used in reference to roles and affiliations; consistently specified that extended presence information in the muc#user namespace must include the full JID as the value of the 'jid' attribute in all cases; cleaned up text and examples throughout; added open issue regarding syntax of room nicknames.
 
 
(psa)
 
(psa)
 
 
Version 1.1 (2002-12-16)
 
Version 1.1 (2002-12-16)
 
 
  
 
Added protocol for declining an invitation; replaced <created/> element with status code 201; modified the destroy room protocol so that <destroy/> is a child of <query/>; clarified usage of 'nick' attribute when adding members; prohibited use of message events.
 
Added protocol for declining an invitation; replaced <created/> element with status code 201; modified the destroy room protocol so that <destroy/> is a child of <query/>; clarified usage of 'nick' attribute when adding members; prohibited use of message events.
 
 
(psa)
 
(psa)
 
 
Version 1.0 (2002-11-21)
 
Version 1.0 (2002-11-21)
 
 
  
 
Per a vote of the Jabber Council, revision 0.23 was advanced to Draft on 2002-11-21. (For earlier revision history, refer to XML source.)
 
Per a vote of the Jabber Council, revision 0.23 was advanced to Draft on 2002-11-21. (For earlier revision history, refer to XML source.)
 
 
(psa)
 
(psa)
 
 
Version 0.23 (2002-11-06)
 
Version 0.23 (2002-11-06)
 
 
  
 
Added examples for disco#items queries sent to a room; prohibited 'type' attribute on invite messages sent from client to room; added dependencies on browse and disco; changed 'room user' to 'occupant'; fixed many small errors throughout.
 
Added examples for disco#items queries sent to a room; prohibited 'type' attribute on invite messages sent from client to room; added dependencies on browse and disco; changed 'room user' to 'occupant'; fixed many small errors throughout.
 
 
(psa)
 
(psa)
 
 
Version 0.22 (2002-11-04)
 
Version 0.22 (2002-11-04)
 
 
  
 
Added example for disco#items; added support for cancellation of room configuration using type='cancel' from XEP-0004; noted 403 error for invites sent by non-admins in members-only room.
 
Added example for disco#items; added support for cancellation of room configuration using type='cancel' from XEP-0004; noted 403 error for invites sent by non-admins in members-only room.
 
 
(psa)
 
(psa)
 
 
Version 0.21 (2002-11-01)
 
Version 0.21 (2002-11-01)
 
 
  
 
Clarified several small ambiguities; made <body/> optional on invites sent from the service to the invitee; added error scenarios for changing nickname and for destroying the room; specified that the service must return the full member list for a members-only room (not only the members in the room); updated the disco examples to track protocol changes.
 
Clarified several small ambiguities; made <body/> optional on invites sent from the service to the invitee; added error scenarios for changing nickname and for destroying the room; specified that the service must return the full member list for a members-only room (not only the members in the room); updated the disco examples to track protocol changes.
 
 
(psa)
 
(psa)
 
 
Version 0.20 (2002-10-29)
 
Version 0.20 (2002-10-29)
 
 
  
 
Specified that messages sent to change the room subject must be of type "groupchat"; updated the legal notice to conform to the XSF IPR policy.
 
Specified that messages sent to change the room subject must be of type "groupchat"; updated the legal notice to conform to the XSF IPR policy.
 
 
(psa)
 
(psa)
 
 
Version 0.19 (2002-10-28)
 
Version 0.19 (2002-10-28)
 
 
  
 
Added ability to create an instant room within MUC (not by using gc-1.0 protocol); cleaned up disco examples.
 
Added ability to create an instant room within MUC (not by using gc-1.0 protocol); cleaned up disco examples.
 
 
(psa)
 
(psa)
 
 
Version 0.18 (2002-10-27)
 
Version 0.18 (2002-10-27)
 
 
  
 
Added experimental support for disco; added sections for security, IANA, and JANA considerations; corrected typographical errors; cleaned up some DocBook formatting.
 
Added experimental support for disco; added sections for security, IANA, and JANA considerations; corrected typographical errors; cleaned up some DocBook formatting.
 
 
(psa)
 
(psa)
 
 
Version 0.17 (2002-10-23)
 
Version 0.17 (2002-10-23)
 
 
  
 
Added the optional <actor/> element (with 'jid' attribute) to <item/> elements inside presence stanzas of type "unavailable" that are sent to users who are kicked or banned, as well as within IQs for tracking purposes; reverted all list editing use cases (ban, voice, member, moderator, admin, owner) to use of MUC format rather than 'jabber:x:data' namespace; added several guidelines regarding generation and handling of XML stanzas; cleaned up the change room subject use case; changed several ambiguous uses of 'would', 'can', and 'will' to 'should', 'may', or 'must'; fixed several small errors in the text, examples, and DTDs.
 
Added the optional <actor/> element (with 'jid' attribute) to <item/> elements inside presence stanzas of type "unavailable" that are sent to users who are kicked or banned, as well as within IQs for tracking purposes; reverted all list editing use cases (ban, voice, member, moderator, admin, owner) to use of MUC format rather than 'jabber:x:data' namespace; added several guidelines regarding generation and handling of XML stanzas; cleaned up the change room subject use case; changed several ambiguous uses of 'would', 'can', and 'will' to 'should', 'may', or 'must'; fixed several small errors in the text, examples, and DTDs.
 
 
(psa)
 
(psa)
 
 
Version 0.16 (2002-10-20)
 
Version 0.16 (2002-10-20)
 
 
  
 
Added the <item/> element to presence stanzas of type "unavailable" in order to improve the tracking of user states in the room; consolidated <invitee/> and <invitor/> elements into an <invite/> element with 'from' and 'to' attributes; made <reason/> element always a child of <item/> or <invite/> in the muc#user namespace; moved the alternate room location in room destruction to a 'jid' attribute of the <alt/> element; further specified several error messages; disallowed simultaneous modifications of both affiliations and roles by a moderator or admin; added several more rules regarding handling of XML stanzas; added use cases for granting and revoking administrative privileges; adjusted DTD to track all changes.
 
Added the <item/> element to presence stanzas of type "unavailable" in order to improve the tracking of user states in the room; consolidated <invitee/> and <invitor/> elements into an <invite/> element with 'from' and 'to' attributes; made <reason/> element always a child of <item/> or <invite/> in the muc#user namespace; moved the alternate room location in room destruction to a 'jid' attribute of the <alt/> element; further specified several error messages; disallowed simultaneous modifications of both affiliations and roles by a moderator or admin; added several more rules regarding handling of XML stanzas; added use cases for granting and revoking administrative privileges; adjusted DTD to track all changes.
 
 
(psa)
 
(psa)
 
 
Version 0.15 (2002-10-18)
 
Version 0.15 (2002-10-18)
 
 
  
 
Fully incorporated the change to affiliations + roles; moved a number of admin use cases to a new section for moderator use cases; added participant use case for requesting membership; added admin use cases for adding members, removing members, granting and revoking moderator privileges, and modifying the moderator list; organized the sections in a more logical manner.
 
Fully incorporated the change to affiliations + roles; moved a number of admin use cases to a new section for moderator use cases; added participant use case for requesting membership; added admin use cases for adding members, removing members, granting and revoking moderator privileges, and modifying the moderator list; organized the sections in a more logical manner.
 
 
(psa)
 
(psa)
 
 
Version 0.14 (2002-10-17)
 
Version 0.14 (2002-10-17)
 
 
  
 
Significantly modified the privileges model by distinguishing between in-room "roles" and long-lived "affiliations"; specified the privileges of the various roles and affiliations; included state transition charts for both roles and affiliations; removed use of MUC protocol for editing ban, voice, and admin lists (but not for the actions of banning users and granting/revoking voice); added delivery rule regarding IQ stanzas; changed kick so that the action is based on changing the role to "none".
 
Significantly modified the privileges model by distinguishing between in-room "roles" and long-lived "affiliations"; specified the privileges of the various roles and affiliations; included state transition charts for both roles and affiliations; removed use of MUC protocol for editing ban, voice, and admin lists (but not for the actions of banning users and granting/revoking voice); added delivery rule regarding IQ stanzas; changed kick so that the action is based on changing the role to "none".
 
 
(psa)
 
(psa)
 
 
Version 0.13 (2002-10-16)
 
Version 0.13 (2002-10-16)
 
 
  
 
Corrected the change nickname examples (newnick sent on unavailable, no nick sent on available).
 
Corrected the change nickname examples (newnick sent on unavailable, no nick sent on available).
 
 
(psa)
 
(psa)
 
 
Version 0.12 (2002-10-16)
 
Version 0.12 (2002-10-16)
 
 
  
 
Removed SHA1 passwords; specified that room shall add passwords on invitations to password-protected rooms (not supplied by invitor).
 
Removed SHA1 passwords; specified that room shall add passwords on invitations to password-protected rooms (not supplied by invitor).
 
 
(psa)
 
(psa)
 
 
Version 0.11 (2002-10-16)
 
Version 0.11 (2002-10-16)
 
 
  
 
Changed 'participant' to 'room user' and 'discussant' to 'participant'; clarified presence rule about client generation of extended presence information; added role of 'none'.
 
Changed 'participant' to 'room user' and 'discussant' to 'participant'; clarified presence rule about client generation of extended presence information; added role of 'none'.
 
 
(psa)
 
(psa)
 
 
Version 0.10 (2002-10-15)
 
Version 0.10 (2002-10-15)
 
 
  
 
Fixed extended presence on entering or creating a room (plain '...muc' with no fragment); harmonized #user with #admin regarding the use of the <item/> element and associated attributes (jid, nick, etc.), and added 'role' attribute; modified management of voice, ban, admin, and member lists to use <query/> wrapper and new <item/> structure; changed the 'member' role to 'discussant', added 'outcast' role for banned users, and added new 'member' role to enable management of member lists; changed invitation-only rooms to members-only rooms and made appropriate adjustments to apply member lists to both members-only rooms and open rooms; modified nickname change protocol slightly to send the old nickname in the unavailable presence and the new nickname in the available presence; removed prohibition on members-only rooms that are password-protected; removed the <query/> wrapper for the <destroy/> element; updated the DTDs.
 
Fixed extended presence on entering or creating a room (plain '...muc' with no fragment); harmonized #user with #admin regarding the use of the <item/> element and associated attributes (jid, nick, etc.), and added 'role' attribute; modified management of voice, ban, admin, and member lists to use <query/> wrapper and new <item/> structure; changed the 'member' role to 'discussant', added 'outcast' role for banned users, and added new 'member' role to enable management of member lists; changed invitation-only rooms to members-only rooms and made appropriate adjustments to apply member lists to both members-only rooms and open rooms; modified nickname change protocol slightly to send the old nickname in the unavailable presence and the new nickname in the available presence; removed prohibition on members-only rooms that are password-protected; removed the <query/> wrapper for the <destroy/> element; updated the DTDs.
 
 
(psa)
 
(psa)
 
 
Version 0.9 (2002-10-13)
 
Version 0.9 (2002-10-13)
 
 
  
 
Added extended presence ('...#user') on entering a room for MUC clients; changed namespace on room creation request to '...#owner'; added a service discovery example using jabber:iq:browse; added information about discussion history; made small fixes to several examples; further defined the presence rules; transferred all implementation notes to a dedicated section; added a Terminology section.
 
Added extended presence ('...#user') on entering a room for MUC clients; changed namespace on room creation request to '...#owner'; added a service discovery example using jabber:iq:browse; added information about discussion history; made small fixes to several examples; further defined the presence rules; transferred all implementation notes to a dedicated section; added a Terminology section.
 
 
(psa)
 
(psa)
 
 
Version 0.8 (2002-10-10)
 
Version 0.8 (2002-10-10)
 
 
  
 
Made further changes to the room creation workflow (finally correct); removed feature discovery use case (this needs to be addressed by a real service discovery protocol!); added ability for room owners to edit the admin list; removed <body/> from invitations generated by the service; removed messages sent to kicked and banned users (handled by unavailable presence with status code); added a number of implementation notes; converted all examples to Shakespeare style.
 
Made further changes to the room creation workflow (finally correct); removed feature discovery use case (this needs to be addressed by a real service discovery protocol!); added ability for room owners to edit the admin list; removed <body/> from invitations generated by the service; removed messages sent to kicked and banned users (handled by unavailable presence with status code); added a number of implementation notes; converted all examples to Shakespeare style.
 
 
(psa)
 
(psa)
 
 
Version 0.7.6 (2002-10-09)
 
Version 0.7.6 (2002-10-09)
 
 
  
 
Fixed the room creation workflow; changed some terminology ("join" to "enter" and "leave" to "exit").
 
Fixed the room creation workflow; changed some terminology ("join" to "enter" and "leave" to "exit").
 
 
(psa)
 
(psa)
 
 
Version 0.7.5 (2002-10-08)
 
Version 0.7.5 (2002-10-08)
 
 
  
 
Specified and improved the handling of invitation-only rooms. In particular, added the ability for room admins to edit the invitation list and added a configuration option that limits the ability to send invitations to room admins only.
 
Specified and improved the handling of invitation-only rooms. In particular, added the ability for room admins to edit the invitation list and added a configuration option that limits the ability to send invitations to room admins only.
 
 
(psa)
 
(psa)
 
 
Version 0.7.4 (2002-10-07)
 
Version 0.7.4 (2002-10-07)
 
 
  
 
Changed namespaces from http://jabber.org/protocol/muc/owner etc. to http://jabber.org/protocol/muc#owner etc. per Jabber Council discussion.
 
Changed namespaces from http://jabber.org/protocol/muc/owner etc. to http://jabber.org/protocol/muc#owner etc. per Jabber Council discussion.
 
 
(psa)
 
(psa)
 
 
Version 0.7.3 (2002-10-07)
 
Version 0.7.3 (2002-10-07)
 
 
  
 
Changed namespaces to HTTP URIs; left role handling up to the implementation; further clarified presence rules.
 
Changed namespaces to HTTP URIs; left role handling up to the implementation; further clarified presence rules.
 
 
(psa)
 
(psa)
 
 
Version 0.7.2 (2002-10-06)
 
Version 0.7.2 (2002-10-06)
 
 
  
 
Disallowed kicking, banning, and revoking voice with respect to room admins and room owners; replaced <x/> with <query/> in the Discovering Room Features and Destroying a Room use cases; corrected some small errors and made many clarifications throughout.
 
Disallowed kicking, banning, and revoking voice with respect to room admins and room owners; replaced <x/> with <query/> in the Discovering Room Features and Destroying a Room use cases; corrected some small errors and made many clarifications throughout.
 
 
(psa)
 
(psa)
 
 
Version 0.7.1 (2002-10-04)
 
Version 0.7.1 (2002-10-04)
 
 
  
 
Removed <whois/> command (unnecessary since participants with appropriate privileges receive the full JID of all participants in presence stanzas); completed many small fixes throughout.
 
Removed <whois/> command (unnecessary since participants with appropriate privileges receive the full JID of all participants in presence stanzas); completed many small fixes throughout.
 
 
(psa)
 
(psa)
 
 
Version 0.7 (2002-10-03)
 
Version 0.7 (2002-10-03)
 
 
  
 
More clearly delineated participant roles and defined the hierarchy thereof (owner, admin, member, visitor); replaced <voice/> element in extended presence with <item role='member'/>; changed initial room configuration to use IQ rather than message; adjusted presence rules (especially regarding extended presence information); cleaned up examples throughout; updated DTD to track changes.
 
More clearly delineated participant roles and defined the hierarchy thereof (owner, admin, member, visitor); replaced <voice/> element in extended presence with <item role='member'/>; changed initial room configuration to use IQ rather than message; adjusted presence rules (especially regarding extended presence information); cleaned up examples throughout; updated DTD to track changes.
 
 
(psa)
 
(psa)
 
 
Version 0.6 (2002-09-21)
 
Version 0.6 (2002-09-21)
 
 
  
 
More clearly defined the scope; removed fully anonymous rooms; changed meaning of semi-anonymous rooms and of non-anonymous rooms; added mechanism for notification of full JIDs in non-anonymous rooms; replaced the <admin/> element in extended presence with a <role/> element (more extensible); changed room passwords to cleartext; added status codes for various messages received from the service; added lists of valid error and status codes associated with the 'http://jabber.org/protocol/muc#user' namespace; added a <reason/> element for invitations; made kick and ban reasons child elements rather than attributes; replaced stopgap feature discovery mechanism with jabber:iq:negotiate; added extended presence element to room creation request and clarified the room creation process; specified presence reflection rules; added method for destroying a room; adjusted DTDs to track all changes.
 
More clearly defined the scope; removed fully anonymous rooms; changed meaning of semi-anonymous rooms and of non-anonymous rooms; added mechanism for notification of full JIDs in non-anonymous rooms; replaced the <admin/> element in extended presence with a <role/> element (more extensible); changed room passwords to cleartext; added status codes for various messages received from the service; added lists of valid error and status codes associated with the 'http://jabber.org/protocol/muc#user' namespace; added a <reason/> element for invitations; made kick and ban reasons child elements rather than attributes; replaced stopgap feature discovery mechanism with jabber:iq:negotiate; added extended presence element to room creation request and clarified the room creation process; specified presence reflection rules; added method for destroying a room; adjusted DTDs to track all changes.
 
 
(psa)
 
(psa)
 
 
Version 0.5.1 (2002-09-20)
 
Version 0.5.1 (2002-09-20)
 
 
  
 
Added DTDs; changed feature discovery to use <x/> element rather than query and made service response come in IQ result; fixed reference to JID spec; changed 'grant' to 'add' and 'revoke' to 'remove' for consistency in the item attributes; made several other small changes.
 
Added DTDs; changed feature discovery to use <x/> element rather than query and made service response come in IQ result; fixed reference to JID spec; changed 'grant' to 'add' and 'revoke' to 'remove' for consistency in the item attributes; made several other small changes.
 
 
(psa)
 
(psa)
 
 
Version 0.5 (2002-09-19)
 
Version 0.5 (2002-09-19)
 
 
  
 
Changed the kick, ban, and voice protocols; added a few more configuration options; specified the restrictions for roomnicks; and added a stopgap service discovery protocol.
 
Changed the kick, ban, and voice protocols; added a few more configuration options; specified the restrictions for roomnicks; and added a stopgap service discovery protocol.
 
 
(psa)
 
(psa)
 
 
Version 0.4 (2002-09-18)
 
Version 0.4 (2002-09-18)
 
 
  
 
Changed all non-GC-1.0 use cases to jabber:gc:* namespaces or jabber:x:data; added use cases for ban list management and room moderation; added protocol for sending notice of admin and voice privileges in presence; cleaned up text and many examples.
 
Changed all non-GC-1.0 use cases to jabber:gc:* namespaces or jabber:x:data; added use cases for ban list management and room moderation; added protocol for sending notice of admin and voice privileges in presence; cleaned up text and many examples.
 
 
(psa)
 
(psa)
 
 
Version 0.3 (2002-09-17)
 
Version 0.3 (2002-09-17)
 
 
  
 
Changed admin use cases; cleaned up participant and owner use cases.
 
Changed admin use cases; cleaned up participant and owner use cases.
 
 
(psa)
 
(psa)
 
 
Version 0.2 (2002-09-12)
 
Version 0.2 (2002-09-12)
 
 
  
 
Broke content out into three actors (participant, owner, and admin) and added more detail to owner and admin use cases.
 
Broke content out into three actors (participant, owner, and admin) and added more detail to owner and admin use cases.
 
 
(psa)
 
(psa)
 
 
Version 0.1 (2002-09-09)
 
Version 0.1 (2002-09-09)
 
 
  
 
Initial version.
 
Initial version.
 
 
(psa)
 
(psa)
  
 
+
END
 
+
END"
+
 
+
'''文档信息'''
+
 
+
系列: [[XMPP扩展]]
+
 
+
编号: 0045
+
 
+
发行者: [XMPP文档列表/XMPP标准基金会]
+
 
+
状态: 草案
+
 
+
类型: 标准跟踪
+
 
+
版本: 1.24
+
 
+
最后更新日期: 2008-07-16
+
 
+
批准机构: [XMPP文档列表/XMPP理事会]
+
 
+
依赖于: [[XMPP Core]], [[XMPP IM]], XEP-0004, XEP-0030, XEP-0068, XEP-0082, XEP-0128
+
 
+
上文: 无
+
 
+
下文: 无
+
 
+
简称: muc
+
 
+
muc名字空间的XML方案: <http://www.xmpp.org/schemas/muc.xsd>
+
 
+
muc#admin名字空间的XML方案: <http://www.xmpp.org/schemas/muc-admin.xsd>
+
 
+
muc#owner名字空间的XML方案: <http://www.xmpp.org/schemas/muc-owner.xsd>
+
 
+
muc#unique名字空间的XML方案: <http://www.xmpp.org/schemas/muc-unique.xsd>
+
 
+
muc#user名字空间的XML方案: <http://www.xmpp.org/schemas/muc-user.xsd>
+
 
+
注册项: <http://www.xmpp.org/registrar/muc.html>
+
 
+
Wiki页: <http://wiki.jabber.org/index.php/Multi-User Chat (XEP-0045)>
+
 
+
'''作者信息'''
+
 
+
:'''Peter Saint-Andre'''
+
 
+
:Email: [mailto:stpeter@jabber.org stpeter@jabber.org]
+
 
+
:JabberID: [xmpp:stpeter@jabber.org stpeter@jabber.org]
+
 
+
'''法律通告'''
+
 
+
'''版权'''
+
 
+
XMPP扩展协议的版权(1999-2008)归XMPP标准化基金会(XSF)所有.
+
 
+
'''权限'''
+
 
+
特此授权,费用全免,对任何获得本协议副本的人,对使用本协议没有限制,包括不限制在软件程序中实现本协议,不限制在网络服务中布署本协议,不限制拷贝,修改,合并,发行,翻译,分发,转授,或销售本协议的副本,被允许使用本协议做了以上工作的人士,应接受前述的版权声明和本许可通知并且必须包含在所有的副本或实质性部分的规格中.除非单独的许可,被重新分发的修改工作,不得含有关于作者,标题,编号,或出版者的规格的误导性资料,并不得宣称修改工作是由本文的作者,作者所属的任何组织或项目,或XMPP标准基金会签注。
+
 
+
'''免责声明''''
+
 
+
注意:本协议是提供的“原样”的基础,没有担保或任何形式的条件,明示或暗示,包括,但不限于任何担保或关于名称,非侵权性,适销性或适合作某一特定目的的条件.在任何情况XMPP标准基金会或作者不对此协议承担任何责任索赔,损害赔偿,或其他责任,无论是在一项行动的合同,侵权,或否则,所产生的,运出,或在他涉嫌与规格或执行,部署或以其它方式使用本协议. ##
+
 
+
'''责任限制'''
+
 
+
在任何情况下以及没有任何法律规定时,不论是侵权行为(包括疏忽),合同或其它方面,除非根据适用法律的要求(如蓄意和有严重疏忽行为)或同意以书面形式,XMPP标准基金会或任何作者不对本协议承担所造成的损失,包括任何直接,间接,特殊,偶发,或相应的损害赔偿的任何字符利用所产生的或不能使用的规格(包括但不限于善意的损失,停止作业,电脑失灵或故障,或任何和所有其他商业损害或损失) ,即使XMPP标准基金会或作者已被告知此类损害的可能性。
+
 
+
'''知识产权的一致性'''
+
 
+
XMPP扩展协议完全遵守XSF的知识产权策略(可在<http://www.xmpp.org/extensions/ipr-policy.shtml>找到副本或写信给XSF, P.O. Box 1641, Denver, CO 80201 USA).
+
 
+
'''讨论地点'''
+
 
+
首选的讨论的地方是标准讨论邮件列表: <http://mail.jabber.org/mailman/listinfo/standards>.
+
 
+
勘误表发送到[mailto:editor@xmpp.org editor@xmpp.org]
+
 
+
'''XMPP 相关信息'''
+
 
+
XMPP 是由XSF(XMPP标准化基金会)按互联网标准程序贡献的,和 IETF的RFC 2026兼容的规范,包括 XMPP核心(RFC 3920)和 XMPP IM(RFC 3921).在本文中定义的任何协议,都是在互联网标准程序之外开发的,是扩展XMPP,而不是改变、发展和修改 XMPP本身.
+
 
+
'''一致性术语'''
+
 
+
本文中以下关键词的含义如 RFC 2119 所述: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".
+

2014年1月2日 (四) 06:01的最后版本


本文的英文原文来自XEP-0045

XEP-0045: 多用户聊天

摘要: 本文定义了一个XMPP协议扩展用于多用户文本会议.即多个XMPP可以在一个房间或频道互相交流信息, 类似互联网中继聊天系统(IRC).还有标准聊天室功能如聊天室的主题和邀请,本协议定义了一个强有力的房间控制模型,包括能够踢和禁止用户,任命主持人和管理员,要求会员或密码才能加入房间,等等。

作者: Peter Saint-Andre

XMPP扩展协议的版权(1999-2008)归XMPP标准化基金会(XSF)所有

版权: © 1999 - 2010 XMPP标准化基金会(XSF). 参见法律通告.

状态: 草案

类型: 标准跟踪

版本: 1.24

最后更新日期: 2008-07-16

注意: 这里定义的协议是XMPP标准化基金会的一个草案标准.对本协议的执行是被鼓励的,也适于部署到生产系统,但是在它成为最终标准之前可能还会有一些变动.

目录

绪论

传统上, 即时消息被视为由一对一的聊天构成而不是多对多聊天(即所谓"群聊"或"文本会议"). 群聊功能常见于一些系统如 Internet Relay Chat (IRC) 和 流行的IM服务所提供的聊天室功能. Jabber社区早在1999年开发和实施了一个基本的群聊协议. 这个 "groupchat 1.0" 协议为聊天室提供了一个最小功能集但是范围很有限. 本协议(多用户聊天或简称MUC)建立在向后兼容旧的"groupchat 1.0"协议的基础上但是提供高级功能如邀请, 房间主持和管理, 以及专门的房间类型.

范围

本文着重于和配置,参与以及管理一个独立的基于文本的会议室相关的通用需求. 这里所指出的需求是应用于单个房间级别的并且是"通用的", 某种意义上它们是在Jabber社区广泛讨论的或在现有的Jabber之外的基于文本的会议环境(例如, 定义在 RFC 1459 1中的Internet Relay Chat 和它的继承者: RFC 2810 2, RFC 2811 3, RFC 2812 4, RFC 2813 5)中已经存在的.

本文明确地不涉及以下需求:

  • 房间之间的关系(例如, 房间的层次结构)
  • 多用户聊天服务的管理(例如, 管理跨越整个服务级别的权限或注册一个全局可用的房间昵称);这些用例定义在Service Administration 6
  • 个别消息的主持
  • 通过房间发送的消息的加密
  • 高级特性, 如附加文件给一个房间, 集成白板, 以及和语音或视频聊天服务的接口
  • MUC部署和外来的聊天系统(例如, 和IRC网关或现有的其他IM系统)之间的交互
  • 在多个MUC部署之间进行镜像或复制

这一受限的范围并非蔑视这些都很有用的主题; 无论如何, 这意味着本文专注于讨论和介绍一个易于理解的协议能够被类似的Jabber客户端和组件开发者实现. 将来的协议当然可能涉及以上提到的这些主题.

需求

本文描述了由Jabber现有的多用户聊天服务提供的最小功能集. 为了向后兼容性起见, 本文使用原来的"groupchat 1.0"协议作为基本功能, 包括以下这些:

  • 每个房间被标识为 <room@service> (例如, <jdev@conference.jabber.org>), 这里 "room" 是房间的名称而 "service" 是多用户聊天服务运行所在的主机名.
  • 在一个房间里每个房客被标识为 <room@service/nick>, 这里 "nick" 是这个房客在这个房间里的昵称,定义于刚加入这个房间的时候,也可以在房客驻留改房间期间修改.
  • 一个用户通过发送出席信息给 <room@service/nick> 来加入一个房间(也就是成为房客).
  • 在多用户聊天房间里发送的消息使用特殊的类型"groupchat"并且被寻址于房间本身 (room@service), 然后反映给所有房客.
  • 通过发送出席信息给 <room@service/newnick>,一个房客可以改变他或她的房间昵称以及在房间中的可用性状态 .
  • 通过发送一个类型为"unavailable"的出席信息给当前的<room@service/nick>,一个房客可以退出房间.

本文追加的特性和功能包括以下这些:

  1. 本地会话日志(不需要房间内的机器人)
  2. 允许用户申请房间成员
  3. 在一个非匿名房间里, 允许房客可以察看(另)一个房客的全JID
  4. 在一个半匿名房间里, 允许主持人可以察看一个房客的全JID
  5. 允许只有主持人修改房间主题
  6. 允许主持人从房间里踢出与会者和游客
  7. 在一个被主持的房间里,主持人可以授予和撤销发言权(也就是说, 发言的权力), 并且管理发言权列表
  8. 允许管理员授权和取消主持人权力, 并且管理主持人列表
  9. 允许管理员在房间禁止用户, 并管理黑名单
  10. 允许管理员授予和撤销成员权力, 并且管理一个仅限成员的房间的成员列表
  11. 允许所有者限制房客的数量
  12. 允许所有者指定其他的所有者(们)
  13. 允许所有者授予或撤销管理特权, 并管理管理员列表
  14. 允许所有者销毁房间

另外, 本文提供了协议元素用于支持以下房间类型:

  1. 公共的或隐藏的
  2. 持久的或临时的
  3. 密码保护的或不安全的
  4. 仅限成员的或开放的
  5. 主持的或非主持的
  6. 非匿名的或半匿名的

为了实现这些需求, 本扩展协议需要满足 'http://jabber.org/protocol/muc' 名字空间(以及 在主名字空间URI加上 #owner, #admin, 和 #user 片断).

术语

通用术语

Affiliation(岗位) -- 一个长期存在的和房间之间的联系或连接; 可能的岗位有 "owner"(所有者), "admin"(管理者), "member"(成员), 以及 "outcast"(被排斥者) (当然也可能没有岗位); 岗位(affiliation)和角色(role)是有区别的. 一个岗位跨越了用户对一个房间的访问期间.

Ban(禁止) -- 从一个房间移除一个用户以使这个用户不能够再进入这个房间 (直到这个禁令被废除为止). 一个被禁止的用户的岗位(affiliation)为 "outcast"(被排斥者).

Bare JID(纯JID) -- 一个用户的标识符 <user@host>, 不同于任何已有会话或资源的上下文, 与之相对的是全JID和房间JID.

Full JID(全JID) -- 一个在线用户的标识符 <user@host/resource> , 不同于一个房间的上下文; 与之相对的是纯JID和房间JID.

GC -- 最小的 "groupchat 1.0" 协议[7], Jabber社区于1999年开发; MUC 向后兼容GC.

History(历史) -- 有限数量的消息节, 由当前讨论的上下文提供发送给一个新的房客.

Invitation(邀请) -- 从一个用户发出的特殊消息给另一个用户, 邀请对方加入房间.; the invitation can be sent directly (see Direct MUC Invitations [8]) or mediated through the room (as described under Inviting Another User to a Room).

IRC -- Internet Relay Chat.

Kick(踢人) -- 临时从一个房间移除一个与会者或游客; 这个用户任何时候都可以再次进入这个房间. 一个被踢的用户的角色是"none".

Logging(记录) -- 存储发生在一个房间的讨论内容用于公开发布到房间上下文之外的地方.

Member(成员) -- 一个用户在一个仅限会员的房间内处于"white list"(白名单)内,或已经注册到一个公开的房间. 一个成员的岗位是"member".

Moderator(主持人) -- 一个房间角色,通常和房间的管理有关但是这个角色可以被赋予非管理员; 可以踢人, 可以授予和撤销发言权, 等等. 一个主持人的角色是"moderator".

MUC -- 本文所定义的基于文本会议的多用户聊天协议.

Occupant(房客) -- 一个房间里的任何Jabber用户 (这是一个 "抽象类" 并且不对应任何特定的角色).

Occupant JID(房客JID) -- 在一个房间上下文中的一个房客,以 <room@service/nick> 来标识; 与之相对的是纯JID和全JID.

Outcast(被排斥者) -- 一个被某个房间禁止的用户. 一个被排斥者的岗位是 "outcast".

Participant(与会者) -- 一个没有管理权限的房客; 在一个被主持的房间里, 参与者更多地被定义为有发言权的 (与之相反的是游客). 一个与会者的角色是"participant".

Private Message(私有消息) -- 从一个房客直接发给另一个房间JID的消息(不是房间本身广播给所有房客的消息).

Role(角色) -- 在一个房间里的一个临时的地位或者权限级别, 对于这个房间中的用户的长期岗位来说是唯一的; 可能的角色有 "moderator"(主持人), "participant"(与会者), 和 "visitor"(游客) (也可能没有预定义的角色). 一个角色仅仅存在于一个房客访问一个房间的期间.

Room(房间) -- 一个虚拟的地方, Jabber用户象征性地加入它, 来和其他用户一起参与一个实时的基于文本的会议.

Room Administrator(房间管理员) -- 一个由房间所有者授权的用户, 可以执行管理功能, 如禁止用户等等; 无论如何, 不允许改变定义的房间特性. 一个管理员的岗位是"admin" .

Room ID(房间ID) -- 一个房间JID的节点标识符部分, 它可以是不透明的因而对人类用户没有什么含义(见 语法的商业规则Business Rules for syntax); 与之相对的是房间名.

Room JID(房间JID) -- 房间地址,如 <room@service>

Room Name(房间名) -- 一个用户友好的, 自然语言的房间名字, 由房间所有者配置并在服务查询中展示; 与之相对的是房间ID.

Room Nickname(房间昵称) -- 房间JID的资源标识符部分(见语法的商业规则); 这是一个房客在这个房间中所呈现的"友好的名字".

Room Owner(房间所有者) -- 建立某个房间的Jabber用户或一个被房间创建者或所有者指派拥有所有者权限(如果允许的话)的Jabber用户; 它被允许改变定义好的房间特性, 也可以执行全部的管理功能. 一个所有者的岗位为"owner".

Room Roster(房间名册) -- 一个房间中的所有房客在一个Jabber客户端的展现.

Server(服务器) -- 一个Jabber服务器,可以关联或不关联一个基于文本的会议服务.

Service(服务) -- 一个主机, 提供基于文本的会议的能力; 通常但不必须是一个Jabber服务器的子域(例如, conference.jabber.org).

Subject(主题) -- 一个房间的临时讨论标题.

Visit(访问) -- 一个房间的一个用户的"session"(会话), 当用户进入这个房间时开始(也就是说, 成为一个房客) , 结束于用户离开房间之时.

Visitor(游客) -- 在一个被主持的房间里的一个没有发言权的房客(相反则是一个与会者). 一个游客的角色是"visitor".

Voice(发言权) -- 在一个被主持的房间里, 发送消息给全部房客的权限.

房间类型

Hidden Room(隐藏房间) -- 一个无法被任何用户以普通方法如搜索和服务查询来发现的房间; 反义词: 公开(public)房间.

Members-Only Room(仅限会员的房间) -- 如果一个用户不在成员列表中则无法加入的一个房间; 反义词: 开放(open)房间.

Moderated Room(被主持的房间) -- 只有有"发言权"的用户才可以发送消息给所有房客的房间; 反义词: 非主持的(Unmoderated)房间.

Non-Anonymous Room(非匿名房间) -- 一个房客的全JID会暴露给所有其他房客的房间, 尽管房客可以选择任何期望的房间昵称; 相对的是半匿名(Semi-Anonymous)房间.

Open Room(开放房间) -- 任何人可以加入而不需要在成员列表中的房间; 反义词: 仅限会员的房间.

Password-Protected Room(密码保护房间) -- 一个用户必须提供正确密码才能加入的房间; 反义词: 非保密房间.

Persistent Room(持久房间) -- 如果最后一个房客退出也不会被销毁的房间; 反义词: 临时房间.

Public Room(公开房间) -- 用户可以通过普通方法如搜索和服务查询来发现的房间; 反义词: 隐藏房间.

Semi-Anonymous Room(半匿名房间) -- 一个房客的全JID只能被房间管理员发现的房间; 相对的是非匿名(Non-Anonymous)房间.

Temporary Room(临时房间) -- 如果最后一个房客退出就会被销毁的房间; 反义词: 持久房间.

Unmoderated Room(非主持的房间) -- 任何房客都被允许发送消息给所有房客的房间; 反义词: 被主持的房间.

Unsecured Room(非保密房间) -- 任何人不需要提供密码就可以进入的房间; 反义词: 密码保护房间.

登场人物

本文的大部分例子使用了莎士比亚的《麦克白》中第四幕第一场开头女巫在黑洞中开会的场景,在这里使用"coven@chat.shakespeare.lit"代表聊天室. 人物如下:

表1: 剧中人

Room Nickname Full JID Affiliation
firstwitch crone1@shakespeare.lit/desktop Owner
secondwitch wiccarocks@shakespeare.lit/laptop Admin
thirdwitch hag66@shakespeare.lit/pda None

角色(Roles),岗位(Affiliations)和权限(Privileges)

A user might be allowed to perform any number of actions in a room, from joining or sending a message to changing configuration options or destroying the room altogether. We call each permitted action a "privilege". There are two ways we might structure privileges:

1. Define each privilege atomically and explicitly define each user's particular privileges; this is flexible but can be confusing to manage.

2. Define bundles of privileges that are generally applicable and assign a user-friendly "shortcut" to each bundle (e.g., "moderator" or "admin").

MUC使用第2种方式。

有两个尺度我们可以用来衡量一个用户的连接或在一个房间的地位. 一个是用户和一个房间的长期的联系 -- 例如, 用户的状态是一个所有者或一个被排斥者. 另一个是当用户驻留于一个聊天室的时候的角色 -- 例如, 一个房客的地位是主持人,有权踢出游客和与会者. 这两个尺度各自都是唯一的, 因为一个岗位是跨越访问的, 而一个角色只存在于一次访问期间. 另外, 在角色和岗位之间没有一对一的对应关系; 例如, 某个不从属于某房间的人可能成为一个(临时的)主持人, 一个成员可能在一个被主持的房间中是一个与会者或游客者. 这些概念以下全面解释.

角色

以下是已定义的角色:

表2: 角色

名称 支持
主持人Moderator 必需的
无None 缺少角色
与会者Participant 必需的
游客Visitor 推荐的

角色是临时的,它不一定要在用户对房间的访问中持久化,它可以(MAY)在一个房客访问房间期间改变. 一个实现可以(MAY)在一次访问期间持久化角色并且应该(SHOULD)在被主持的房间这样做 (因为在游客和与会者之间,唯一性对一个被主持的房间是很关键的).

在角色和岗位之间没有一对一的映射(例如, 一个成员可以是一个与会者或一个游客).

在房间会话中,一个主持人是最有权力的房客, 它能在某种程度走上管理房间的其他房客的角色. 一个与会者的权力小于一个主持人, 尽管他或她有权发言. 在一个被主持的房间会话中游客是一个更受限制的角色, 因为访问者不允许发送消息给所有房客.

角色的授予,撤销, 和维护是基于房客的房间昵称或全JID,而不是纯JID. 和这些角色相关的权限,还有角色改变触发的动作, 定义在下文中.

所有在房间中生成或反射的出席信息中关于角色的信息必须(MUST)被发送,从而发送给房客们.

权限

大部分情况下, 角色存在于一个层次中. 例如, 一个与会者可以做任何游客能做的事, 而一个主持人可以做任何与会者能做的事. 每个角色拥有下一级角色所没有的权限; 这些权限定义于下表作为缺省值(一个实现可以(MAY)提供配置选项来重载这些缺省值).

表3: 和角色相关的权限

权限 游客 与会者 主持人
在房间中出席
接收消息
接收房客出席信息 是*
出席信息广播到房间 是*
改变可用性状态
改变房间昵称 是*
发送私人消息 是*
邀请其他用户 是* 是*
发送消息给所有人 否**
修改标题 否* 是*
踢出与会者和游客
授予发言权
撤销发言权 是***
  • 缺省; 设定配置时可以(MAY)修改这个权限.
    • 一个实现可以(MAY)在非主持的房间里缺省地授予发言权给游客.
      • 主持人不能(MUST NOT)从一个管理员或所有者收回发言权.

默认角色

服务必须(SHOULD)根据用户的岗位信息来设置房客在房间里的默认角色(没有与岗位(“outcast”)关联的默认角色,因为outcast用户不允许进入房间)。下表对与每个岗位关联的默认角色进行了总结。

表4: 基于岗位的默认角色

Room Type None Member Admin Owner
Moderated Visitor Participant Moderator Moderator
Unmoderated Participant Participant Moderator Moderator
Members-Only N/A * Participant Moderator Moderator
Open Participant Participant Moderator Moderator
  • Entry is not permitted.

变更角色

一个房客的角色变更方法是定义好的. 有时候房客自己的动作导致变更 (例如, 加入或退出房间), 反之有时候由主持人,管理员或所有者的动作导致变更. 如果一个房客的角色改变了, 一个 MUC 服务实现必须(MUST)变更这个房客的角色来反映这个变更并且传达这个变更给所有房客. 角色的变更和它们触发的动作定义于下表.

表4: 角色状态表

> 游客 与会者 主持人
-- 进入被主持的房间 进入非主持的房间 管理员或所有者进入房间
游客 退出房间或被主持人踢出房间 -- 主持人授予发言权 管理员或所有者授予主持人权限
与会者 退出房间或被主持人踢出房间 主持人撤销发言权 -- 管理员或所有者授予主持人权限
主持人 退出房间 管理员或所有者改变角色成为游客* 管理员或所有者改变角色成为与会者或撤销主持人权限* --
  • 一个主持人不能(MUST NOT)从一个岗位等于或高于主持人的房客那里收回主持人权限.

注意: 特定的角色一般暗含特定的权限. 例如, 一个管理员或所有者自动成为一个主持人, 所以如果一个房客被授予管理员地位那么这个房客事实上将被授予主持人权限; 类似的, 当一个房客成为一个被主持的房间的成员, 这个房客自动拥有一个与会者的角色. 无论如何, 失去管理员地位并不足以意味这个房客不再是主持人 (因为只要是与会者就可能成为一个主持人). 因此, 当一个房客被授予特定的岗位的时候所拥有的角色是固定的, 反之当一个房客失去一个特定的岗位时它的角色是不确定的并取决于(服务的)实现. 因为一个客户端无法预料是否在撤销某个岗位之后这个角色成为什么, 如果它不想同时移除管理员/所有者权限和主持人角色, 那么除了岗位变更之外它还必须特意请求角色变更.

岗位

已定义了以下岗位:

  1. 所有者
  2. 管理员
  3. 成员
  4. 被排斥者
  5. 无 (缺少岗位)

必须支持"所有者"这个岗位,推荐支持"管理员","成员","被排斥者"的岗位.("无"表示缺少岗位)

这些岗位是长时间的跨越一个用户对这个房间的访问期间的并且不受房间里事件的影响. 而且, 这些岗位和一个房客在房间中的角色之间没有一对一的映射关系. 岗位被授予,撤销, 和维护都是基于这个用户的纯 JID.

如果一个没有已定义的岗位的用户进入一个房间, 这个用户的岗位被定义为"无"; 无论如何, 这个岗位不能跨越(多次的)访问 (也就是说, 一个服务不会跨越访问维护一个 "无 列表").

"成员"岗位为房间所有者或管理员提供了一个方法来指定一个"白名单",其中的用户被允许加入一个仅供会员的房间. 当一个成员加入了一个仅供会员的房间, 他或她的岗位不会改变, 无论他或她的角色是什么. 成员岗位也为用户提供一个方法来高效地注册一个开放的房间并在某种方式意义上保持和那个房间的联系(例如可能在房间里预留那个用户的昵称).

一个被排斥者就是一个被从房间踢出来并且不允许进入那个房间的用户.

关于岗位的信息必须(MUST)由房间生成或反射到所有的出席信息节之中发送给房客们.

权限

大部分情况下, 岗位存在一个层次结构. 例如, 一个所有者可以做任何管理员能做的事情, 而一个管理员可以做任何成员能做的事情. 每个岗位拥有其下一级岗位所没有的权限; 这些权限定义在下表中.

表5: 和岗位相关的权限

权限 Outcast(被排斥者) None(无) Member(成员) Admin(管理员) Owner(所有者)
进入房间 是*
注册一个开放的房间 N/A N/A N/A
接收成员列表 否**
加入一个仅限会员的房间 是*
禁止成员并把用户的岗位删除
编辑成员列表
编辑主持人列表 是** 是**
编辑管理员列表
编辑所有者列表
变更房间定义
销毁房间
  • 作为缺省值, 一个无岗位的用户进入一个被主持的房间的角色是一个游客, 而进入一个开放的房间的角色是一个与会者. 一个成员进入一个房间的角色是与会者. 一个管理员或所有者进入房间的角色是一个主持人.
    • 一个管理员或所有者不能(MUST NOT)撤销另一个管理员或所有者的权限.

变更岗位

一个用户的岗位变更方法已经定义得很完善. 有时用户自己的动作导致这些变更(例如, 注册为一个房间的新成员), 反之有时候一个管理员或所有者的动作导致了这些变更. 如果一个用户的岗位改变了, 一个MUC服务实现必须(MUST)变更这个用户的岗位来反射这一变更并通知所有房客. 岗位变更和他们触发的动作定义在下表中.

表6: 岗位状态表

被排斥者(Outcast) 无(None) 成员(Member) 管理员(Admin) 所有者(Owner)
被排斥者(Outcast) -- 管理员或所有者移除屏蔽 管理员或所有者增加用户到成员列表 所有者增加用户到管理员列表 所有者增加用户到所有者列表
无(None) 管理员或所有者使用屏蔽 -- 管理员或所有者增加用户到成员列表, 或用户注册一个成员(如果允许) 所有者增加用户到管理员列表 所有者增加用户到所有者列表
成员(Member) 管理员或所有者使用屏蔽 管理员或所有者变更岗位为"none" -- 所有者增加用户到管理员列表 所有者增加用户到所有者列表
管理员(Admin) 所有者使用屏蔽 所有者变更岗位为"none" 所有者变更岗位为"member" -- 所有者增加用户到所有者列表
所有者(Owner) 所有者使用屏蔽 所有者变更岗位为"none" 所有者变更岗位为"member" 所有者变更岗位为"admin" --

实体用例

一个MUC实现必须(MUST)支持服务发现 7.

MUC的发现组件支持

一个Jabber实体可能希望发现是否一个服务实现了多用户聊天协议; 为了达到这个目的, 它发送一个服务发现信息("disco#info")查询给这组件的JID:

例子 1. 用户通过Disco查询聊天服务是否支持MUC

<iq from='hag66@shakespeare.lit/pda'
    id='disco1'
    to='macbeth.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

服务必须(MUST)返回它的的身份和它所支持的特性:

例子 2. 服务返回Disco Info结果

<iq from='macbeth.shakespeare.lit'
    id='disco1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        name='Macbeth Chat Service'
        type='text'/>
    <feature var='http://jabber.org/protocol/muc'/>
  </query>
</iq>

注意: 因为MUC是旧的"groupchat 1.0"协议的超集, 一个MUC服务不应该(SHOULD NOT)返回一个<feature var='gc-1.0'/>条目在一个disco#info结果中.

发现房间

发现服务条目("disco#items")协议使得一个用户可以向一个服务查询相关的条目列表, 在一个聊天服务中这包含这个服务所承载的所有特定房间的集合.

例子 3. 用户向聊天服务查询房间

<iq from='hag66@shakespeare.lit/pda'
    id='disco2'
    to='macbeth.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

服务应该(SHOULD)返回它承载的所有房间的列表.

例子 4. 服务返回Disco Item结果

<iq from='macbeth.shakespeare.lit'
    id='disco2'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='heath@macbeth.shakespeare.lit'
          name='A Lonely Heath'/>
    <item jid='darkcave@macbeth.shakespeare.lit'
          name='A Dark Cave'/>
    <item jid='forres@macbeth.shakespeare.lit'
          name='The Palace'/>
    <item jid='inverness@macbeth.shakespeare.lit'
          name='Macbeth&apos;s Castle'/>
  </query>
</iq>

如果全部房间的列表太大(详见XEP-0030), 服务可以(MAY)只返回部分的房间列表.如果这样做了, 它应该 SHOULD 包含一个 <set/> 元素 (定义在 Result Set Management 8) 以表明这个列表不是全部的结果集.

例子 5. 服务返回Disco Item结果的部分列表

<iq from='rooms.shakespeare.lit'
    id='disco-rsm-1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='alls-well-that-ends-well@rooms.shakespeare.lit'/>
    <item jid='as-you-like-it@rooms.shakespeare.lit'/>
    <item jid='cleopatra@rooms.shakespeare.lit'/>
    <item jid='comedy-of-errors@rooms.shakespeare.lit'/>
    <item jid='coriolanus@rooms.shakespeare.lit'/>
    <item jid='cymbeline@rooms.shakespeare.lit'/>
    <item jid='hamlet@rooms.shakespeare.lit'/>
    <item jid='henry-the-fourth-one@rooms.shakespeare.lit'/>
    <item jid='henry-the-fourth-two@rooms.shakespeare.lit'/>
    <item jid='henry-the-fifth@rooms.shakespeare.lit'/>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <first index='0'>alls-well-that-ends-well@rooms.shakespeare.lit</first>
      <last>henry-the-fifth@rooms.shakespeare.lit</last>
      <count>37</count>
    </set>
  </query>
</iq>

查询房间信息

使用 disco#info 协议, 一个用户也可以查询一个特定房间的详情. 为了在进入房间之间确定这个房间的隐私和安全配置用户应该(SHOULD)这样做(详见安全事项).

例子 6. 用户查询特定聊天室的信息

<iq from='hag66@shakespeare.lit/pda'
    id='disco3'
    to='darkcave@macbeth.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

房间必须(MUST)返回它的标识并且应该(SHOULD)返回它支持的特性:

例子 7. 房间返回查询信息结果

<iq from='darkcave@macbeth.shakespeare.lit'
    id='disco3'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        name='A Dark Cave'
        type='text'/>
    <feature var='http://jabber.org/protocol/muc'/>
    <feature var='muc_passwordprotected'/>
    <feature var='muc_hidden'/>
    <feature var='muc_temporary'/>
    <feature var='muc_open'/>
    <feature var='muc_unmoderated'/>
    <feature var='muc_nonanonymous'/>
  </query>
</iq>

注意: 因为 MUC 是旧的 "groupchat 1.0" 协议的超集, 一个 MUC 房间不应该(SHOULD NOT)在一个disco#info结果中返回<feature var='gc-1.0'/>条目. 房间应该(SHOULD)返回它支持的实质的有意义的特性, 例如密码保护和房间主持(这些特性被完整地列入了特性注册, 由XMPP Registrar维护; 也见于本文的XMPP注册 章节).

一个聊天室可以(MAY)使用服务查询扩展 9在它的disco#info应答中返回更详细的信息, 通过包含一个隐含的FORM_TYPE属性值"http://jabber.org/protocol/muc#roominfo"来标识. 这些信息可能包括关于一个房间的更详细的描述, 当前的房间标题, 以及这个房间当前的房客数量:

例子 8. 房间返回扩展的查询信息结果

<iq from='darkcave@macbeth.shakespeare.lit'
    id='disco3a'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        name='A Dark Cave'
        type='text'/>
    <feature var='http://jabber.org/protocol/muc'/>
    <feature var='muc_passwordprotected'/>
    <feature var='muc_hidden'/>
    <feature var='muc_temporary'/>
    <feature var='muc_open'/>
    <feature var='muc_unmoderated'/>
    <feature var='muc_nonanonymous'/>
    <x xmlns='jabber:x:data' type='result'>
      <field var='FORM_TYPE' type='hidden'>
        <value>http://jabber.org/protocol/muc#roominfo</value>
      </field>
      <field var='muc#roominfo_description' label='Description'>
        <value>The place for all good witches!</value>
      </field>
      <field var='muc#roominfo_changesubject' label='Whether Occupants May Change the Subject'>
        <value>true</value>
      </field>
      <field var='muc#roominfo_contactjid' label='Contact Addresses'>
        <value>crone1@shakespeare.lit</value>
      </field>
      <field var='muc#roominfo_subject' label='Subject'>
        <value>Spells</value>
      </field>
      <field var='muc#roominfo_occupants' label='Number of occupants'>
        <value>3</value>
      </field>
      <field var='muc#roominfo_lang' label='Language of discussion'>
        <value>en</value>
      </field>
      <field var='muc#roominfo_logs' label='URL for discussion logs'>
        <value>http://www.shakespeare.lit/chatlogs/darkcave/</value>
      </field>
      <field var='muc#roominfo_pubsub' label='Associated pubsub node'>
        <value>xmpp:pubsub.shakespeare.lit?node=chatrooms/darkcave</value>
      </field>
    </x>
  </query>
</iq>

某些扩展的房间信息可能是动态生成的(例如, 讨论记录的URL地址, 它可能取决于服务器那一层的配置); 反之另一些信息则可能基于房间那一层的配置,任何定义在muc#roomconfig FORM_TYPE 里的字段都可以用于扩展服务发现的字段(如上文所示的 muc#roomconfig_changesubject 字段).

注意: 前述 'http://jabber.org/protocol/muc#roominfo' FORM_TYPE的扩展服务发现字段将来还可以扩充(通过本文的字段标准化章节描述的机制).

查询房间条目

一个用户也可以(MAY)向一个特定的聊天室查询和它相关的条目:

例子 9. 用户查询和一个特定聊天室相关的条目

<iq from='hag66@shakespeare.lit/pda'
    id='disco4'
    to='darkcave@macbeth.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

一个实现可以(MAY)返回现有房客的列表(如果那信息是可公开的), 或不返回列表(如果那信息是私有的).

例子 10. 房间返回查询条目结果(条目是公开的)

<iq from='darkcave@macbeth.shakespeare.lit'
    id='disco4'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='darkcave@macbeth.shakespeare.lit/firstwitch'/>
    <item jid='darkcave@macbeth.shakespeare.lit/secondwitch'/>
  </query>
</iq>

注意: 这些 <item/> 元素由 disco#items 名字空间限定, 而不是 muc 名字空间; 这意味着他们不能拥有 'affiliation' 或 'role' 属性, 例如.

例子 11. 房间返回空的查询条目结果(条目是私有的)

<iq from='darkcave@macbeth.shakespeare.lit'
    id='disco4'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

查询一个房间的房客

如果一个非房客试图发送一个查询请求给一个<room@service/nick>类型的地址, 一个 MUC 服务应该(SHOULD)返回这个请求给这个实体并指明一个<bad-request/>错误条件. 如果一个房客发送这样一个请求, 服务可以(MAY)把它传递给指定的接收者; 详见本文的 实现注意事项章节.

发现客户端对MUC的支持

一个 Jabber 用户可能想发现这个用户的某个联系人是否支持多用户聊天协议. 这可以使用服务发现(协议)来完成.

例子 12. 用户查询联系人对于 MUC 的支持

<iq from='hag66@shakespeare.lit/pda'
    id='disco5'
    to='wiccarocks@shakespeare.lit/laptop'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

客户端应该(SHOULD)返回它的标识和它支持的特性:

例子 13. 联系人返回发现信息结果

<iq from='wiccarocks@shakespeare.lit/laptop'
    id='disco5'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='client'
        type='pc'/>
    ...
    <feature var='http://jabber.org/protocol/muc'/>
    ...
  </query>
</iq>

一个用户也可能查询一个联系人在哪个房间. 这可以通过特定服务发现节点 'http://jabber.org/protocol/muc#rooms' 查询联系人的全JID(<user@host/resource>)来完成 :

例子 14. 用户在当前房间查询联系人

<iq from='hag66@shakespeare.lit/pda'
    id='rooms1'
    to='wiccarocks@shakespeare.lit/laptop'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='http://jabber.org/protocol/muc#rooms'/>
</iq>

例子 15. 联系人返回房间查询结果

<iq from='wiccarocks@shakespeare.lit/laptop'
    id='rooms1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='http://jabber.org/protocol/muc#rooms'/>
    <item jid='darkcave@macbeth.shakespeare.lit'/>
    <item jid='characters@conference.shakespeare.lit'/>
  </query>
</iq>

可选的, 联系人可以(MAY)把它的房间昵称作为'name'属性的值返回:

    ...
    <item jid='darkcave@macbeth.shakespeare.lit'
          name='secondwitch'/>
    ...

房客用例

在一个多用户聊天环境中主要的行为者是房客, 它可以被认为存在于一个多用户聊天室"之内"并且参与那个房间的讨论 (在本协议中, 与会者和游客"仅仅"被认为是房客, 因为他们不拥有管理员权限). 为了更加清晰起见, 本文中的协议元素中涉及到驻留者的用例分为以下三类:

  1. 现存于 "groupchat 1.0" 协议的最小功能集
  2. 对于 "groupchat 1.0" 协议直接的应用, 如处理一些和新房间类型有关的错误
  3. 用来处理"groupchat 1.0"协议未涉及的功能的额外的协议元素(房间邀请, 房间密码, 和房间角色及岗位相关的扩展出席信息); 在'http://jabber.org/protocol/muc#user'名字空间

注意: 这里所有客户端生成的例子是从服务的角度来展示的, 所以所有由服务收到的节都包含一个'from'属性来表达发送者的全JID(这个from属性是由一个通用的Jabber路由或会话管理者加入的). 另外, 通常的表示请求已被完成的 IQ 结果节(如 RFC 3920 [10]中所要求的)未显示在这里.

进入一个房间

Groupchat 1.0协议

为了参加一个多用户聊天室的讨论, 一个Jabber用户必须(MUST)首先进入一个房间成为一个房客. 在旧的"groupchat 1.0"协议中, 这是通过发送出席信息<room@service/nick>来实现的, 这里"room"是房间的 ID, "service" 是聊天服务的主机名, "nick" 是这个用户在这房间里预期的昵称:

例子 16. Jabber用户进入一个房间(Groupchat 1.0)

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@macbeth.shakespeare.lit/thirdwitch'/>

在这个例子中, 一个全JID为"hag66@shakespeare.lit/pda"的用户请求用昵称"thirdwitch"进入位于"macbeth.shakespeare.lit"聊天服务的房间"darkcave".

如果用户未指定一个房间昵称, 服务应该(SHOULD)返回一个<jid-malformed/>错误:

例子 17. Jabber用户进入一个房间(Groupchat 1.0)

<presence
    from='darkcave@macbeth.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <error code='400' type='modify'>
    <jid-malformed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

基本MUC协议

兼容的多用户聊天服务必须(MUST)接受知道"groupchat 1.0" (GC)协议或multi-user chat (MUC)协议的任何客户端发出上述请求进入会议室; 无论如何, MUC 客户端应该(SHOULD)声明他们的有能力支持 MUC 协议, 方法是在出席信息节里面包含一个空的 <x/> 元素, 满足名字空间 'http://jabber.org/protocol/muc' (注意不需要 '#user' 部分):

例子 18. Jabber用户准备进入一个房间(Multi-User Chat)

<presence
    from="hag66@shakespeare.lit/pda"
    to='darkcave@macbeth.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

注意: 如果发生了一个和加入房间有关的错误, 服务应该 SHOULD 返回一个包含 MUC 子元素 (i.e., <x xmlns='http://jabber.org/protocol/muc'/>) 的 <presence/> 节,其 type 为 "error".

在尝试进入房间之间, 一个兼容MUC的客户端应该(SHOULD)首先查询它的保留的房间昵称 (如果有的话), 接下来的协议本文中的 发现保留的房间昵称 章节对此作了定义.

出席信息广播

如果服务能够添加用户到房间, 它必须(MUST)从所有现存的房客的房间JID发送出席信息给新的房客的全JID, 包括扩展的关于角色的出席信息, 一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'role'属性值设为"moderator", "participant", 或"visitor", 这个子元素的'affiliation'属性值设为"owner", "admin", "member", 或 "none" 中的一个:

例子 19. 服务从现有的房客发送出席信息给新的房客

<presence
    from='darkcave@macbeth.shakespeare.lit/firstwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner' role='moderator'/>
  </x>
</presence>
<presence
    from='darkcave@macbeth.shakespeare.lit/secondwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin' role='moderator'/>
  </x>
</presence>

这个示例中, 用户已从前一个例子进入房间, 有两个人已经在房间里: 一个是昵称为"firstwitch"的(房间拥有者), 另一个是昵称为"secondwitch"的(房间管理员).

服务也必须(MUST)从新进入的房客的房间JID向所有房客的全JID发送出席信息(含新房客):

例子 20. 服务发送新房客的出席信息给所有房客

<presence
    from='darkcave@macbeth.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
  </x>
</presence>
 
<presence
    from='darkcave@macbeth.shakespeare.lit/thirdwitch'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
  </x>
 
</presence>
 
<presence
    from='darkcave@macbeth.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='110'/>
  </x>
</presence>

在这个例子里, 初始的房间出席信息从新房客(thirdwitch)发送给所有房客, 包括这个新房客自己. 看看上面最后一个节, 由房间以房客的名义发送给用户自己的出席信息,应该 SHOULD 包含一个 110 状态码,这样用户就知道这个出席信息来自于作为房客的那个他自己.

服务可以 MAY 重写新房客的房间昵称 (例如, 如果房间昵称被锁定). 如果服务不接受新房客请求的房间昵称,而是分配一个新的房间昵称, 它必须 MUST 包含一个 "210" 状态码在发送给这个新房客的出席信息广播里.

例子 21. 服务发送新房客的出席信息给新房客

<presence
    from='darkcave@macbeth.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='110'/>
    <status code='210'/>
  </x>
</presence>

注意: 发送给新房客的出席信息的顺序是很重要的. 服务必须 MUST 首先发送现有房客的完整列表给这个新房客,然后只发送新房客自己的出席信息给新房客. 这有助于客户端知道什么时候它收到了完整的房间名册( "room roster").

发送出席信息广播之后(并且只在这之后), 服务可以发送讨论历史, 即时消息, 出席信息更新, 以及其他房间内的流量.

缺省角色

下表总结了初始缺省的角色,一个服务应该根据用户的岗位来设置它们(没有和 被排斥者 "outcast" 岗位相关的角色, 因为这些用户不允许进入房间).

表7: 基于岗位的初始角色

房间类型 成员 管理员 所有者
被主持的 游客 与会者 主持人 主持人
非主持的 与会者 与会者 主持人 主持人
仅限会员的 N/A * 与会者 主持人 主持人
开放的 与会者 与会者 主持人 主持人
  • 实体不被允许.

非匿名房间

如果房间是非匿名的, 服务必须 MUST 发送新房客的全JID给所有房客,使用满足 'http://jabber.org/protocol/muc#user' 名字空间的扩展出席信息,其中带有 <x/> 元素并包含一个 <item/> 子元素,其 'jid' 属性值为这个房客的全JID:

例子 22. 服务发送全JID给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

如果这个用户正在进入一个非匿名房间(即, 它如上所示,向所有房客通报每个房客的全JID), 服务应该 SHOULD 允许该用户加入本房间,但是必须 MUST 同时警告该用户本房间是非匿名的. 应该 SHOULD 在房间发送给这个新房客的初始出席信息种包含状态码 "100" 来实现这一点:

例子 23. 服务发送新房客的出席信息给新房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='100'/>
    <status code='110'/>
    <status code='210'/>
  </x>
</presence>

无论如何, 也可以 MAY 发送一个 "groupchat" 类型的消息给新房客来达到上述目的,这个消息应该包含一个 <x/> 子元素,并拥有 <status/> 子元素,并且其'code'属性值为"100":

例子 24. 服务警告新房客(该房间)非匿名

<message
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='groupchat'>
  <body>This room is not anonymous.</body>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <status code='100'/>
  </x>
</message>

附带的状态码协助客户端展示它们自己的通知消息 (例如, 和用户所在地方有关的信息).

半匿名房间

如果房间是半匿名的, 服务必须 MUST 如上文所述从新房客发送出席信息给所有房客, 但是必须 MUST 只在发给"主持人"的时候发送新房客的全JID,而非主持人则不发(全JID).

(注意: 所有随后的例子中,涉及的<item/>元素都带有'jid'属性, 即使这个信息在半匿名房间里不被发送给非主持人.)

密码保护房间

如果房间要求密码验证而用户不能提供(或密码错误), 服务必须 MUST 拒绝访问这个房间并且通知该用户它们是未被授权的; 具体方法是返回一个类型为"error"的出席信息节并标明 <not-authorized/> 错误:

例子 25. 服务拒绝访问,因为(用户)未提供密码

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='auth'>
    <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

密码应该 SHOULD 通过进入房间时发送的出席信息节来提供, 包含在满足 'http://jabber.org/protocol/muc' 名字空间的 <x/> 元素的<password/> 子元素里. 密码以明码方式发送; 目前不支持其它验证方法, 而且任何这类的验证或授权方法都将会定义在一个独立的协议里(参见本文的安全事项章节).

例子 26. 用户进入房间时提供密码

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <password>cauldronburn</password>
  </x>
</presence>

仅限会员房间

如果房间是仅限会员的,但用户不是(该房间的)成员, 服务必须 MUST 拒绝访问这个房间并通知用户它们不被允许进入房间; 具体方法是返回一个"error"类型的出席信息节,并包含一个 <registration-required/> 错误条件:

例子 27. 服务拒绝访问,因为用户不在成员列表中

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='auth'>
    <registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

被禁止的用户

如果用户已经被房间禁止(即, 其岗位为被排斥者 "outcast"), 服务必须 MUST 拒绝访问这个房间并通知用户他(她)被禁止了; 具体方法是返回一个出席信息节,类型为"error",标明 <forbidden/> 错误条件:

例子 28. 服务拒绝访问,因为用户被禁止了

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

昵称冲突

如果房间里已经有别的用户使用了准备进入房间的新用户预期的昵称(或如果这个昵称被保留给另一个成员列表里面的用户), 服务必须 MUST 拒绝访问这个房间并通知用户这个冲突; 具体方法是返回一个出席信息节,类型为"error",标明 <conflict/> 错误条件:

例子 29. 服务拒绝访问,因为昵称冲突

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

无论如何, 如果现有房客的纯 JID <localpart@domain.tld> 和准备进入房间的用户的纯 JID 相同, 那么服务应该 SHOULD 允许这个用户的进入, 所以这个用户就有两个(或更多) 房间内的会话 "sessions" 使用同一个房间昵称, 每一个对应一个资源. 如果一个服务允许相同纯JID可以同时存在多个房客并使用同一个房间的房间昵称, 它应该 SHOULD 路由房间内的消息给该用户的所有资源并允许用户的所有资源发送消息给房间; 视实现而定,服务来决定如何适当的处理从用户的资源发送的出席信息以及如何路由私有消息到所有或某个资源(基于出席信息优先级或其他机制).

如何确定昵称冲突取决于实现(例如, 该服务是否应用于一个特定的惯例, 一个 stringprep 规则如 Resourceprep 或 Nodeprep, 等等).

最大用户数

如果房间达到它的最大房客数量, 服务应该 SHOULD 拒绝访问这个房间并通知该用户这个限制; 方法是返回一个出席信息节,类型为"error",标明 <service-unavailable/> 错误条件:

例子 30. 服务通知用户该房间已达到房客数量极限

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='wait'>
    <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

另外, 房间可以踢出空闲用户("idle user")以腾出空间.

如果房间的房客数量已达到最大值但是一个房间管理员或所有者试图进入,该房间应该允许管理员或所有者加入,为了使得额外的房客达到一个合理的数目,该数量可以 MAY 做成可配置的。

锁住的房间

如果一个用户尝试进入一个房间而该房间是锁住的 "locked" (即, 在房间创建者提供初始的配置之前以及也就是在房间正式存在之前), 服务必须 MUST 拒绝进入并返回一个 <item-not-found/> 错误给该用户:

例子 31. 服务拒绝访问,因为房间不存在

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

不存在的房间

如果用户准备进入房间时,该房间已经不存在了, 服务应该 SHOULD 建立它; 无论如何, 这不是必需的, 因为一个实现或部署可以 MAY 选择限制建立房间的权限. 详见本文的新建房间章节.

房间记录

如果用户进入一个房间,该房间的讨论是被记录到一个公开的存档里面(经常可以通过HTTP访问的), 服务应该 SHOULD 允许该用户加入该房间但是必须 MUST 同时警告该用户讨论已被记录. 方法是应该 SHOULD 在房间发送给该新房客的初始出席信息中包含一个状态码 "170":

例子 32. 服务发送新房客的出席信息给新房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='100'/>
    <status code='110'/>
    <status code='170'/>
    <status code='210'/>
  </x>
</presence>

讨论历史

如上发送完初始出席信息之后, 一个房间可以 MAY 发送讨论历史给这个新房客. (在完成按照本文出席信息广播章节规定的发送房间出席信息之前,该房间不能 MUST NOT 发送任何讨论历史.) 是否这个历史要被发送, 以及这个历史里面包含多少条消息, 将由聊天服务实现或特定的部署来决定.

例子 33. 讨论历史的发送

<message
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='hecate@shakespeare.lit/broom'
    type='groupchat'>
  <body>Thrice the brinded cat hath mew'd.</body>
  <delay xmlns='urn:xmpp:delay'
     from='crone1@shakespeare.lit/desktop'
     stamp='2002-10-13T23:58:37Z'/>
</message>
 
<message
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='hecate@shakespeare.lit/broom'
    type='groupchat'>
  <body>Thrice and once the hedge-pig whined.</body>
  <delay xmlns='urn:xmpp:delay'
     from='wiccarocks@shakespeare.lit/laptop'
     stamp='2002-10-13T23:58:43Z'/>
</message>
 
<message
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hecate@shakespeare.lit/broom'
    type='groupchat'>
  <body>Harpier cries 'Tis time, 'tis time.</body>
  <delay xmlns='urn:xmpp:delay'
     from='hag66@shakespeare.lit/pda'
     stamp='2002-10-13T23:58:49Z'/>
</message>

讨论历史消息必须 MUST 标为Delayed Delivery 11信息,满足'urn:xmpp:delay' 名字空间,以表明它们是被延迟发送的并且标明它们最初发出的时间. (注意: 'urn:xmpp:delay' 名字空间定义在 XEP-0203 里面,取代了旧的定义在 Legacy Delayed Delivery 12 里的 'jabber:x:delay' 名字空间 ; XEP-0091状态更改为已过时之前, 实现应该 SHOULD 包含两种日期时间(datetime)格式.). 在非匿名房间里,'from'属性应该 SHOULD 是原始发送者的全JID, 但不能 MUST NOT 在半匿名房间里(在那里'from'属性应该 SHOULD 设置为房间本身的JID). 服务应该 SHOULD 在进入该房间之后,发送任何即时("live")消息之前,发送完所有讨论历史消息.

管理讨论历史

用户可能 MAY 希望管理进入房间时(由房间)提供的讨论历史(可能因为用户带宽比较低或正在使用迷你客户端). 他必须 MUST 在加入房间时发出的初始出席信息节里包含一个 <history/> 子元素. 这个元素有四个可用的属性:

表8: 历史管理属性

属性 数据类型 含义
maxchars int 限制历史中的字符总数为"X" (这里的字符数量是全部 XML 节的字符数, 不只是它们的 XML 字符数据).
maxstanzas int 限制历史中的消息总数为"X".
seconds int 仅发送最后 "X" 秒收到的消息.
since dateTime 仅发送从指定日期时间 datetime 之后收到的消息 (这个datatime必须 MUST 符合XMPP Date and Time Profiles 13 定义的DateTime 规则,).

服务必须 MUST 发送满足以上条件组合的最小数量的消息, 还要顾及服务级别和房间级别的缺省设置. 服务必须 MUST 只发送完整的消息节(即, 它不能 MUST not 按特定字符数把历史从字面上截断, 但是必须 MUST 发送最大数量的完整节,这使得字符数小于或等于 'maxchars' 属性的值). 如果客户端不希望收到历史, 它必须 MUST 把'maxchars' 属性值设为"0" (zero).

以下例子展示如何使用这个协议.

例子 34. 用户请求在历史中限制消息数量

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history maxstanzas='20'/>
  </x>
</presence>

例子 35. 用户请求最后三分钟的历史

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history seconds='180'/>
  </x>
</presence>

例子 36. 用户请求从Unix时代到现在的所有历史

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history since='1970-01-01T00:00:00Z'/>
  </x>
</presence>

服务绝对不应该 SHOULD NOT 返回从Unix时代开始到现在的所有消息, 而应该 SHOULD 基于服务或房间的缺省值返回适当的有限数量的历史给用户.

例子 37. 用户请求不发送历史

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history maxchars='0'/>
  </x>
</presence>

退出一个房间

为了退出一个多用户聊天房间, 一个房客发送一个类型为"unavailable"的出席信息节给正在使用这个房间的 <room@service/nick> .

例子 38. 房客退出一个房间

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'
    type='unavailable'/>

服务必须 MUST 接着从要离开的房客的房间JID发送"unavailable"类型的出席信息节给这个要离开的房客的全JID们以及留在房间的房客们:

例子 39. 服务发送和离开的房客有关的出席信息

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='none'/>
    <status code='110'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='none'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='wiccarocks@shakespeare.lit/laptop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='none'/>
  </x>
</presence>

由房间反射的类型为"unavailable"的出席信息节必须 MUST 包含扩展的关于角色和岗位的出席信息; 'role'属性值应该 SHOULD 被设为 "none" 以表示这个人不再是一个房客了.

房客可以 MAY 在出席信息节包含一个常规的 <status/> 信息; 这使房客能在必要的情况下提供一个自定的退出消息:

例子 40. 自定的退出消息

<presence
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/oldhag'
    type='unavailable'>
  <status>gone where the goblins go</status>
</presence>

常规的出席信息节生成规则定义在 XMPP IM 14, 所以如果用户发送一个一般的不可用出席信息节, 用户的服务器将广播那个节到 <room@service/nick> ,而该用户之前曾经发送过直接出席信息给这个<room@service/nick>.

有可能一个用户不能正常地通过直接发送不可用信息给一个房间来退出该房间. 如果该用户没有发送不可用出席信息就下线了, 用户的服务器负责代替该用户发送不可用出席信息 (依据 RFC 3921). 如果该用户的服务器下线或该用户的服务器和该用户连接的MUC服务失去连接(例如, 在联邦通信), 这个MUC服务负责监视它收到的错误信息节以确定该用户是否下线. 如果该MUC服务确定该用户已下线, 它必须 must 当成该用户自己发送了不可用信息一样地处理这个用户.

注意: 如果房间不是持久的并且该房客是最后一个退出的, 服务负责销毁这个房间.

更改昵称

多用户聊天室的一个常用功能是一个房客能修改自己在房间里的昵称. 在 MUC 里这需要发送一个更新出席信息给房间, 具体来说是在相同的房间里发送出席信息给一个新的房间JID (变更的只是这个房间JID的资源).

例子 41. 房客修改昵称

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/oldhag'/>

服务接着发送两个出席信息节给每个房客的全JID(包括修改自己昵称的房客本身), 一个是类型为"unavailable"的用于旧的昵称另一个指明新昵称可用了.

这个不可用出席信息必须 MUST 在一个满足'http://jabber.org/protocol/muc#user' 名字空间的 <x/> 子元素里面包含以下扩展的出席信息 :

  • 新昵称(在这个例子中, nick='oldhag')
  • 一个状态码 303

这使接受者能从旧昵称关联到新昵称.

例子 42. 服务更新昵称

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          nick='oldhag'
          role='participant'/>
    <status code='303'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='wiccarocks@shakespeare.lit/laptop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          nick='oldhag'
          role='participant'/>
    <status code='303'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          nick='oldhag'
          role='participant'/>
    <status code='303'/>
    <status code='110'/>
  </x>
</presence>
 
<presence
    from='darkcave@chat.shakespeare.lit/oldhag'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/oldhag'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/oldhag'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
    <status code='110'/>
  </x>
</presence>

如果该用户尝试修改他或她的房间昵称,但这个昵称已经被其他用户使用了 (或者这个昵称是被这房间的其他用户岗位保留的, 例如, 一个成员或者所有者), 服务必须 MUST 拒绝这次昵称修改并通知该用户这一冲突; 也就是返回一个类型为 "error" 的出席信息节指明 <conflict/> 错误条件:

例子 43. 服务拒绝昵称修改,因为昵称冲突

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

无论如何, 如果现有房客的纯JID <localpart@domain.tld> 和尝试变更昵称的房客的纯JID相同, 那么服务可以 MAY 允许昵称变更. 详见本文的昵称冲突章节.

如果该用户尝试变更自己的昵称但是房间昵称被锁定了("locked down"), 服务必须 MUST 拒绝这个昵称变更请求并返回一个"error"类型的出席信息节,指明一个 <not-acceptable/> 错误条件:

例子 44. 服务拒绝昵称变更,因为房间昵称被锁定

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

用户应该 SHOULD 接着发现它的保留昵称,如本文的 发现保留的房间昵称章节所述.

更改可用性状态

在一个多用户聊天系统里例如IRC, 一个常用的修改某人房间昵称的行为也意味着变更某人的可用性(例如, 变更某人的房间昵称为"thirdwitch|away"). 在Jabber里面, 可用性当然是通过出席信息 (中 <show/> 和 <status/> 元素)的变更来通知的, 这能提供重要的上下文给聊天室. 一个房客通过发送更新的出席信息给它自己的<room@service/nick>来改变他在房间内的可用性状态.

例子 45. 房客变更可用性状态

<presence
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/oldhag'>
  <show>xa</show>
  <status>gone where the goblins go</status>
</presence>

服务然后从该房客发送一个出席信息节来修改他或她的出席信息给每个房客的全JID, 包含扩展的出席信息,包括这个房客的角色和全JID(给那些有权知道的人):

例子 46. 服务传递修改的出席信息给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <show>xa</show>
  <status>gone where the goblins go</status>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit/laptop'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

邀请其他用户进入一个房间

直接邀请

一个办法是发送一个直接的邀请(而不是由房间本身来间接邀请),定义在Direct MUC Invitations 15. 直接发送邀请有助于适应被邀请者那一边的通信阻塞(对方可能拒绝和和不在好友名单中的实体通信).

间接邀请

邀请别的用户到一个房间成为房客是很有用的. 为了做到这一点, 一个 MUC 客户端必须 MUST 发送以下格式的 XML 给 <room@service> 本身 (原因(reason)是可选的 OPTIONAL 而消息(message)的类型必须 MUST 是显式或隐式的"normal"类型):

例子 47. 房客通过房间发送一个邀请

<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='hecate@shakespeare.lit'>
      <reason>
        Hey Hecate, this is the place for all good witches!
      </reason>
    </invite>
  </x>
</message>

<room@service> 本身必须 MUST 接着增加一个 'from' 地址到 <invite/> 元素,其值为邀请者的纯JID, 全JID, 或房间JID,并发送邀请给 'to' 地址所指明的被邀请者(为了旧的客户端,服务可以 MAY 包含一个消息主体"message body"解释这个邀请或包含一个原因"reason"(子元素); 另外, 房间应该 SHOULD 增加 password 如果该房间是密码保护的):

例子 48. 房间代表邀请者发送邀请给被邀请者

<message
    from='darkcave@chat.shakespeare.lit'
    to='hecate@shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='crone1@shakespeare.lit/desktop'>
      <reason>
        Hey Hecate, this is the place for all good witches!
      </reason>
    </invite>
    <password>cauldronburn</password>
  </x>
</message>

如果房间是仅限成员的, 服务可以 MAY 同时把这个被邀请者加入成员列表. (注意: 在仅限成员的房间里邀请的权力应该 SHOULD 由房间管理员限定; 如果一个没有权限的成员修改成员列表试图邀请别的用户, 服务应该 SHOULD 返回一个 <forbidden/> 错误给该房客; 详见本文的修改成员列表章节.)

如果邀请者提供了一个不存在的JID, 房间应该 SHOULD 返回一个 <item-not-found/> 错误给邀请者.

被邀请者可以 MAY 选择正式地拒绝 (反之则忽略) 邀请; 这是发送者希望看到的正式的通知. 为了拒绝这个邀请, 被邀请者必须 MUST 发送以下格式的消息给 <room@service> 本身:

例子 49. 被邀请者谢绝邀请

<message
    from='hecate@shakespeare.lit/broom'
    to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <decline to='crone1@shakespeare.lit'>
      <reason>
        Sorry, I'm too busy right now.
      </reason>
    </decline>
  </x>
</message>

例子 50. 房间通知邀请者邀请被拒绝了

<message
    from='darkcave@chat.shakespeare.lit'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <decline from='hecate@shakespeare.lit'>
      <reason>
        Sorry, I'm too busy right now.
      </reason>
    </decline>
  </x>
</message>

可能(有人)想知道为什么被邀请者不直接发送拒绝消息给访问者. 主要原因是特定的实现可能 MAY 选择让邀请基于房间JIDs而不是纯JIDs (所以, 例如, 一个房客可能从一个房间邀请某人到另一个房间而不需要知道这个人的纯JID). 因而服务必须 MUST 同时处理邀请和拒绝.

把一对一聊天转为多用户会议

有时候人们需要把一个一对一的聊天转成一个多用户的会议. 以下例子展示了这个流程.

首先, 两个用户开始一个一对一聊天.

例子 51. 一个一对一聊天

<message
    from='crone1@shakespeare.lit/desktop'
    to='wiccarocks@shakespeare.lit/laptop'
    type='chat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice the brinded cat hath mew'd.</body>
</message>
 
<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='crone1@shakespeare.lit/desktop'
    type='chat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice and once the hedge-pig whined.</body>
</message>

现在第一个用户决定加入第三个人到这个讨论, 所以她 (或, 更准确地说, 她的客户端) 做以下事情:

  1. 新建一个多用户聊天室
  2. 可选地发送一对一聊天的历史到房间
  3. 发送一个邀请给第二个人和第三个人, 包含一个 <continue/> 元素 (可选地包含一个 'thread' 属性).

注意: 新房间应该 SHOULD 是非匿名的, 可以 MAY 是一个即时房间(定义于本文的新建即时房间章节), 也可以 MAY 有一个从服务接收的唯一房间名(定义于本文的请求唯一的房间名章节.

注意: 如果这个一对一的聊天消息包含了一个 <thread/> 元素, 这个新建房间的人应该 SHOULD 在历史消息中包含这个 ThreadID, 在邀请中把这个 ThreadID 的值赋予 <continue/> 元素的 'thread' 属性, 并把这 ThreadID 包含在任何新的消息中发送到房间. ThreadIDs 的使用是推荐的 RECOMMENDED ,因为它帮助提供一对一聊天和多用户聊天的连续性.

例子 52. 继续讨论 I: 用户新建房间

<presence
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit/firstwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>
 
<presence
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner' role='moderator'/>
    <status code='110'/>
  </x>
</presence>

例子 53. 继续讨论 II: 所有者发送历史到房间

<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice the brinded cat hath mew'd.</body>
  <delay xmlns='urn:xmpp:delay'
     from='crone1@shakespeare.lit/desktop'
     stamp='2004-09-29T01:54:37Z'/>
</message>
 
<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice and once the hedge-pig whined.</body>
  <delay xmlns='urn:xmpp:delay'
     from='wiccarocks@shakespeare.lit/laptop'
     stamp='2004-09-29T01:55:21Z'/>
</message>

注意: 使用 Delayed Delivery 协议使房间创建者能够从他一对一聊天历史指明每个消息的日期时间 datetime (通过 'stamp' 属性), 以及每个消息的原始发送者的 JID (通过'from' 属性). 房间创建者应该 SHOULD 在邀请额外的用户到房间之前发送完整的一对一聊天历史, 并且也应该 SHOULD 把第二个人加入该房间之前和第一个人在一对一聊天界面中出现的任何消息当成历史来发送; 如果这个一对一历史特别的大, 发送的客户端可能希望在数秒内发送这个历史而不是一次性发送所有历史(以to 避免触发频率限制). 服务不应该 SHOULD NOT 在从房间所有者接收的历史消息之前添加它自己的延迟元素"delay elements" (见本文的讨论历史章节) .

例子 54. 继续讨论 III: 所有者发送邀请(们), 包含 Continue 标志

<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='wiccarocks@shakespeare.lit/laptop'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
    <invite to='hag66@shakespeare.lit'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
  </x>
</message>

注意: 当邀请者的客户端一知道和它一对一聊天的那个人的全JID之后, 它就应该 SHOULD 在邀请中包含这个全JID (而不是纯JID).

邀请被递送到被邀请者:

例子 55. 邀请被递送

<message
    from='darkcave@chat.shakespeare.lit'>
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='crone1@shakespeare.lit'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
  </x>
</message>
 
<message
    from='darkcave@chat.shakespeare.lit'>
    to='hag66@shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='crone1@shakespeare.lit'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
  </x>
</message>

当客户端被 <wiccarocks@shakespeare.lit/laptop> 用来接收邀请, 它应该 SHOULD 自动加入或提示用户是否加入 (取决于用户的选项配置) 并且随后无缝地把现有的一对一聊天窗口转到一个多用户会议的窗口:

例子 56. 被邀请者接受邀请, 加入房间, 并接收出席信息和历史

<presence
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/secondwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>
 
<presence
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner' role='moderator'/>
  </x>
</presence>
 
<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
  </x>
</presence>
 
<message
    from='darkcave@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice the brinded cat hath mew'd.</body>
  <delay xmlns='urn:xmpp:delay'
     from='crone1@shakespeare.lit/desktop'
     stamp='2004-09-29T01:54:37Z'/>
</message>
 
<message
    from='darkcave@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice and once the hedge-pig whined.</body>
  <delay xmlns='urn:xmpp:delay'
     from='wiccarocks@shakespeare.lit/laptop'
     stamp='2004-09-29T01:55:21Z'/>
</message>

注意: 事实上,这些消息从 <room@service> 本身而不是 <room@service/nick> 发出,告诉这些接收的客户端这些消息是优先的聊天历史, 因为任何来自房客的消息的 'from' 地址应该等于发送者的房间JID.

房客修改房间标题

如果房间配置允许, 一个房客可以 MAY 被允许修改一个房间的主题. 详见本文的修改房间主题章节.

发送私有消息

因为每个房客有一个唯一的房间JID, 一个房客可以 MAY 发送一个私有消息 "private message" 给选定的房客,即通过服务发送一个消息给那房客的房间JID. 这个消息类型应该 SHOULD 是 "chat" 并且不能 MUST NOT 是 "groupchat", 但是可以 MAY 不表明 (即, 一个常规"normal"消息). 这个权力应该 SHOULD 被任何房客允许 (甚至在一个被主持的房间里的游客).

例子 57. 房客发送私有消息

<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/firstwitch'
    type='chat'>
  <body>I'll give thee a wind.</body>
</message>

服务负责把'from'地址改为发送者的房间JID并递送这个消息到预期的接收者的全JID.

例子 58. 接收者接收私有消息

<message
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'
    type='chat'>
  <body>I'll give thee a wind.</body>
</message>

如果发送者尝试发送一个类型为 "groupchat" 的私有消息给特定的房客, 服务必须 MUST 拒绝递送这个消息 (因为接收者的客户端期望的房间内的消息类型为"groupchat") 并且返回一个 <bad-request/> 错误给发送者:

例子 59. 房客尝试发送类型为"Groupchat"的私有消息给特定的房客

<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/firstwitch'
    type='groupchat'>
  <body>I'll give thee a wind.</body>
</message>
 
<message
    from='darkcave@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    type='error'>
  <body>I'll give thee a wind.</body>
  <error type='modify'>
    <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>

如果发送者尝试发送一个私有消息给一个不存在的房间JID, 服务必须 MUST 返回一个 <item-not-found/> 错误给发送者.

如果发送者不是预期的接收者正在访问的那个房间的房客, 服务必须 MUST 返回一个 <not-acceptable/> 错误给发送者.

发送消息给所有房客

房客发送一个消息给所有房间内的房客的方法,是发送一个类型为 "groupchat" 的消息到 <room@service> 本身 (服务可以 MAY 忽略或拒绝类型不是 "groupchat" 的消息). 在一个被主持的房间, 这个权力限于角色为与会者或更高的房客拥有.

例子 60. 房客发送一个消息给所有房客

<message
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit'
    type='groupchat'>
  <body>Harpier cries: 'tis time, 'tis time.</body>
</message>

如果发送者在这个房间有发言权 (在被主持的房间里缺省是这样期望), 服务必须 MUST 修改发送者的 'from' 属性成为房间JID并反射这个消息到每个房客的全JID.

例子 61. 服务反射消息给所有房客

<message
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'
    type='groupchat'>
  <body>Harpier cries: 'tis time, 'tis time.</body>
</message>
<message
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='wiccarocks@shakespeare.lit/laptop'
    type='groupchat'>
  <body>Harpier cries: 'tis time, 'tis time.</body>
</message>
<message
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'
    type='groupchat'>
  <body>Harpier cries: 'tis time, 'tis time.</body>
</message>

如果发送者是个游客 即, 在一个被主持的房间里没有发言权), 服务可以 MAY 返回一个 <forbidden/> 错误给发送者并且不能 MUST NOT 反射这个消息给所有房客. 如果发送者不是该房间的房客, 服务应该 SHOULD 返回一个 <not-acceptable/> 错误给发送者并且不应该 SHOULD NOT 反射这个消息给所有房客; 这个规则的唯一的例外是,一个实现可以 MAY 允许用户们拥有特定的权限 (例如, 一个房间拥有者, 房间管理员, 或服务级别的管理员) 发送消息到这个房间,即使那些用户不是房客.

注册到房间

一个实现可以 MAY 允许一个无岗位的用户(在一个被主持的房间里, 通常是一个与会者) 注册一个房间从而成为该房间的一个成员 (反之, 一个实现也可以 MAY 限制这个权力并且只允许房间管理员添加新的成员). 特别是, 不在成员列表的人是无法加入一个仅限会员的房间的, 所以为了加入这样一个房间,实体需要申请会籍.

如果允许, 这个功能应该 SHOULD 这样被实现。让用户使用 'jabber:iq:register' 名字空间带内注册 16提出注册申请给房间,:

例子 62. 用户提出注册申请

<iq from='hag66@shakespeare.lit/pda'
    id='reg1'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='jabber:iq:register'/>
</iq>

如果用户提出的注册申请不被允许注册该房间 (例如, 因为那个权限被限制了), 该房间必须 MUST 返回一个 <not-allowed/> 错误给该用户. 如果该用户已经注册过了, 房间必须 MUST 返回一个类型为"result"的IQ节并包含一个空的<register/>元素(定义于XEP-0077). 如果该房间不存在, 服务必须 MUST 返回一个 <item-not-found/> 错误.

否则, 房间必须 MUST 接着返回一个数据表单"Data Form"给该用户 (定义于数据表单 17). 注册需要的信息可以 MAY 根据实现和部署的不同而不同并且没有完全定义在本文中 (例如, 本文根据 'http://jabber.org/protocol/muc#register' 名字空间采用的注册字段 FORM_TYPE 可能将来会根据字段标准化章节里描述的得到补充,). 以下是一个典型的例子:

例子 63. 服务返回注册表单

<iq from='darkcave@chat.shakespeare.lit'
    id='reg1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='jabber:iq:register'>
    <instructions>
      To register on the web, visit http://shakespeare.lit/
    </instructions>
    <x xmlns='jabber:x:data' type='form'>
      <title>Dark Cave Registration</title>
      <instructions>
        Please provide the following information
        to register with this room.
      </instructions>
      <field
          type='hidden'
          var='FORM_TYPE'>
        <value>http://jabber.org/protocol/muc#register</value>
      </field>
      <field
          label='Given Name'
          type='text-single'
          var='muc#register_first'>
        <required/>
      </field>
      <field
          label='Family Name'
          type='text-single'
          var='muc#register_last'>
        <required/>
      </field>
      <field
          label='Desired Nickname'
          type='text-single'
          var='muc#register_roomnick'>
        <required/>
      </field>
      <field
          label='Your URL'
          type='text-single'
          var='muc#register_url'/>
      <field
          label='Email Address'
          type='text-single'
          var='muc#register_email'/>
      <field
          label='FAQ Entry'
          type='text-multi'
          var='muc#register_faqentry'/>
    </x>
  </query>
</iq>

用户应该 SHOULD 接着提交这个表单:

例子 64. 用户提交注册表单

<iq from='hag66@shakespeare.lit/pda'
    id='reg2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='jabber:iq:register'>
    <x xmlns='jabber:x:data' type='submit'>
      <field var='FORM_TYPE'>
        <value>http://jabber.org/protocol/muc#register</value>
      </field>
      <field var='muc#register_first'>
        <value>Brunhilde</value>
      </field>
      <field var='muc#register_last'>
        <value>Entwhistle-Throckmorton</value>
      </field>
      <field var='muc#register_roomnick'>
        <value>thirdwitch</value>
      </field>
      <field var='muc#register_url'>
        <value>http://witchesonline/~hag66/</value>
      </field>
      <field var='muc#register_email'>
        <value>hag66@witchesonline</value>
      </field>
      <field var='muc#register_faqentry'>
        <value>Just another witch.</value>
      </field>
    </x>
  </query>
</iq>

如果期望的房间昵称已经被那个房间保留, 房间必须 MUST 返回一个 <conflict/> 错误给该用户:

例子 65. 房间返回冲突错误给用户

<iq from='darkcave@chat.shakespeare.lit'
    id='reg2'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

如果该房间或服务不支持注册, 它必须 MUST 返回一个 <service-unavailable/> 错误给用户:

例子 66. 房间返回服务不可用错误给用户

<iq from='darkcave@chat.shakespeare.lit'
    id='reg2'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <error type='cancel'>
    <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

如果用户没有提交合法的数据表格, 房间必须 MUST 返回一个 <bad-request/> 错误给用户:

例子 67. 房间返回"服务错误的请求"错误给用户

<iq from='darkcave@chat.shakespeare.lit'
    id='reg2'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <error type='modify'>
    <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

否则, 该房间必须 MUST 通知用户注册请求被成功地接收到了:

例子 68. 房间通知用户注册请求已经被处理了

<iq from='darkcave@chat.shakespeare.lit'
    id='reg2'
    to='hag66@shakespeare.lit/pda'
    type='result'/>

用户提交表单之后, 服务可以 MAY 向一个房间 管理员/所有者 请求批准该申请 (参见本文的批准注册申请章节) 或也可以 MAY 立刻把该用户的岗位从"none"变更为"member"来添加此用户到成员列表. 如果服务变更了该用户的岗位并且该用户在房间里, 它必须 MUST 从这个用户发送更新的出席信息给所有房客, 声明岗位的变更,这个更新的出席信息应包含一个满足 'http://jabber.org/protocol/muc#user' 名字空间 <x/> 元素并包含一个'affiliation' 属性值设为"member"的 <item/> 子元素.

例子 69. 服务发送成员变更通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

如果一个用户已经注册到一个房间, 该房间可以 MAY 选择限制这个用户在那个房间仅能使用已注册的昵称. 如果它这样做, 当用户尝试以不同于该用户之前已注册的房间昵称来加入该房间 (这使房间锁定"lock down"房间昵称以保证房客身份的一致性)的时候,它应该 SHOULD 返回一个 <not-acceptable/> 错误给该用户.

获取成员列表

根据房间配置如果允许的话, 一个房客可以 MAY 被允许接收房间成员的列表. 详见本文的修改成员列表章节.

发现保留的房间昵称

一个用户可以 MAY 有一个保留的房间昵称, 例如通过显式的房间注册, 数据库集成, 或昵称锁定 "lockdown". 用户应该 SHOULD 在尝试进入该房间之前发现自己的保留昵称. 这可以通过发送一个发现服务信息请求并指定一个服务发现节点"x-roomuser-item"给房间JID来做到.

例子 70. 用户请求保留的昵称

<iq from='hag66@shakespeare.lit/pda'
    id='getnick1'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='x-roomuser-item'/>
</iq>

对一个多用户聊天服务来说,对上述的服务发现节点的支持是可选的 OPTIONAL . 如果房间或服务不支持上述的服务发现节点, 它必须 MUST 返回一个 <feature-not-implemented/> 错误给用户. 如果它支持这个特性并且该用户有一个已注册的昵称, 它必须 MUST 返回这个昵称给这个用户,方法是发送一个服务发现的<identity/>元素,其'name'属性值为这个昵称 (此处 category/type 应该 SHOULD 是 "conference/text"):

例子 71. 房间返回昵称

<iq from='darkcave@chat.shakespeare.lit'
    id='getnick1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='x-roomuser-item'>
    <identity
        category='conference'
        name='thirdwitch'
        type='text'/>
  </query>
</iq>

如果该用户没有已注册的昵称, 房间必须 MUST 返回一个空的服务发现 <query/> 元素 (根据 XEP-0030).

即使一个用户已经注册了一个房间昵称, 服务应该 SHOULD 允许该用户在加入该房间时指定一个不同的昵称 (例如, 为了从不同的客户端资源加入), 尽管该服务可以 MAY 选择通过一个 <not-acceptable/> 错误来锁定 "lock down" 昵称并拒绝该用户 . 如果该用户的客户端在加入该房间之后发送上述请求,服务不能 MUST NOT 返回一个错误给该用户, 而应该 SHOULD 返回上文所述.

如果另一个用户尝试以第一个用户保留的房间昵称来加入房间, 服务必须 MUST 拒绝第二个用户并返回一个前文所述的 <conflict/> 错误.

申请发言权

在一个被主持的房间里游客是不能发言的 (即, 发送一个消息给所有房客). 为了申请发言权, 一个游客应该 SHOULD 发送包含一个数据表格的 <message/> 节给房间本身, 这个数据表格仅仅是一个 'muc#role' 字段,值为 "participant".

例子 72. 房客申请发言权

<message from='hag66@shakespeare.lit/pda'
         to='darkcave@chat.shakespeare.lit'>
  <x xmlns='jabber:x:data' type='submit'>
    <field var='FORM_TYPE'>
      <value>http://jabber.org/protocol/muc#request</value>
    </field>
    <field var='muc#role'
           type='text-single'
           label='Requested role'>
      <value>participant</value>
    </field>
  </x>
</message>

服务接着应该 SHOULD 转发这个请求给房间主持人(们) ,定义于本文的批准发言权申请.

主持人用例

一个主持人有权在房间里执行特定的动作 (例如, 变更某些房客的角色) 但无权变更岗位的持久信息 (它只能被管理员或所有者) 或定义关于这个房间的信息. 具体哪些动作可由主持人执行,取决于配置. 无论如何, 对于 MUC 框架来说, 主持人被规定有权执行以下动作:

  1. 在一个半匿名的房间里发现一个房客的全JID(如上文所述缺省会发生)
  2. 修改主题
  3. 从该房间踢出一个与会者或游客
  4. 在一个被主持的房间里授予或撤销发言权
  5. 在一个被主持的房间里修改拥有发言权的房客列表

这些特性将通过一个基于 <iq/> 元素的 请求/应答 交换来实现,这个IQ元素包含一个满足 'http://jabber.org/protocol/muc#admin' 名字空间的子元素. 以下例子展示这个协议和实现如何互动达到期望的功能. (以下除非显式地提及, 任何接下来的管理请求必须 MUST 被拒绝,如果该请求的'from'地址 <user@host> 和主持人的纯JID不符的话; 在这种情况下, 服务必须 MUST 返回一个 <forbidden/> 错误.)

修改房间主题

多用户聊天室的一个常用特性是变更房间主题的能力. 缺省地, 一个房间里只有角色为主持人 "moderator" 的用户应该 SHOULD 被允许变更主题 (尽管这应该 SHOULD 是可配置的, 结果是如果需要的话,仅仅与会者或甚至游客都被允许修改主题). 主题变更是通过发送一个类型为 "groupchat" 的消息给 <room@service>来实现的, 在这里 <message/> 必须 MUST 包含一个 <subject/> 元素以指定新的主题,但不应该 SHOULD NOT 包含其他元素 (例如, 不应该有 <body/> 元素或 <thread/> 元素).

例子 73. 主持人变更主题

<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit'
    type='groupchat'>
  <subject>Fire Burn and Cauldron Bubble!</subject>
</message>

如果一个 MUC 服务接收到这样一个消息, 它必须 MUST 以发送这个变更主题消息的那个用户的房间JID作为'from'地址来反射这个消息给所有其他房客:

例子 74. 服务通知所有房客主题变更

<message
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'
    type='groupchat'>
  <subject>Fire Burn and Cauldron Bubble!</subject>
</message>
 
[ ... ]

另外, 当一个新的房客加入房间时,该房间应该 SHOULD 在被发送的讨论历史中包含最后的主题变更.

一个接收到这类信息的 MUC 客户端可以 MAY 选择显示一个房间内的消息, 如下:

例子 75. 客户端显式房间主题变更消息

* secondwitch has changed the subject to: Fire Burn and Cauldron Bubble!

如果一些没有适当权限的人尝试变更房间主题, 服务必须 MUST 返回一个 "error" 类型的消息指明一个 <forbidden/> 错误条件:

例子 76. 服务返回未被授权变更主题的错误

<message
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <subject>Fire Burn and Cauldron Bubble!</subject>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>

为了移除现有的主题而不是提供一个新主题 (即, 设置主题为空), 客户端应该发送一个空的 <subject/> 元素 (即, "<subject/>" 或 "<subject></subject>").

例子 77. 主持人设置空的主题

<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit'
    type='groupchat'>
  <subject></subject>
</message>

踢出房客

主持人有权从一个房间踢出特定种类的房客 (哪些房客是可被踢的 "kickable" 取决于服务规定, 房间配置, 以及主持人的岗位 -- 见下文). 踢人通常基于房客的房间昵称来执行 (尽管可以 MAY 基于全JID) 并且完全是通过把与会者或游客的角色设为 "none" 来实现的.

例子 78. 主持人踢出房客

<iq from='fluellen@shakespeare.lit/pda'
    id='kick1'
    to='harfleur@henryv.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='pistol' role='none'>
      <reason>Avaunt, you cullion!</reason>
    </item>
  </query>
</iq>

服务必须 MUST 移除被踢的用户,通过发送一个类型为 "unavailable" 的出席信息节给每个被踢的房客, 这个出席信息应在其扩展出席信息中包含状态码 307 , 或(可选地)包含 reason 子元素(如果提供了) 以及踢人的执行者的纯JID.

例子 79. 服务移除被踢的房客

<presence
    from='harfleur@henryv.shakespeare.lit/pistol'
    to='pistol@shakespeare.lit/harfleur'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='none'>
      <actor jid='fluellen@shakespeare.lit'/>
      <reason>Avaunt, you cullion!</reason>
    </item>
    <status code='307'/>
  </x>
</presence>

包含状态码可使客户端能够提交他们自己的通知消息 (例如, 适当的用户位置的信息). 可选的包含原因 reason 元素以及执行者 actor 使得被踢的用户能理解为什么他或她被踢了, 以及被踢的用户可以找谁去理论. 18

移除被踢的房客(们)之后, 服务必须 MUST 接着通知主持人成功了:

例子 80. 服务通知主持人成功了

<iq from='harfleur@henryv.shakespeare.lit'
    id='kick1'
    to='fluellen@shakespeare.lit/pda'
    type='result'/>

通知主持人之后, 服务必须 MUST 接着通知剩余的房客那个被踢的房客已经不在房间里了,即从被踢者的房间昵称(<room@service/nick>)发送 "unavailable" 类型的出席信息节给所有剩余的房客 (就像房客自愿退出房间时所做的一样), 包含状态码 status 以及可选的原因 reason 和执行者 actor.

例子 81. 服务通知剩余的房客

<presence
    from='harfleur@henryv.shakespeare.lit/pistol'
    to='gower@shakespeare.lit/cell'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='none'/>
    <status code='307'/>
  </x>
</presence>
 
[ ... ]

一个用户不能被比自己岗位低的主持人踢出. 所以, 如果一个身为与会者的主持人尝试踢出一个管理员,或一个身为与会者的主持人或管理员尝试踢出一个所有者, 服务必须 MUST 拒绝这个请求并返回一个 <not-allowed/> 错误给发送者:

例子 82. 服务对于尝试踢出更高岗位的用户返回错误

<iq from='darkcave@chat.shakespeare.lit'
    id='kicktest'
    to='wiccarocks@shakespeare.lit/laptop'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='firstwitch' role='none'>
      <reason>Be gone!</reason>
    </item>
  </query>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

如果一个主持人尝试踢出他自己, 服务可以 MAY 拒绝这个请求并返回一个 <conflict/> 错误给发送者. (尽管这个踢出自己的行为可能看起来怪异, 它在 IRC 里很常见,用于在房间里为某人的行为道歉.)

授予游客发言权

在一个被主持的房间里, 主持人可能希望管理房间内谁有水没有发言权 "voice" (即, 发送消息给所有房客的能力). 发言权的授予是基于游客的房间昵称来的, 服务将从内部把这个房间昵称转成游客的全JID. 主持人通过把游客的角色变更为与会者 "participant"来给一个游客授予权限.

例子 83. 主持人授予权限给一个游客

<iq from='crone1@shakespeare.lit/desktop'
    id='voice1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='participant'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL:

例子 84. 主持人授予权限给一个游客(包含一个原因 Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='voice1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='participant'>
      <reason>A worthy witch indeed!</reason>
    </item>
  </query>
</iq>

服务必须 MUST 接着通知主持人成功了:

例子 85. 服务通知主持人成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='voice1'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 接着以这个人的<room@service/nick>发送更新的出席信息给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'role'属性值为"participant",指明添加了发言权.

例子 86. 服务发送发言权通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          nick='thirdwitch'
          role='participant'>
      <reason>A worthy witch indeed!</reason>
    </item>
  </x>
</presence>
 
[ ... ]

撤销与会者发言权

在一个被主持的房间里, 主持人可能希望撤销一个与会者发言的权力,主持人通过把与会者的角色变更为游客 "visitor"来撤销一个游客的发言权:

例子 87. 主持人撤销一个与会者的发言权

<iq from='crone1@shakespeare.lit/desktop'
    id='voice2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='visitor'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL:

例子 88. 主持人撤销一个与会者的发言权(包含一个原因Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='voice2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='visitor'>
      <reason>Not so worthy after all!</reason>
    </item>
  </query>
</iq>

服务必须 MUST 接着通知主持人成功了:

例子 89. 服务通知主持人成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='voice2'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 接着以这个人的<room@service/nick>发送更新的出席信息给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'role'属性值为"visitor",指明移除了发言权.

例子 90. 服务通知失去发言权

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='visitor'/>
  </x>
</presence>
 
[ ... ]

一个主持人不能 MUST NOT 从一个岗位等于或高于主持人岗位的用户撤销发言权. 另外, 服务不能 MUST NOT 允许一个管理员或所有者的发言权被任何人撤销. 如果一个主持人尝试撤销这些人的发言权, 服务必须 MUST 拒绝这个请求并返回一个 <not-allowed/> 的错误给发送者(通过以下的违规条目):

例子 91. 服务对于尝试从管理员,所有者或更高岗位的用户撤销权限返回错误

<iq from='darkcave@chat.shakespeare.lit'
    id='voicetest'
    to='crone1@shakespeare.lit/desktop'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='secondwitch' role='visitor'/>
  </query>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

修改发言权列表

在一个被主持的房间里主持人可能希望管理发言权列表. 为了达到这个目的, 主持人首先查询房间所有角色为'participant'的房客列表来请求发言权列表.

例子 92. 主持人请求发言权列表

<iq from='bard@shakespeare.lit/globe'
    id='voice3'
    to='goodfolk@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item role='participant'/>
  </query>
</iq>

服务必须 MUST 接着返回发言权列表给主持人; 每个条目必须 MUST 包含 'nick' 和 'role' 属性并且应该 SHOULD 包含 'affiliation' 和 'jid' 属性:

例子 93. 服务发送发言权列表给主持人

<iq from='goodfolk@chat.shakespeare.lit'
    id='voice3'
    to='bard@shakespeare.lit/globe'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='none'
          jid='polonius@hamlet/castle'
          nick='Polo'
          role='participant'/>
    <item affiliation='none'
          jid='horatio@hamlet/castle'
          nick='horotoro'
          role='participant'/>
    <item affiliation='member'
          jid='hecate@shakespeare.lit/broom'
          nick='Hecate'
          role='participant'/>
  </query>
</iq>

主持人可以 MAY 接着修改发言权列表. 为了达到这个目的, 主持人必须 MUST 发送变更了的条目 (即, 只有 "delta") 给服务; 每个条目必须 MUST 包含 'nick' 属性和 'role' 属性 (通常设置值为 "participant" 或 "visitor") 但是不应该 SHOULD NOT 包含 'jid' 属性并且不能 MUST NOT 包含 'affiliation' 属性 (它用于管理如所有者那样的岗位而不是与会者那样的角色):

例子 94. 主持人发送修改的发言权列表给服务

<iq from='bard@shakespeare.lit/globe'
    id='voice4'
    to='goodfolk@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='Hecate'
          role='visitor'/>
    <item nick='rosencrantz'
          role='participant'>
      <reason>A worthy fellow.</reason>
    </item>
    <item nick='guildenstern'
          role='participant'>
      <reason>A worthy fellow.</reason>
    </item>
  </query>
</iq>

服务必须 MUST 接着通知主持人成功了:

例子 95. 服务通知主持人成功了

<iq from='goodfolk@chat.shakespeare.lit'
    id='voice1'
    to='bard@shakespeare.lit/globe'
    type='result'/>

服务必须 MUST 接着为任何受影响的人发送更新的出席信息给所有房客, 如前文的用例所述,发送适当的扩展出席信息来指明发言权的变更.

大家知道, 不能撤销一个房间所有者或管理员的发言权, 也不能撤销比发出请求的主持人岗位高的用户的发言权. 如果一个房间管理员尝试通过修改发言权列表来撤销这类用户的发言权, 服务必须 MUST 拒绝请求并返回一个 <not-allowed/> 错误给发送者:

例子 96. 服务返回错误给试图撤销管理员,所有者或比发送者岗位更高的用户的发言权的发送者

<iq from='goodfolk@chat.shakespeare.lit'
    id='voicetest'
    to='bard@shakespeare.lit/globe'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item jid='hecate@shakespeare.lit'
          nick='Hecate'
          role='visitor'/>
  </query>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

批准发言权申请

在本文的申请发言权章节提到, 当服务接受到一个来自房客的请求,它应该 SHOULD 转发那个请求给房间的主持人(们). 为了达到这个目的, 服务应该 SHOULD 发送一个 <message/> 节给房间主持人(们), 这里 <message/> 节包含一个数据表格data form来批准或拒绝这个申请, 如下所示.

'例子 97. 申请批准发言权表格

<message from='darkcave@chat.shakespeare.lit'
         id='approve'
         to='crone1@shakespeare.lit/pda'>
  <x xmlns='jabber:x:data' type='form'>
    <title>Voice request</title>
    <instructions>
      To approve this request for voice, select 
      the &quot;Grant voice to this person?&quot;
      checkbox and click OK. To skip this request, 
      click the cancel button.
    </instructions>
    <field var='FORM_TYPE' type='hidden'>
        <value>http://jabber.org/protocol/muc#request</value>
    </field>
    <field var='muc#role'
           type='text-single'
           label='Requested role'>
      <value>participant</value>
    </field>
    <field var='muc#jid'
           type='text-single'
           label='User ID'>
      <value>hag66@shakespeare.lit/pda</value>
    </field>
    <field var='muc#roomnick'
           type='text-single'
           label='Room Nickname'>
      <value>thirdwitch</value>
    </field>
    <field var='muc#request_allow'
           type='boolean'
           label='Grant voice to this person?'>
      <value>false</value>
    </field>
  </x>
</message>

为了批准这个申请, 主持人将提交此表格:

例子 98. 批准发言权申请

<message from='crone1@shakespeare.lit/pda'
         id='approve'
         to='darkcave@chat.shakespeare.lit'>
  <x xmlns='jabber:x:data' type='submit'>
    <field var='FORM_TYPE' type='hidden'>
        <value>http://jabber.org/protocol/muc#request</value>
    </field>
    <field var='muc#role'>
      <value>participant</value>
    </field>
    <field var='muc#jid'>
      <value>hag66@shakespeare.lit/pda</value>
    </field>
    <field var='muc#roomnick'>
      <value>thirdwitch</value>
    </field>
    <field var='muc#request_allow'>
      <value>true</value>
    </field>
  </x>
</message>

如果主持人批准了这个发言权申请, 服务将授予发言权给该房客并发送一个出席信息更新,如本文授予游客发言权章节所述.

管理员用例

一个房间管理员有权修改用户岗位的持久信息 (例如, 通过禁止用户) 并授予和撤销主持人权限, 但是无权修改房间的定义, 那是唯一属于房间所有者(们)的权力. 具体哪些动作是管理员可以执行的则取决于配置. 无论如何, 在 MUC 框架中的用途, 规定房间管理员最少拥有执行以下操作的权限:

  1. 在房间里禁止一个用户
  2. 在房间里修改黑名单
  3. 授予或撤销成员资格
  4. 修改成员列表
  5. 授予或撤销主持人权力
  6. 修改主持人列表

这些特性将由一个 请求/应答 request/response 式的交换来实现,使用 <iq/> 元素,包含满足 'http://jabber.org/protocol/muc#admin' 名字空间的子元素. 以下例子展示协议如何与实现互动以得到期望的功能. (以下除非显示地声明, 如果发送方的'from'地址中的<user@host>和任何房间管理员的纯JID都不同,接下来的任何管理请求必须 MUST 被拒绝; 这种情况下, 服务必须 MUST 返回一个 <forbidden/> 错误.)

禁止用户

在房间里一个管理员或所有者可以禁止一个或多个用户. 这动作必须 MUST 基于房客的纯JID来执行. 为了禁止一个用户, 管理员必须 MUST 把该用户的岗位改为"outcast".

例子 99. 管理员禁止用户

<iq from='kinghenryv@shakespeare.lit/throne'
    id='ban1'
    to='southampton@henryv.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='outcast'
          jid='earlofcambridge@shakespeare.lit'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL.

例子 100. 管理员禁止用户(包含一个原因 Reason)

<iq from='kinghenryv@shakespeare.lit/throne'
    id='ban1'
    to='southampton@henryv.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='outcast'
          jid='earlofcambridge@shakespeare.lit'>
      <reason>Treason</reason>
    </item>
  </query>
</iq>

服务必须 MUST 把那个纯JID添加到黑名单, 应该 SHOULD 把被排斥者的昵称从已注册的昵称列表中移除, 并且必须 MUST 通知管理员或所有者成功了:

例子 101. 服务通知管理员或所有者成功了

<iq from='southampton@henryv.shakespeare.lit'
    id='ban1'
    to='kinghenryv@shakespeare.lit/throne'
    type='result'/>

服务必须 MUST 也移除任何还在房间中的被禁止的用户,通过发送 "unavailable" 类型的出席信息节给每个被禁止的房客, 在扩展的出席信息中包含一个状态码 301 , 可选地带上 reason (如果服务提供的话) 以及执行这个禁止动作的用户的纯JID.

例子 102. 服务移除被禁止的用户

<presence
    from='southampton@henryv.shakespeare.lit/cambridge'
    to='earlofcambridge@shakespeare.lit/stabber'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='outcast' role='none'>
      <actor jid='kinghenryv@shakespeare.lit'/>
      <reason>Treason</reason>
    </item>
    <status code='301'/>
  </x>
</presence>

包含状态码可使客户端能够提交他们自己的通知消息 (例如, 适当的用户位置的信息). 可选的包含原因 reason 元素以及执行者 actor 使得被踢的用户能理解为什么他或她被踢了, 以及被踢的用户可以找谁去理论.

通知主持人之后, 服务必须 MUST 接着通知剩余的房客那个被禁止的房客已经不在房间里了,即从被禁止用户发送 "unavailable" 类型的出席信息节给所有剩余的房客 (就像房客自愿退出房间时所做的一样), 包含状态码 status 以及可选的原因 reason 和执行者 actor.

例子 103. 服务通知剩余的房客

<presence
    type='unavailable'
    from='southampton@henryv.shakespeare.lit/cambridge'
    to='exeter@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='outcast'
          jid='earlofcambridge@shakespeare.lit/stabber'
          role='none'/>
    <status code='301'/>
  </x>
</presence>
 
[ ... ]

就像踢出房客一样, 一个用户不能被自己岗位低的管理员禁止. 所以, 如果一个管理员尝试禁止一个所有者, 服务必须 MUST 拒绝这个请求并返回一个 <not-allowed/> 错误给发送者:

例子 104. 服务对尝试禁止更高岗位用户返回错误

<iq from='kinghenryv@shakespeare.lit/throne'
    id='ban1'
    to='southampton@henryv.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='outcast'
          jid='earlofcambridge@shakespeare.lit'>
      <reason>Treason</reason>
    </item>
  </query>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

如果一个管理员或所有者尝试禁止他自己, 服务必须 MUST 拒绝这个请求并返回一个 <conflict/> 错误给发送者. (注意:这和踢出自己时推荐的服务行为不同, 踢自己的行为服务是允许的.)

修改黑名单

房间管理员可能希望修改黑名单. 注意: 黑名单总是基于用户的纯JID. 要修改黑名单, 管理员首先向房间查询所有岗位为'outcast'的用户以得到黑名单.

例子 105. 管理员请求黑名单

<iq from='kinghenryv@shakespeare.lit/throne'
    id='ban2'
    to='southampton@henryv.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='outcast'/>
  </query>
</iq>

服务必须 MUST 接着返回黑名单给管理员; 每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性但不应该 SHOULD NOT 包含 'nick' 和 'role' 属性:

例子 106. 服务发送黑名单给管理员

<iq from='southampton@henryv.shakespeare.lit'
    id='ban2'
    to='kinghenryv@shakespeare.lit/throne'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='outcast'
          jid='earlofcambridge@shakespeare.lit'>
      <reason>Treason</reason>
    </item>
  </query>
</iq>

管理员可以 MAY 接着修改黑名单. 为此, 管理员必须 MUST 发送变更的条目 (即, 仅是 "delta") 给服务; 每个条目必须 MUST 包含 'affiliation' 属性 (通常设为"outcast"来禁止或"none"来取消禁止) 和 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,不能 MUST NOT 包含 'role' 属性 (它用来管理角色,例如与会者,而不是被排斥者岗位); 另外, reason 和 actor 元素是可选的 OPTIONAL:

例子 107. 管理员发送修改的黑名单给服务

<iq from='kinghenryv@shakespeare.lit/throne'
    id='ban3'
    to='southampton@henryv.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='outcast'
          jid='earlofcambridge@shakespeare.lit'>
      <reason>Treason</reason>
    </item>
    <item affiliation='outcast'>
          jid='lordscroop@shakespeare.lit'>
      <reason>Treason</reason>
    </item>
    <item affiliation='outcast'
          jid='sirthomasgrey@shakespeare.lit'>
      <reason>Treason</reason>
    </item>
  </query>
</iq>

更新黑名单之后, 服务必须 MUST 通知管理员成功了:

例子 108. 服务通知管理员成功了

<iq from='southampton@henryv.shakespeare.lit'
    id='ban3'
    to='kinghenryv@shakespeare.lit/throne'
    type='result'/>

服务必须 MUST 接着移除受影响的房客 (如果他们在房间里) 并从他们发送更新的出席信息 (包含适当的状态码) 给所有剩余的房客,如 "禁止用户" 用例所述. (服务应该 SHOULD 也移除从保留房间昵称列表中移除每个被禁止的用户的保留昵称, 如果必要.)

当一个实体被一个房间禁止, 实现应该 SHOULD 按以下顺序匹配 JIDs (这些匹配规则和RFC 3921中定义的隐私列表的匹配规则是相同的):

  1. <user@domain/resource> (仅匹配特定的资源)
  2. <user@domain> (匹配任何资源)
  3. <domain/resource> (仅匹配特定资源)
  4. <domain> (匹配域名本身, 就像任何 user@domain 或 domain/resource 一样)

一些管理员可能希望在一个 MUC 服务中的所有房间里禁止所有和特定域名相关的用户. 这个功能是一个服务级的特性,所以超过了本文的范围, 它定义在 XEP-0133里.

授予成员资格

管理员可以授予成员资格给一个用户; 方法是把用户的岗位改为 "member" (通常如果用户在房间里,基于昵称,如果用户不在房间里,则基于纯JID; 在这两种情况下如果提供了昵称, 那么这个昵称就是用户在这个房间的缺省昵称,如果实现支持那个功能的话):

例子 109. 管理员授予成员资格

<iq from='crone1@shakespeare.lit/desktop'
    id='member1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL.

例子 110. 管理员授予成员资格(包含一个原因Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='member1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit'>
      <reason>A worthy witch indeed!</reason>
    </item>
  </query>
</iq>

服务必须 MUST 把这个用户添加到成员列表,然后通知管理员成功了:

例子 111. 服务通知管理员成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='member1'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'affiliation'属性值为"member",指明授予了成员资格.

例子 112. 服务发送成员资格通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

如果该用户不在房间里, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 在这个消息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'affiliation'属性值为"member",指明授予了成员资格.

例子 113. 服务发送成员资格通知给所有房客

<message
    from='chat.shakespeare.lit'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit'
          role='none'/>
  </x>
</message>
 
[ ... ]

撤销成员资格

一个管理员可能想撤销一个用户的成员资格; 通过把该用户的岗位改为"none":

例子 114. 管理员撤销成员资格

<iq from='crone1@shakespeare.lit/desktop'
    id='member2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL.

例子 115. 管理员撤销成员资格(包含一个原因Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='member2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit'>
      <reason>Not so worthy after all!</reason> 
    </item>
  </query>
</iq>

服务必须 MUST 从成员列表中移除该用户然后通知主持人成功了:

例子 116. 服务通知主持人成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='member2'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 接着以这个用户的名义发送更新的出席信息节给所有房客, 在这个出席信息里包含了一个满足'http://jabber.org/protocol/muc#user'名字空间的<x/>元素,<x/>元素则包含一个<item/>子元素,其'affiliation'属性值为"none",指明失去了成员资格.

例子 117. 服务通知失去成员资格

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

如果房间是仅限会员的, 服务必须 MUST 从房间移除这个用户, 包含一个状态码 321 来指明用户被移除是因为岗位变更, 并通知所有剩余的房客:

例子 118. 服务移除非会员

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='none'>
      <actor jid='bard@shakespeare.lit'/>
    </item>
    <status code='321'/>
  </x>
</presence>
 
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='none'/>
    <status code='321'/>
  </x>
</presence>
 
[ ... ]

修改成员列表

在一个仅限会员的房间的上下文里, 成员列表本质上是一个允许人们加入房间的白名单 "whitelist". 任何不是成员的人等于是被禁止加入该房间, 即使他们的岗位不是"outcast".

在一个开放房间的上下文里, 成员列表只是一个注册了这个房间的用户 (纯JID和保留的昵称) 的列表. 这些用户可以出现在一个房间名册里, 有他们自己的保留房间昵称, 在搜索结果或类似FAQ里被返回给(查询者).

推荐 RECOMMENDED 在仅限会员的房间里只让房间管理员拥有修改成员列表的权力. 为此, 管理员首先请求成员列表,通过查询房间里所有岗位为"member"的用户来实现:

例子 119. 管理员请求成员列表

<iq from='crone1@shakespeare.lit/desktop'
    id='member3'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='member'/>
  </query>
</iq>

注意: 在一个仅限会员的房间里,服务也应该 SHOULD 返回成员列表给任何房客; 即, 当一个房间的成员请求房间列表时,它不应该 SHOULD NOT 生成一个 <forbidden/> 错误. 这个功能可帮助客户端展示所有现有的成员,即使他们中的一些人不在房间里, 例如. 帮助成员确定是否另一个用户应该被邀请. 服务也应该 SHOULD 允许任何成员接收成员列表,即使还不是一个房客(译注:即未进入房间).

服务必须 MUST 接着返回全部的成员列表给管理员,遵循 'http://jabber.org/protocol/muc#admin' 名字空间; 每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性,每个正在房间里的成员可以 MAY 包含 'nick' 和 'role' 属性.

例子 120. 服务发送成员列表给管理员

<iq from='darkcave@chat.shakespeare.lit'
    id='member3'
    to='crone1@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit'
          nick='thirdwitch'
          role='participant'/>
  </query>
</iq>

管理员可以 MAY 接着修改成员列表. 为此, 管理员必须 MUST 发送变更的条目 (即, 仅 "delta") 给服务; 每个条目必须 MUST 包含 'affiliation' 属性(通常值设为 "member" 或 "none") 和 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,并且不能 MUST NOT 包含 'role' 属性(它是用来管理角色的,例如与会者,而不是成员的岗位):

例子 121. 管理员发送修改的成员列表给服务

<iq from='crone1@shakespeare.lit/desktop'
    id='member4'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit'/>
    <item affiliation='member'
          jid='hecate@shakespeare.lit'/>
  </query>
</iq>

服务必须 MUST 修改成员列表然后通知主持人成功了:

例子 122. 服务通知主持人成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='member4'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 变更任何受影响的用户的岗位. 如果该用户已经从成员列表中移除了, 服务必须 MUST 把该用户的岗位从 "member" 变更为 "none". 如果该用户已经被加入到成员列表, 服务必须 MUST 把该用户的岗位改成 "member".

如果一个被移除的成员正在一个仅限会员的房间, 服务应该 SHOULD 踢出这个房客,如前文所述,通过把被移除的成员的角色改成 "none" 并发送适当的出席信息给这个被移除的成员来实现. 无论是否被移除的那个用户在或不在一个仅限会员的房间里, 服务必须 MUST 随后拒绝这个用户的进入.

对所有的房间类型来说, 服务必须 MUST 以这个用户的名义发送更新的出席信息给所有的房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'affiliation'属性值设为"none",以指明这个岗位的变更.

例子 123. 服务发送失去成员资格的通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

另外, 服务必须 SHOULD 发送一个邀请给任何已加入到仅限会员的房间里的成员名单中的用户,如果该用户目前在该房间还没有岗位, 例如作为一个管理员或所有者(这类用户在定义时不在房间里; 同时要注意这个例子里使用了一个密码password而不是原因reason -- 这两个子元素都是可选的 OPTIONAL):

例子 124. 房间发送邀请给新成员

<message
    from='darkcave@chat.shakespeare.lit'
    to='hecate@shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='bard@shakespeare.lit'/>
    <password>cauldronburn</password>
  </x>
</message>

因为只有管理员们和所有者们应该 SHOULD 被允许修改成员列表, 一个实现可以 MAY 提供一个配置选项,在仅限会员的房间里开放邀请权限给任何成员. 这种情况下, 任何被发送的邀请都应该 SHOULD 自动触发被邀请者加入成员列表. 无论如何, 如果邀请权限被限于管理员们,而普通成员尝试发送邀请, 服务必须 MUST 拒绝这个邀请的的请求并返回一个 <forbidden/> 错误给发送者:

例子 125. 服务在普通成员尝试邀请其他人加入仅限会员的房间时返回错误

<message
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='hecate@shakespeare.lit'>
      <reason>
        Hey Hecate, this is the place for all good witches!
      </reason>
    </invite>
  </x>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>

从开放房间发送的邀请不能 MUST NOT 触发被邀请者加入成员列表.

如果一个用户被加入一个开放房间的成员列表并且该用户在该房间内, 服务必须 MUST 以该用户的名义发送更新的出席信息给所有房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'affiliation'属性值设为"member",以指明这个岗位的变更.

例子 126. 服务发送成员资格通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/hecate'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hecate@shakespeare.lit/broom'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

授予主持人权限

管理员可能想授予主持人权限给一个与会者或游客; 通过把用户的角色改为 "moderator":

例子 127. 管理员授予主持人权限

<iq from='crone1@shakespeare.lit/desktop'
    id='mod1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='moderator'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL.

例子 128. 管理员授予主持人权限(包含一个原因Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='mod1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='moderator'>
      <reason>A worthy witch indeed!</reason> 
    </item>
  </query>
</iq>

服务必须 MUST 添加这个用户到主持人列表然后通知管理员成功了:

例子 129. 服务通知管理员成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='mod1'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 接着以该用户的名义发送更新的出席信息给所有的房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'role'属性值设为"moderator",以指明添加了主持人权限.

例子 130. 服务发送主持人权限通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

撤销主持人权限

管理员可能想撤销用户的主持人权限. 一个管理员只可以 MAY 撤销岗位为"member" 或 "none" (也就是, 非管理员和所有者)的用户的主持人权限. 权限的撤销是通过把用户的角色改为 "participant"实现的:

例子 131. 管理员撤销主持人权限

<iq from='crone1@shakespeare.lit/desktop'
    id='mod2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='participant'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL.

例子 132. 管理员撤销主持人权限(包含一个原因Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='mod2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='thirdwitch'
          role='participant'>
      <reason>Not so worthy after all!</reason> 
    </item>
  </query>
</iq>

服务必须 MUST 从主持人列表移除这个用户然后通知管理员成功了:

例子 133. 服务通知管理员成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='mod2'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 接着以该用户的名义发送更新的出席信息给所有的房客, 这个出席信息拥有一个满足 'http://jabber.org/protocol/muc#user' 名字空间的<x/> 元素并包含一个<item/>子元素, 这个子元素的'role'属性值设为"participant",以指明移除了主持人权限.

例子 134. 服务通知失去了主持人权限

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

大家知道, 管理员不 MUST NOT 被允许从岗位为 "owner" 或 "admin"的用户撤销主持人权限. 如果一个管理员尝试撤销这类用户的权限, 服务必须MUST 拒绝这个请求并返回一个 <not-allowed/> 错误给发送者:

例子 135. 服务在用户尝试撤销管理员或所有者的主持人权限时返回错误

<iq from='darkcave@chat.shakespeare.lit'
    id='modtest'
    to='crone1@shakespeare.lit/desktop'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='secondwitch' role='participant'/>
  </query>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

修改主持人列表

管理员可能希望修改主持人列表. 为此, 管理员首先通过请求房间内所有角色为'moderator'的用户来请求主持人列表.

例子 136. 管理员请求主持人列表

<iq from='crone1@shakespeare.lit/desktop'
    id='mod3'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item role='moderator'/>
  </query>
</iq>

服务必须 MUST 接着返回主持人列表给管理员; 每个条目必须 MUST 包含 'jid', 'nick', 'role' 属性并应该 SHOULD 包含 'affiliation' 属性:

例子 137. 服务发送主持人列表给管理员

<iq from='darkcave@chat.shakespeare.lit'
    id='mod3'
    to='crone1@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          nick='thirdwitch'
          role='moderator'/>
  </query>
</iq>

管理员可以 MAY 接着修改主持人列表. 为此, 管理员必须 MUST发送修改的条目(即, 仅"delta") 给服务; 每个条目必须 MUST 包含 'jid' 属性和'role' 属性(通常值设为 "member" 或 "participant") 但不应该 SHOULD NOT 包含 'nick' 属性并且不能 MUST NOT 包含 'affiliation' 属性(它被用于管理类似管理员这样的岗位而不是主持人这样的角色):

例子 138. 管理员发送修改了的主持人列表给服务

<iq from='crone1@shakespeare.lit/desktop'
    id='mod4'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item jid='hag66@shakespeare.lit/pda'
          role='participant'/>
    <item jid='hecate@shakespeare.lit/broom'
          role='moderator'/>
  </query>
</iq>

服务必须 MUST 修改主持人列表并通知管理员成功了:

例子 139. 服务通知管理员成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='mod4'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 随后以所有受影响的用户发送更新的出席信息给所有的房客, 支出主持人权限的变更,通过发送前面用例所述的适当的扩展出席信息.

显然, 房间所有者或房间管理员的主持人权限不能被撤销. 如果一个房间管理员尝试通过修改主持人列表来撤销这类用户的主持人权限, 服务必须 MUST 拒绝请求并返回一个 <not-allowed/> 错误给发送者:

例子 140. 服务在用户尝试撤销管理员或所有者的主持人权限时返回错误

<iq from='darkcave@chat.shakespeare.lit'
    id='modtest'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item jid='hecate@shakespeare.lit/broom'
          nick='Hecate'
          role='participant'/>
  </query>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

批准注册申请

如果一个服务不自动接受注册到房间的请求, 它可以 MAY 为房间管理员提供一个方法来批准或拒绝来自 Jabber 的注册请求(替代方案是, 它可能提供一个 web 接口或一些其他管理工具). 对这个服务来说,最简单的办法就是,当接收到注册请求时发送一个 <message/> 节给房间管理员(们), 这里的<message/> 节包含一个数据表格 Data Form asking 用来询问管理员是否批准用户的注册申请. 推荐 RECOMMENDED 以下数据表格 Data Form,但是实现可以 MAY 使用完全不同的表格, 或or 在下面的表格基础上补充字段.

例子 141. 注册申请批准表格

<message from='darkcave@chat.shakespeare.lit'
         id='approve'
         to='crone1@shakespeare.lit/pda'>
  <x xmlns='jabber:x:data' type='form'>
    <title>Registration request</title>
    <instructions>
      To approve this registration request, select the
      &quot;Allow this person to register with the room?&quot;
      checkbox and click OK. To skip this request, click the 
      cancel button.
    </instructions>
    <field var='FORM_TYPE' type='hidden'>
        <value>http://jabber.org/protocol/muc#register</value>
    </field>
    <field var='muc#register_first'
           type='text-single'
           label='Given Name'>
      <value>Brunhilde</value>
    </field>
    <field var='muc#register_last'
           type="text-single"
           label="Family Name">
      <value>Entwhistle-Throckmorton</value>
    </field>
    <field var='muc#register_roomnick'
           type="text-single"
           label="Desired Nickname">
      <value>thirdwitch</value>
    </field>
    <field var='muc#register_url'
           type="text-single"
           label="User URL">
      <value>http://witchesonline/~hag66/</value>
    </field>
    <field var='muc#register_email'
           type="text-single"
           label="Email Address">
      <value>hag66@witchesonline</value>
    </field>
    <field var='muc#register_faqentry'
           type="text-single"
           label="FAQ Entry">
      <value>Just another witch.</value>
    </field>
    <field var='muc#register_allow'
           type='boolean'
           label='Allow this person to register with the room?'>
      <value>0</value>
    </field>
  </x>
</message>

如果管理员批准了注册申请, 服务将把该用户注册到房间.

更多高级的批准机制(例如, 使用特定命令Ad-Hoc Commands 19来接收注册申请列表,就像 Publish-Subscribe 20里所做的一样) 超出了本文的范围.

所有者用例

每个房间必须 MUST 至少有一个所有者, 而所有者(或一个成功者)在一个房间的生命周期里是这个房间长期存在的属性(例如, 所有者在退出一个持久性的房间时不会失去所有权). 本文假定(初始的) 房间所有者是那个新建了该房间的用户并且有一个房间所有者有权修改房间配置选项的定义,例如房间类型. 理想情况下, 房间所有者不仅能指定房间类型(密码保护的, 仅限会员的, 等等) 而且包括如本文的 [XEP-0045#需求|需求]章节所述的房间特定属性. 另外, 如果所有者能指定其他所有者们的JID也是不错的, 但那将取决于具体实现.

为了让配置选项更加广泛提供必要的伸缩性, 房间配置将使用 Data Forms (XEP-0004), 通过使用由 'http://jabber.org/protocol/muc' 名字空间触发. 也就是, 如果一个实体在它请求加入房间的 join/request 里不包含 MUC 名字空间, 那么服务将立刻新建房间,在新建房间之前不等待通过数据表格进行配置(这保证了和旧的"groupchat 1.0"协议的向后兼容); 无论如何, 如果房间的 join/create 请求包含了 MUC 扩展, 那么服务在新建和解锁该房间之前将通过数据表格请求配置.

注意: 以下展示的配置选项列出了本文的需求章节的所有特性和房间类型; 无论如何, 实际的配置选项和表格布局将取决于实现和具体的布署. 而且, 这些只是例子,不代表这些就是房间可以拥有的所有允许或需要的配置选项. 一个特定的实现或布署可以 MAY 选择提供额外的配置选项(敏感词过滤, 设置房间的缺省语言, 消息记录, 等等), 这就是为什么在这里使用 'jabber:x:data' 协议是很有价值的.

新建房间

一般注意事项

新建房间的权限可以 MAY 限制在特定的用户群或可以 MAY 保留给一个服务级别的管理员. 如果访问被拒绝而一个用户试图新建一个房间, 服务必须MUST 返回一个 <not-allowed/> 错误:

例子 142. 服务通知用户不能新建房间

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>

如果访问不限制, 服务必须 MUST 允许用户按以下步骤新建房间.

从房间创建的视角来看, 本质上有两种房间:

  • 即时房间"Instant rooms" -- 可以立刻访问并基于某些缺省配置自动创建.
  • 保留房间"Reserved rooms" -- 在任何人访问之前由房间配置者手动创建.

新建和配置这些房间的流程如下:

  1. 用户必须 MUST 发送出席信息到 <room@service/nick> 并声明他或她对MUC协议的支持,通过包含一个扩展的出席信息,并包含在一个空的满足'http://jabber.org/protocol/muc'名字空间的 <x/> 子元素里(注意这里不包含 '#owner' 或 '#user' 后缀).
  2. 如果用户被允许新建房间并且房间还不存在, 服务必须 MUST 根据一些缺省配置新建此房间, 指定请求的用户成为初始的房间拥有者, 并增加这个拥有者到该房间但不允许任何别的用户进入该房间(有效地锁定 "locking"该房间). 从房间发送由所有者收到的初始的出席信息节必须 MUST 包含扩展的出席信息以指出该用户的状态为一个所有者并承认房间已经被创建了(通过状态码 201) 并等待配置.
  3. 如果初始的房间所有者想新建和配置一个保留房间, 房间所有者必须 MUST 接着请求一个配置,通过发送类型为"get"的IQ节并包含一个空的满足'http://jabber.org/protocol/muc#owner'名字空间的<query/>元素给该房间 ,然后完成第4和第5步. 如果房间所有者喜欢新建一个即时房间, 该房间所有者必须 MUST 发送一个遵循'http://jabber.org/protocol/muc#owner'名字空间的 query 元素并包含一个遵循 'jabber:x:data' 名字空间的空的类型为 "submit" 的 <x/> 元素, 然后跳到第6步.
  4. 如果房间所有者请求了一个配置表格, 服务必须 MUST 发送一个包含配置表格并遵循 'jabber:x:data'名字空间的 IQ 给房间拥有者. 如果没有配置选项可用, 房间必须 MUST 返回一个空的 query 元素给房间所有者.
  5. 初始的房间所有者应该 SHOULD 为该房间提供一个开始的配置(或接受缺省配置),通过发送"set"类型并包含完整的配置表格的 IQ . 另外, 房间所有者可以 MAY 取消配置过程. (实现可以 MAY 设置一个初始化配置的超时, 这样如果房间所有者再给定的超时时间内不配置房间, 房间所有者就被假定已经接受了缺省得配置或取消了配置过程.)
  6. 一旦服务从初始房间所有者接收了完整的配置表格(或接收到了一个即时房间的请求), 服务必须 MUST 解锁 "unlock" 这个房间 (即, 允许其他用户进入此房间) 并发送"result"类型的 IQ 给房间所有者. 如果服务接收到了取消(指令), 它必须 MUST 销毁这个房间.

以下例子展示了这个协议流程.

首先, Jabber用户必须 MUST 发送出席信息给房间, 包含空的 <x/> 元素,遵循 'http://jabber.org/protocol/muc' 名字空间(当他寻求进入一个房间时也发送和这同样的节).

例子 143. Jabber用户新建一个房间并声明对多用户聊天的支持

<presence
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit/firstwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

如果该房间不存在, 服务应该 SHOULD 新建这个房间(取决于关于新建房间的本地策略), 指定发出请求的用户的纯JID成为所有者, 添加这个所有者到房间, 并通过发送以下格式的出席信息节承认房间新建成功:

例子 144. 服务承认房间新建成功

<presence
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner'
          role='moderator'/>
    <status code='110'/>
    <status code='201'/>
  </x>
</presence>

接收到该房间已经创建的通知之后, 房间所有者需要决定是否接受缺省的房间配置(即, 新建一个即时房间 "instant room") 还是做一些不同于缺省房间设置的配置 (即, 新建一个保留房间"reserved room"). 完成这两个用例的协议流程展示如下.

注意: 如果如上的发送到一个不存在的房间里的出席信息节没有包含一个遵循 'http://jabber.org/protocol/muc'名字空间的 <x/> 元素, 服务应该SHOULD 立刻新建一个缺省的房间(即, 它必须 MUST 假定客户端支持 "groupchat 1.0" 而不是 Multi-User Chat, 所以在等待房间创建者决定是创建即时房间还是保留房间的时候,它不能 MUST NOT 锁定这个房间).

新建即时房间

如果初始的房间所有者想接受缺省的房间配置(即, 新建一个即时房间"instant room"), 房间所有者必须 MUST 拒绝初始配置表格,通过发送一个 IQ set 给 <room@service> 本身,包含一个遵循'http://jabber.org/protocol/muc#owner'名字空间的 <query/> 元素, 这里 <query/> 的唯一子元素是一个空的遵循'jabber:x:data'名字空间的 <x/> 元素并且拥有一个 'type'属性值为 "submit":

例子 145. 所有者请求即时房间

<iq from='crone1@shakespeare.lit/desktop'
    id='create1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x xmlns='jabber:x:data' type='submit'/>
  </query>
</iq>

服务必须 MUST 接着解锁该房间并允许其他实体加入它.

新建保留房间

如果初始的房间所有者想新建并配置一个保留房间, 这个房间所有者必须 MUST 请求初始配置表格,通过发送一个 IQ get 给 <room@service> 本身,包含一个空的遵循 'http://jabber.org/protocol/muc#owner' 名字空间的 <query/> 元素 :

例子 146. 所有者请求配置表单

<iq from='crone1@shakespeare.lit/desktop'
    id='create1'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#owner'/>
</iq>

如果房间还不存在, 服务必须 MUST 返回一个初始的房间配置表单给该用户. (注意: 以下例子展示一个配置选项的典型例子. 已登记用于房间创建和配置的所有 x:data 字段列表由 XMPP Registrar 维护; 参见本文的 XMPP注册项事项 章节.)

例子 147. 服务发送配置表单

<iq from='darkcave@chat.shakespeare.lit'
    id='create1'
    to='crone1@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x xmlns='jabber:x:data' type='form'>
      <title>Configuration for "darkcave" Room</title>
      <instructions>
          Your room darkcave@macbeth has been created!
          The default configuration is as follows:
            - No logging
            - No moderation
            - Up to 20 occupants
            - No password required
            - No invitation required
            - Room is not persistent
            - Only admins may change the subject
            - Presence broadcasted for all users
          To accept the default configuration, click OK. To
          select a different configuration, please complete
          this form.
      </instructions>
      <field
          type='hidden'
          var='FORM_TYPE'>
        <value>http://jabber.org/protocol/muc#roomconfig</value>
      </field>
      <field
          label='Natural-Language Room Name'
          type='text-single'
          var='muc#roomconfig_roomname'/>
      <field
          label='Short Description of Room'
          type='text-single'
          var='muc#roomconfig_roomdesc'/>
      <field
          label='Natural Language for Room Discussions'
          type='text-single'
          var='muc#roomconfig_lang'/>
      <field
          label='Enable Public Logging?'
          type='boolean'
          var='muc#roomconfig_enablelogging'>
        <value>0</value>
      </field>
      <field
          label='Allow Occupants to Change Subject?'
          type='boolean'
          var='muc#roomconfig_changesubject'>
        <value>0</value>
      </field>
      <field
          label='Allow Occupants to Invite Others?'
          type='boolean'
          var='muc#roomconfig_allowinvites'>
        <value>0</value>
      </field>
      <field
          label='Maximum Number of Occupants'
          type='list-single'
          var='muc#roomconfig_maxusers'>
        <value>20</value>
        <option label='10'><value>10</value></option>
        <option label='20'><value>20</value></option>
        <option label='30'><value>30</value></option>
        <option label='50'><value>50</value></option>
        <option label='100'><value>100</value></option>
        <option label='None'><value>none</value></option>
      </field>
      <field
          label='Roles for which Presence is Broadcast'
          type='list-multi'
          var='muc#roomconfig_presencebroadcast'>
        <value>moderator</value>
        <value>participant</value>
        <value>visitor</value>
        <option label='Moderator'><value>moderator</value></option>
        <option label='Participant'><value>participant</value></option>
        <option label='Visitor'><value>visitor</value></option>
      </field>
      <field
          label='Roles and Affiliations that May Retrieve Member List'
          type='list-multi'
          var='muc#roomconfig_getmemberlist'>
        <value>moderator</value>
        <value>participant</value>
        <value>visitor</value>
        <option label='Moderator'><value>moderator</value></option>
        <option label='Participant'><value>participant</value></option>
        <option label='Visitor'><value>visitor</value></option>
      </field>
      <field
          label='Make Room Publicly Searchable?'
          type='boolean'
          var='muc#roomconfig_publicroom'>
        <value>1</value>
      </field>
      <field
          label='Make Room Persistent?'
          type='boolean'
          var='muc#roomconfig_persistentroom'>
        <value>0</value>
      </field>
      <field
          label='Make Room Moderated?'
          type='boolean'
          var='muc#roomconfig_moderatedroom'>
        <value>0</value>
      </field>
      <field
          label='Make Room Members-Only?'
          type='boolean'
          var='muc#roomconfig_membersonly'>
        <value>0</value>
      </field>
      <field
          label='Password Required to Enter?'
          type='boolean'
          var='muc#roomconfig_passwordprotectedroom'>
        <value>0</value>
      </field>
      <field type='fixed'>
        <value>
          If a password is required to enter this room,
          you must specify the password below.
        </value>
      </field>
      <field
          label='Password'
          type='text-private'
          var='muc#roomconfig_roomsecret'/>
      <field
          label='Who May Discover Real JIDs?'
          type='list-single'
          var='muc#roomconfig_whois'>
        <option label='Moderators Only'>
          <value>moderators</value>
        </option>
        <option label='Anyone'>
          <value>anyone</value>
        </option>
      </field>
      <field type='fixed'>
        <value>
          You may specify additional people who have
          administrative privileges in the room. Please
          provide one Jabber ID per line.
        </value>
      </field>
      <field
          label='Room Admins'
          type='jid-multi'
          var='muc#roomconfig_roomadmins'/>
      <field type='fixed'>
        <value>
          You may specify additional owners for this
          room. Please provide one Jabber ID per line.
        </value>
      </field>
      <field
          label='Room Owners'
          type='jid-multi'
          var='muc#roomconfig_roomowners'/>
    </x>
  </query>
</iq>

注意: _whois 配置选项指定该房间是非匿名的(值为 "anyone"), 半匿名的(值为"moderators"), 还是全匿名的(值为"none", 不显示在这).

如果没有配置选项可用, 服务必须 MUST 返回空的 query 元素给房间所有者:

例子 148. 服务通知所有者没有配置可用

<iq from='darkcave@chat.shakespeare.lit'
    id='create1'
    to='crone1@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#owner'/>
</iq>

房间所有者应该 SHOULD 接着填好表单并提交给服务.

例子 149. 所有者提交配置表单

<iq from='crone1@shakespeare.lit/desktop'
    id='create2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x xmlns='jabber:x:data' type='submit'>
      <field var='FORM_TYPE'>
        <value>http://jabber.org/protocol/muc#roomconfig</value>
      </field>
      <field var='muc#roomconfig_roomname'>
        <value>A Dark Cave</value>
      </field>
      <field var='muc#roomconfig_roomdesc'>
        <value>The place for all good witches!</value>
      </field>
      <field var='muc#roomconfig_enablelogging'>
        <value>0</value>
      </field>
      <field var='muc#roomconfig_changesubject'>
        <value>1</value>
      </field>
      <field var='muc#roomconfig_allowinvites'>
        <value>0</value>
      </field>
      <field var='muc#roomconfig_maxusers'>
        <value>10</value>
      </field>
      <field var='muc#roomconfig_publicroom'>
        <value>0</value>
      </field>
      <field var='muc#roomconfig_persistentroom'>
        <value>0</value>
      </field>
      <field var='muc#roomconfig_moderatedroom'>
        <value>0</value>
      </field>
      <field var='muc#roomconfig_membersonly'>
        <value>0</value>
      </field>
      <field var='muc#roomconfig_passwordprotectedroom'>
        <value>1</value>
      </field>
      <field var='muc#roomconfig_roomsecret'>
        <value>cauldronburn</value>
      </field>
      <field var='muc#roomconfig_whois'>
        <value>moderators</value>
      </field>
      <field var='muc#roomconfig_roomadmins'>
        <value>wiccarocks@shakespeare.lit</value>
        <value>hecate@shakespeare.lit</value>
      </field>
    </x>
  </query>
</iq>

如果房间创建成功, 服务必须 MUST 通知新的房间所有者成功了:

例子 150. 服务通知新房间所有者成功

<iq from='darkcave@chat.shakespeare.lit'
    id='create2'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

如果因为指定的房间配置违反了一个或多个服务策略而导致房间创建失败 (例如, 因为密码保护房间的密码为空), 服务必须 MUST 返回一个 <not-acceptable/> 错误.

例子 151. 服务通知所有者请求的配置选项不被接受

<iq from='darkcave@chat.shakespeare.lit'
    id='create2'
    to='crone1@shakespeare.lit/desktop'
    type='error'>
  <error type='modify'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

另一方面, 房间所有者可以 MAY 取消配置过程:

例子 152. 所有者取消初始的配置

<iq from='crone1@shakespeare.lit/desktop'
    id='create2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x xmlns='jabber:x:data' type='cancel'/>
  </query>
</iq>

如果房间所有者取消了初始的房间配置, 服务应该 SHOULD 销毁房间, 确保发送不可用出席信息给房间所有者 (详见 "销毁房间" 用例).

如果房间所有者在提交表单之前因为任何原因下线了(例如, 失去连接), 服务将接收到一个类型为 "unavailable" 的出席信息节,从所有者到所有者的 <room@service/nick> 或到 <room@service> (或两者). 服务必须 MUST 接着销毁这个房间, 发送一个 "unavailable" 类型的出席信息节,从房间到所有者,包含一个 <destroy/> 元素以及 reason (子元素)(如果提供了) ,参见本文的 销毁房间章节.

申请唯一房间名

在一些场合 (例如, 当 把一对一聊天转为会议), 房间创建者可能想在尝试新建房间之前请求一个唯一的房间名 (例如, 避免可能的房间冲突). 为此, 服务可以 MAY 如本章所述支持这个特性. (如果服务支持这个特性, 它必须 MUST 在对服务发现信息请求应答时返回一个 "http://jabber.org/protocol/muc#unique" 特性.)

房间创建者通过发送一个 IQ-get 给服务本身来请求唯一房间名, 这个IQ节中包含一个空的 <unique/> 元素,遵循 'http://jabber.org/protocol/muc#unique' 名字空间:

例子 153. 实体请求唯一房间名

<iq from='crone1@shakespeare.lit/desktop'
    id='unique1'
    to='chat.shakespeare.lit'
    type='get'>
  <unique xmlns='http://jabber.org/protocol/muc#unique'/>
</iq>

如果服务支持这个特性, 它应该 SHOULD 以 XML 字符数据的方式返回一个唯一房间名,包含一个 <unique/> 元素 (但不创建该房间):

例子 154. 服务返回唯一房间名

<iq from='chat.shakespeare.lit'
    id='unique1'
    to='crone1@shakespeare.lit/desktop'
    type='result'>
  <unique xmlns='http://jabber.org/protocol/muc#unique'>
    6d9423a55f499b29ad20bf7b2bdea4f4b885ead1
  </unique>
</iq>

服务可以 MAY 拒绝返回一个唯一房间名给一个没有资格创建房间的实体, 或那些发送请求唯一房间名过多次数的实体, 等等.

服务可以 MAY 使用算法保证房间名的创建在服务上下文中是唯一的 (例如, 对发出请求的JID,datetime,和random salt的SHA-1 哈希运算).

房间创建者将接着使用 XML 字符数据 <unique/> 元素作为它请求的房间JID的节点标识符(ID):

例子 155. 所有者以唯一名创建房间

<presence 
    from='crone1@shakespeare.lit/desktop'
    to='6d9423a55f499b29ad20bf7b2bdea4f4b885ead1@chat.shakespeare.lit/firstwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

随后的房间配置

在指定房间的初始配置之后的任何时间, 房间所有者可能想修改房间配置. 为此, 房间所有者必须 MUST 向房间发出一个新的配置表单请求,通过发送一个 IQ 到 <room@service> ,包含一个空的 <query/> 元素,遵循 'http://jabber.org/protocol/muc#owner' 名字空间.

例子 156. 所有者请求配置表单

<iq from='crone1@shakespeare.lit/desktop'
    id='config1'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#owner'/>
</iq>

如果'from'地址的 <user@host> 部分和房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者:

例子 157. 服务禁止非所有者的访问配置

<iq from='darkcave@chat.shakespeare.lit'
    id='configures'
    to='wiccarocks@shakespeare.lit/laptop'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#owner'/>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

另外, 服务必须 MUST 以当前使用的选项组作为缺省值发送一个配置表单给房间所有者:

例子 158. 服务发送配置表单给所有者

<iq from='darkcave@chat.shakespeare.lit'
    id='config1'
    to='crone1@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x xmlns='jabber:x:data' type='form'>
      <title>Configuration for "darkcave" Room</title>
      <instructions>
        Complete this form to make changes to
        the configuration of your room.
      </instructions>
      <field
          type='hidden'
          var='FORM_TYPE'>
        <value>http://jabber.org/protocol/muc#roomconfig</value>
      </field>
      <field
          label='Natural-Language Room Name'
          type='text-single'
          var='muc#roomconfig_roomname'>
        <value>A Dark Cave</value>
      </field>
      <field
          label='Short Description of Room'
          type='text-single'
          var='muc#roomconfig_roomdesc'>
        <value>The place for all good witches!</value>
      </field>
      <field
          label='Enable Public Logging?'
          type='boolean'
          var='muc#roomconfig_enablelogging'>
        <value>0</value>
      </field>
      <field
          label='Allow Occupants to Change Subject?'
          type='boolean'
          var='muc#roomconfig_changesubject'>
        <value>0</value>
      </field>
      <field
          label='Allow Occupants to Invite Others?'
          type='boolean'
          var='muc#roomconfig_allowinvites'>
        <value>0</value>
      </field>
      <field
          label='Maximum Number of Occupants'
          type='list-single'
          var='muc#roomconfig_maxusers'>
        <value>10</value>
        <option label='10'><value>10</value></option>
        <option label='20'><value>20</value></option>
        <option label='30'><value>30</value></option>
        <option label='50'><value>50</value></option>
        <option label='100'><value>100</value></option>
        <option label='None'><value>none</value></option>
      </field>
      <field
          label='Roles for which Presence is Broadcast'
          type='list-multi'
          var='muc#roomconfig_presencebroadcast'>
        <value>moderator</value>
        <value>participant</value>
        <value>visitor</value>
        <option label='Moderator'><value>moderator</value></option>
        <option label='Participant'><value>participant</value></option>
        <option label='Visitor'><value>visitor</value></option>
      </field>
      <field
          label='Roles and Affiliations that May Retrieve Member List'
          type='list-multi'
          var='muc#roomconfig_getmemberlist'>
        <value>moderator</value>
        <value>participant</value>
        <value>visitor</value>
        <option label='Moderator'><value>moderator</value></option>
        <option label='Participant'><value>participant</value></option>
        <option label='Visitor'><value>visitor</value></option>
      </field>
      <field
          label='Make Room Publicly Searchable?'
          type='boolean'
          var='muc#roomconfig_publicroom'>
        <value>0</value>
      </field>
      <field
          label='Make Room Persistent?'
          type='boolean'
          var='muc#roomconfig_persistentroom'>
        <value>0</value>
      </field>
      <field
          label='Make Room Moderated?'
          type='boolean'
          var='muc#roomconfig_moderatedroom'>
        <value>0</value>
      </field>
      <field
          label='Make Room Members Only?'
          type='boolean'
          var='muc#roomconfig_membersonly'>
        <value>0</value>
      </field>
      <field
          label='Password Required for Entry?'
          type='boolean'
          var='muc#roomconfig_passwordprotectedroom'>
        <value>1</value>
      </field>
      <field type='fixed'>
        <value>
          If a password is required to enter this room,
          you must specify the password below.
        </value>
      </field>
      <field
          label='Password'
          type='text-private'
          var='muc#roomconfig_roomsecret'>
        <value>cauldronburn</value>
      </field>
      <field
          label='Who May Discover Real JIDs?'
          type='list-single'
          var='muc#roomconfig_whois'>
        <value>moderators</value>
        <option label='Moderators Only'>
          <value>moderators</value>
        </option>
        <option label='Anyone'>
          <value>anyone</value>
        </option>
      </field>
      <field type='fixed'>
        <value>
          You may specify additional people who have
          administrative privileges in the room. Please
          provide one Jabber ID per line.
        </value>
      </field>
      <field
          label='Room Admins'
          type='jid-multi'
          var='muc#roomconfig_roomadmins'>
        <value>wiccarocks@shakespeare.lit</value>
        <value>hecate@shakespeare.lit</value>
      </field>
      <field type='fixed'>
        <value>
          You may specify additional owners for this
          room. Please provide one Jabber ID per line.
        </value>
      </field>
      <field
          label='Room Owners'
          type='jid-multi'
          var='muc#roomconfig_roomowners'/>
    </x>
  </query>
</iq>

如果没有配置选项可用, 服务必须 MUST 返回一个空的 query 元素给房间所有者,如前面的用例所示.

该房间所有者应该 SHOULD 接着以更新的配置信息提交表单.

另外, 房间所有者可以 MAY 取消这次配置过程:

例子 159. 所有者取消随后的配置

<iq from='crone1@shakespeare.lit/desktop'
    id='config2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x xmlns='jabber:x:data' type='cancel'/>
  </query>
</iq>

如果房间所有者取消随后的配置, 服务必须 MUST 让该房间的配置保持和房间所有者请求这次配置之前一样.

如果一次房间配置变更导致一个房间管理员失去管理权限,而这个管理员正在房间里, 该房间必须 MUST 为那个管理员发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "member" 或 'role' 属性值为 "participant" 或 "visitor" ,以适当地表达岗位级别和房间类型:

例子 160. 服务通知失去管理员岗位

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='wiccarocks@shakespeare.lit/laptop'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

如果一次房间配置变更导致一个用户获得管理员权限,而这个用户正在房间里, 房间必须 MUST 为那个用户发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin" 或 'role' 属性值为 "admin" :

例子 161. 服务通知所有用户有人获得管理员岗位

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit/laptop'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

如果一次房间配置变更导致一个房间所有者失去所有者权限,而这个所有者正在房间里, 该房间必须 MUST 为那个所有者发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin" 或 'role' 属性值为根据岗位和房间类型确定的适当的值(推荐为"moderator").

例子 162. 服务通知失去所有者岗位

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit/laptop'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

如果没有其他所有者,服务不能 MUST NOT 允许一个所有者撤销他或她自己的所有权; 如果一个所有者企图这么干, 服务必须 MUST 返回一个 <conflict/> 错误给这个所有者. 然而, 如果有其他所有者,服务应该 SHOULD 允许一个所有者撤销自己的所有者权限.

如果一次房间配置变更导致一个用户获得所有者权限,而这个用户正在房间里, 房间必须 MUST 为那个用户发送更新的出席信息给所有房客, 表明状态的变更,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "owner" 或 'role' 属性值为根据岗位和房间类型确定的适当的值(推荐为"moderator").

例子 163. 服务通知所有用户有人获得所有者权限

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner'
          jid='wiccarocks@shakespeare.lit/laptop'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

如果一次房间配置变更导致房间类型变成仅限会员,但还有非成员在房间里, 服务必须 MUST 从房间移除任何非成员,并在发送给那些剩余的房客的 '不可用' 出席信息节里包含状态码 322.

配置变更通知

当一个房间的配置变更会对房间的隐私和安全策略产生影响时,该房间必须 MUST 发送通知给所有房客. 这个通知将包括一个 <message/> 节,包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的 <x/> 元素, <x/> 元素则只有一个 <status/> 子元素,其 'code' 属性为一个适当的值. 这是例子:

例子 164. 配置状态码

<message from='darkcave@chat.shakespeare.lit'
         to='crone1@shakespeare.lit/desktop'
         type='groupchat'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <status code='170'/>
  </x>
</message>

房间配置中和隐私相关的策略变更导致生成这些状态码,如下:

  • 如果房间日志功能可用了, 状态码 170.
  • 如果房间日志现在禁止了, 状态码 171.
  • 如果房间现在是非匿名的了, 状态码 172.
  • 如果房间现在是半匿名的了, 状态码 173.
  • 如果房间现在是全匿名的了, 状态码 174.

对更多其他配置变更, 房间应该 SHOULD 发送状态码 104 这样感兴趣的房客如果想要的话可以接受到更新的房间配置.

授予所有者权限

如果实现允许, 一个所有者可以 MAY 授予所有权给其他用户; 只要把用户的岗位改成"owner":

例子 165. 所有者授予所有权

<iq from='crone1@shakespeare.lit/desktop'
    id='owner1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='owner'
          jid='hecate@shakespeare.lit'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL.

例子 166. 所有者授予所有权(饱含一个原因 Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='owner1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='owner'
          jid='hecate@shakespeare.lit'>
      <reason>A worthy witch indeed!</reason>
    </item>
  </query>
</iq>

服务必须 MUST 把用户添加到所有者列表并通知所有者成功了:

例子 167. 服务通知所有者成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='owner1'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已授予所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "owner" 并且 'role' 属性值为根据岗位和房间类型确定的适当的值(推荐为"moderator").

例子 168. 服务发送所有权通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/hecate'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner'
          jid='hecate@shakespeare.lit'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已授予所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "owner" .

例子 169. 服务发送所有权通知给所有房客

<message
    from='chat.shakespeare.lit'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hecate@shakespeare.lit'
          role='none'/>
  </x>
</message>
 
[ ... ]

撤销所有者权限

实现可以 MAY 允许一个所有者撤销其他用户的所有权; 只要把用户的岗位改成非"owner":

例子 170. 所有者撤销所有权

<iq from='crone1@shakespeare.lit/desktop'
    id='owner2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='admin'
          jid='hecate@shakespeare.lit'/>
  </query>
</iq>

<reason/>元素是可选的 OPTIONAL.

例子 171. 所有者撤销所有权(包含一个原因)

<iq from='crone1@shakespeare.lit/desktop'
    id='owner2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='admin'
          jid='hecate@shakespeare.lit'>
      <reason>Not so worthy after all!</reason> 
    </item>
  </query>
</iq>

如果没有其它所有者,服务不能 MUST NOT 允许一个所有者撤销他或她自己的所有权; 如果一个所有者尝试这么干, 服务必须 MUST 返回一个 <conflict/> 错误给该所有者. 然而, 如果有其他所有者,服务应该 SHOULD 允许一个所有者撤销自己的所有权.

如果一个实现不允许所有者撤销另一个用户的所有权, 实现必须 MUST 返回一个 <not-authorized/> 错误给做出这个请求的所有者.

注意: 允许一个所有者移除其它用户的所有权能给房间管理一个折衷的控制模式; 所以这个特性是可选的 OPTIONAL, 并且鼓励实现支持通过一个只有拥有服务范围管理权限的用户使用的接口来移除所有者.

其它情况下, 服务必须 MUST 把用户从所有者列表移除并通知所有者成功了:

例子 172. 服务通知所有者成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='owner2'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已失去所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非 "owner" 并且 'role' 属性值为根据岗位和房间类型确定的适当的值:

例子 173. 服务通知失去所有权

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='hecate@shakespeare.lit'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已失去所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非 "owner" .

例子 174. 服务发送失去所有权通知给所有房客

<message
    from='chat.shakespeare.lit'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='hecate@shakespeare.lit'
          role='none'/>
  </x>
</message>
 
[ ... ]

修改所有者列表

如果实现允许, 一个房间所有者可能想修改所有者列表. 为此, 所有者首先请求所有者列表,通过向房间请求所有岗位为 'owner'的用户.

例子 175. 所有者请求所有者列表

<iq from='bard@shakespeare.lit/globe'
    id='owner3'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='owner'/>
  </query>
</iq>

如果'from'地址的 <user@host> 部分和房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者.

否则, 服务必须 MUST 接着返回所有者列表给所有者; 每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性,对任何正是一名房客(也就是正在房间里)的所有者可以 MAY 包含 'nick' 和 'role' 属性:

例子 176. 服务发送所有者列表给所有者

<iq from='darkcave@chat.shakespeare.lit'
    id='owner3'
    to='bard@shakespeare.lit/globe'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='owner'
          jid='crone1@shakespeare.lit'/>
  </query>
</iq>

所有者可以 MAY 接着修改所有者列表. 为此, 所有者必须 MUST 发送修改的条目 (即, 仅 "delta") 给服务; 21每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,不能 MUST NOT 包含 'role' 属性 (它用于管理参与者之类的角色,而不是所有者之类的岗位):

例子 177. 所有者发送修改过的所有者列表给服务

<iq from='bard@shakespeare.lit/globe'
    id='owner4'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='owner'
          jid='hecate@shakespeare.lit'/>
  </query>
</iq>

只有所有者被允许修改所有者列表. 如果一个非所有者试图察看或修改所有者列表, 服务必须 MUST 拒绝这个请求并返回一个 <forbidden/> 错误给发送者:

例子 178. 服务对于非所有者试图修改所有者列表返回错误

<iq from='darkcave@chat.shakespeare.lit'
    id='ownertest'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='owner' 
          jid='hecate@shakespeare.lit'/>
  </query>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

如果没有别的所有者,服务不能 MUST NOT 允许一个所有者撤销自己的所有权; 如果一个所有者尝试这么干, 服务必须 MUST 返回一个 <conflict/> 错误给该所有者. 然而, 如果有其他所有者,服务应该 SHOULD 允许一个所有者撤销自己的所有权.

其它情况下, 服务必须 MUST 修改所有者列表并通知所有者成功了:

例子 179. 服务通知所有者成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='owner4'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 也为任何因前述所有者列表修改而导致的岗位变化而发送出席信息通知.

授予管理员权限

一个所有者可以授予管理员权限给一个成员或无岗位的用户; 只要把用户的岗位改成"admin":

例子 180. 所有者授予管理员权限

<iq from='crone1@shakespeare.lit/desktop'
    id='admin1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit'/>
  </query>
</iq>

<reason/> 元素是可选的 OPTIONAL.

例子 181. 所有者授予管理员权限(包含一个原因 Reason)

<iq from='crone1@shakespeare.lit/desktop'
    id='admin1'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit'>
      <reason>A worthy witch indeed!</reason>
    </item>
  </query>
</iq>

服务必须 MUST 把用户添加到管理员列表并通知所有者成功了:

例子 182. 服务通知所有者成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='admin1'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已授予管理员权限,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin" 并且 'role' 属性值为根据岗位和房间类型确定的适当的值.

例子 183. 服务发送管理员权限通知给所有房客

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit'
          role='moderator'/>
  </x>
</presence>
 
[ ... ]

如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已授予管理员权限,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为 "admin".

例子 184. 服务发送管理员权限通知给所有房客

<message
    from='chat.shakespeare.lit'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit'
          role='none'/>
  </x>
</message>
 
[ ... ]

撤销管理员权限

一个所有者可能想撤销一个用户的管理员权限; 只要把用户的岗位改成非"admin"和非"owner":

例子 185. 所有者撤销管理员权限

<iq from='crone1@shakespeare.lit/desktop'
    id='admin2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='member'
          jid='wiccarocks@shakespeare.lit'/>
  </query>
</iq>

<reason/>元素是可选的 OPTIONAL.

例子 186. 所有者撤销管理员权限(包含一个原因)

<iq from='crone1@shakespeare.lit/desktop'
    id='admin2'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='member'
          jid='wiccarocks@shakespeare.lit'>
      <reason>Not so worthy after all!</reason> 
    </item>
  </query>
</iq>

服务必须 MUST 把该用户从管理员列表移除并接着通知所有者成功了:

例子 187. 服务通知所有者成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='admin2'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

如果该用户在房间里, 服务必须 MUST 接着以这个用户的名义发送更新的出席信息给所有房客, 表明已失去管理员权限,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非"admin"非"owner", 并且 'role' 属性值为根据岗位和房间类型确定的适当的值:

例子 188. 服务通知失去管理员权限

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='wiccarocks@shakespeare.lit'
          role='participant'/>
  </x>
</presence>
 
[ ... ]

如果该用户不在房间, 服务可以 MAY 从房间本身发送一个消息给房间的房客们, 表明已失去所有权,通过包含一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的的 <x/> 元素以及一个 <item/> 子元素,该 <item/> 子元素的 'affiliation' 属性值为非 "admin" .

例子 189. 服务通知失去管理员权限

<message
    from='chat.shakespeare.lit'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='wiccarocks@shakespeare.lit'
          role='none'/>
  </x>
</message>
 
[ ... ]

修改管理员列表

一个房间所有者可能想修改管理员列表. 为此, 所有者首先请求管理员列表,通过向房间请求所有岗位为 'admin'的用户.

例子 190. 所有者请求管理员列表

<iq from='bard@shakespeare.lit/desktopaffiliation
    id='admin3'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='admin'/>
  </query>
</iq>

如果'from'地址的 <user@host> 部分和房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者.

否则, 服务必须 MUST 接着返回管理员列表给所有者; 每个条目必须 MUST 包含 'affiliation' 和 'jid' 属性,对任何正是一名房客(也就是正在房间里)的管理员可以 MAY 包含 'nick' 和 'role' 属性:

例子 191. 服务发送管理员列表给所有者

<iq from='darkcave@chat.shakespeare.lit'
    id='admin3'
    to='bard@shakespeare.lit/globe'
    type='result'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit'
          nick='secondwitch'/>
    <item affiliation='admin'
          jid='hag66@shakespeare.lit'/>
  </query>
</iq>

所有者可以 MAY 接着修改管理员列表. 为此, 所有者必须 MUST 发送修改的条目 (即, 仅 "delta") 给服务; 22 每个条目必须 MUST 包含 'affiliation'属性(通常值为 "admin" 或 "none") 和 'jid' 属性,但不应该 SHOULD NOT 包含 'nick' 属性,不能 MUST NOT 包含 'role' 属性 (它用于管理参与者之类的角色,而不是管理员之类的岗位):

例子 192. 所有者发送修改的管理员列表给服务

<iq from='bard@shakespeare.lit/globe'
    id='admin4'
    to='darkcave@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit'>
    </item>
    <item affiliation='admin'
          jid='hecate@shakespeare.lit'>
    </item>
  </query>
</iq>

只有所有者被允许修改管理员列表. 如果一个非所有者试图察看或修改所有者列表, 服务必须 MUST 拒绝这个请求并返回一个 <forbidden/> 错误给发送者:

例子 193. 服务对于非所有者试图修改管理员列表返回错误

<iq from='darkcave@chat.shakespeare.lit'
    id='admintest'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='admin' 
          jid='hecate@shakespeare.lit'/>
  </query>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

否则, 服务必须 MUST 修改管理员列表并通知所有者成功了:

例子 194. 服务通知所有者成功了

<iq from='darkcave@chat.shakespeare.lit'
    id='admin4'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

服务必须 MUST 也为任何因前述管理员列表修改而导致的岗位变化而发送出席信息通知.

销毁房间

房间所有者必须 MUST 能够销毁一个房间, 特别是如果这个房间不是持久房间的时候. 流程如下:

  1. 房间所有者请求销毁房间, 如果必要的话指出一个原因 reason 和一个备用场地.
  2. 该房间移除所有房客(包含适当的关于备用场地和被移除的原因的信息) 并销毁房间, 即使它被定义为持久房间.

不像前述的, 本文不指定一个MUC服务实现收到一个销毁房间请求之后将会如何做. 例如, 如果房间定义为持久地, 一个实现可以 MAY 选择锁定房间I,这样它不能被重用, 把加入该房间的请求重定向到替代场地, 或邀请当前的参与者到新的房间; 无论如何, 这些行为是可选的 OPTIONAL.

为了销毁一个房间, 房间所有者必须 MUST 发送一个 IQ set 指令到要销毁的房间的地址. 这个 <iq/> 节将包含一个遵循 'http://jabber.org/protocol/muc#owner' 名字空间的 <query/> 元素,它将包含一个 <destroy/> 元素. 替代场地的地址可以 MAY 用这个 <destroy/> 元素的 'jid' 属性来提供. 一个密码保护的替代场地可以 MAY 通过 <destroy/> 元素的 <password/> 子元素的 XML 字符数据来提供. 摧毁房间的原因可以 MAY 通过 <destroy/> 元素的 <reason/> 子元素的 XML 字符数据来提供.

以下例子展示了协议发送和接收的元素:

例子 195. 所有者提交房间摧毁请求

<iq from='crone1@shakespeare.lit/desktop'
    id='begone'
    to='heath@chat.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <destroy jid='darkcave@chat.shakespeare.lit'>
      <reason>Macbeth doth come.</reason>
    </destroy>
  </query>
</iq>

服务负责移除所有房客. 它不应该 SHOULD NOT 广播类型为"unavailable"的出席信息节给所有房客, 只需要发送一个"unavailable"类型的出席信息节给每个房客,这样该用户知道他或她已经从房间移除了. 如果所有者的扩展出席信息指定了一个替代场地的 JID 以及房间销毁的原因, 这个出席信息节必须 MUST 包含那些信息.

例子 196. 服务移除每个房客

<presence
    from='heath@chat.shakespeare.lit/firstwitch'
    to='crone1@shakespeare.lit/desktop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='none'/>
    <destroy jid='darkcave@chat.shakespeare.lit'>
      <reason>Macbeth doth come.</reason>
    </destroy>
  </x>
</presence>
 
<presence
    from='heath@chat.shakespeare.lit/secondwitch'
    to='wiccarocks@shakespeare.lit/laptop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='none'/>
    <destroy jid='darkcave@chat.shakespeare.lit'>
      <reason>Macbeth doth come.</reason>
    </destroy>
  </x>
</presence>
 
<presence
    from='heath@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='none'/>
    <destroy jid='darkcave@chat.shakespeare.lit'>
      <reason>Macbeth doth come.</reason>
    </destroy>
  </x>
</presence>

例子 197. 服务通知所有者成功销毁房间

<iq from='heath@chat.shakespeare.lit'
    id='begone'
    to='crone1@shakespeare.lit/desktop'
    type='result'/>

如果在一个销毁请求中接收到的'from'地址的 <user@host> 和一个房间所有者的纯JID不符, 服务必须 MUST 返回一个 <forbidden/> 错误给发送者:

例子 198. 服务拒绝由非所有者提交的销毁请求

<iq from='heath@chat.shakespeare.lit'
    id='destroytest'
    to='wiccarocks@shakespeare.lit/laptop'
    type='error'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <destroy jid='darkcave@chat.shakespeare.lit'>
      <reason>Macbeth doth come.</reason>
    </destroy>
  </query>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

错误和状态码

错误码

和'http://jabber.org/protocol/muc#user' 名字空间相关的错误码相当简单, 总结于下表之中. 关于传统的错误码到XMPP格式的错误之间的映射的详细信息, 参见 错误条件映射 23; 实现应该 SHOULD 支持传统和XMPP错误处理两者.

表9: http://jabber.org/protocol/muc#user 名字空间的错误码

类型 元素 上下文 目的
401 Error Presence 进入一个房间 通知用户需要密码
403 Error Presence 进入一个房间 通知用户他或她被房间禁止了
404 Error Presence 进入一个房间 通知用户房间不存在
405 Error Presence 进入一个房间 通知用户限制创建房间
406 Error Presence 进入一个房间 通知用户必须使用保留的房间昵称
407 Error Presence 进入一个房间 通知用户他或她不在成员列表中
409 Error Presence 进入一个房间 通知用户他或她的房间昵称正在使用或被别的用户注册了
503 Error Presence 进入一个房间 通知用户已经达到最大用户数

本文不规定和上述错误条件相关的文本字符串(即, XMPP <text/> 元素值).

状态码

多用户聊天的使用一个 <status/> 元素(特指, <status/> 元素的的 'code' 属性 ) 来传达关于用户在一个房间里的状态的信息. 随着时间的推移, 状态码的数量已经增加了很多, 而新的状态码继续被作者申请. 所以, 这些状态码现在记录在一个由XMPP登记处维护的注册表里. 细节可参考本文的 状态码注册表.

注意: 通常, MUC 状态码倾向于沿用RFC 2616 24RFC 1893 25 (1xx 码表示信息, 2xx 码说明情况良好可继续, 3xx 码指定重定向被踢或被禁止的用户, x3x 码指系统状态, x7x 码指安全或策略事务, 等等) 里面的状态码的 "抽象"含义.

注意: 如果今天来定义 MUC 协议, 它将指定一个更有弹性的, XML-友好的 途径而不是硬编码的状态数字; 然而, 现在修改状态汇报系统带来的痛苦将远大于好处, 这是为什么状态码数字保持使用至今. 本文的未来版本可能定义一个更 类XMPP 的途径来表示状态条件, 保留状态码数字但是给它们补充更多的描述性的子元素,就像 RFC 3920 里那样.

国际化事项

RFC 3920 中所定义的, XMPP 实体 (包括 MUC 房间和 MUC 服务) 应该 SHOULD 遵守任何给定的节提供的 'xml:lang' 属性. 然而, 群聊消息的同声翻译超出了本文的范围.

这里定义的状态和错误码允许一个客户端实现展示一个本地化的界面; 然而, 任何给定语言社区的本地化文本字符串的定义超出了本文范围.

尽管这里的很多数据表单字段的标签显示为英文, MUC 客户端应该 SHOULD 把这些字段展示为本地化的文本而不是英文文本.

安全事项

用户验证和授权

本文没有定义或要求比明文密码更安全的房间准入验证或授权方法. 然而, 这些潜在的风险可能使用 RFC 3920 描述的通过使用 TLS 和 SASL 加密通道来减轻.

端到端加密

这里没有定义没有端到端消息或会话加密方法. 用户不应该 SHOULD NOT 相信一个服务能保持通过房间发送的任何文本的安全.

隐私

取决于房间配置, 一个房间可以公开地记录房间里发生的所有讨论. 服务必须 MUST 警告用户该房间是公开记录的,通过在该用户的初始出席信息中返回一个状态码 "170" , 并且如果房间讨论被记录 (用户的客户端也应该 SHOULD 在允许用户进入之前查询房间的配置,以"预先发现"房间是否被记录),该用户的客户端也必须 MUST 警告用户. 如果房间的配置随后修改成允许房间记录(当房间发送状态码 170 时客户端将发现),客户端也必须 MUST 警告用户 . 注意: 房间内的历史和公开房间记录是不同的, 并且很自然的一个房间不能有效地阻止房客独立维护的自有的房间记录, 它可能被公开; 用户应该 SHOULD 谨慎操作并认识到任何房间讨论可能被有效地公开.

匿名

取决于房间配置, 一个房间可以 MAY 暴光每个房客的真实 JID 给其他房客 (如果该房间是非匿名的) 并且将几乎肯定地暴光每个房客的真实 JID 给该房间的所有者和管理员(如果该房间不是全匿名的).服务必须 MUST 警告用户真实 JIDs 在房间被暴光,通过在该用户的初始出席信息中包含状态码 "100" , 并且用户的客户端必须 MUST 警告该用户 (一个用户的客户端应该 SHOULD 也在允许用户进入房间之前查询房间配置以 "预先发现" 是否真实 JIDs 会在房间中暴光). 如果房间配置随后从半匿名或全匿名修改成非匿名(当房间发送状态码 172 时客户端将发现) ,客户端必须 MUST 也警告用户,如果房间的配置随后从全匿名改成半匿名时(当房间发送状态码 173 时客户端将发现),客户端也应该 SHOULD 警告用户.

拒绝服务

公开的 MUC 房间能承受一定数量的攻击, 大部分能减少拒绝服务攻击. 这些攻击包括但不限于:

  1. 向房间里塞进大量的非法房客从而阻止合法用户加入房间.
  2. 发送侮辱性的消息接着在被踢或被禁止之前离开房间; 这些侮辱性的消息包含但不限于,大量消息以阻止参与者正常跟踪会话线索或房间历史, 对参与者的人身攻击 (特别是房间管理员和主持人), 攻击性的文字, 以及垃圾网站链接.
  3. 高频率的制造出席信息变更.
  4. 使用过长的昵称导致无法看到完整的发言.
  5. 辱骂房间管理员或其他房间房客.
  6. 在一个服务里注册很多昵称然后禁止这些昵称的使用.
  7. 模仿别的房客的昵称(例如, 通过在尾部增加一个空格或看起来相似的字符串), 然后以那个房间昵称发送消息用于欺骗房客.

这些攻击可能被减轻不能完全被阻止,通过灵活地使用管理员操作。例如禁止用户, 有管理员权限的自动的房间机器人出席信息, 智能内容过滤的实现, 检查连接的用户的 IP 地址(在分布式的系统里不一定能实现), 应用发言规则到出席信息以及消息, 使用比Resourceprep profile of stringprep更严格的规则匹配房间昵称, 等等. 然而, 经验表明无法完全阻止这类攻击.

其它事项

关于延迟递送符号的列入和流程的更多安全事项参见 XEP-0203.

IANA事项

本文档与互联网编号分配授权机构 26无关。

XMPP登记事项

XMPP登记处 27在它的登记处包含了以下信息.

协议名字空间

XMPP登记处在它的协议名字空间注册表里包含了以下 MUC相关的名字空间:

服务发现种类/类型

一个多用户聊天服务或房间在服务发现里是用 "conference" 种类categary 和 "text" 类型type 来标识的.

服务发现特性

有很多和MUC相关的服务或房间相关的特性可以被"服务发现"来发现. 这里面最基本的是 'http://jabber.org/protocol/muc' 名字空间. 另外, 一个MUC房间应该 SHOULD 提供关于它实现的特定房间特性的信息, 例如密码保护和房间主持.

注册提交

<var>
  <name>http://jabber.org/protocol/muc#register</name>
  <desc>Support for the muc#register FORM_TYPE</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>http://jabber.org/protocol/muc#roomconfig</name>
  <desc>Support for the muc#roomconfig FORM_TYPE</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>http://jabber.org/protocol/muc#roominfo</name>
  <desc>Support for the muc#roominfo FORM_TYPE</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_hidden</name>
  <desc>Hidden room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_membersonly</name>
  <desc>Members-only room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_moderated</name>
  <desc>Moderated room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_nonanonymous</name>
  <desc>Non-anonymous room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_open</name>
  <desc>Open room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_passwordprotected</name>
  <desc>Password-protected room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_persistent</name>
  <desc>Persistent room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_public</name>
  <desc>Public room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_rooms</name>
  <desc>List of MUC rooms (each as a separate item)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_semianonymous</name>
  <desc>Semi-anonymous room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_temporary</name>
  <desc>Temporary room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_unmoderated</name>
  <desc>Unmoderated room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>
<var>
  <name>muc_unsecured</name>
  <desc>Unsecured room in Multi-User Chat (MUC)</desc>
  <doc>XEP-0045</doc>
</var>

知名服务发现节点

知名服务发现节点 'http://jabber.org/protocol/muc#rooms' 允许发现一个用户是哪个房间的房客.

知名服务发现节点 'x-roomuser-item' 允许一个用户从房间外发现自己的已注册房间昵称.

知名服务发现节点 'http://jabber.org/protocol/muc#traffic' 允许发现通过一个房间能发送哪些名字空间的通讯(参见本文允许的 允许的通讯章节).

字段标准化

数据表单的字段标准化 28 定义了用于遵循特定名字空间的数据表单的字段标准化的过程. 在 MUC 里面, 使用了四种这类表单: 房间注册 ( "muc#register" FORM_TYPE), 请求发言权和批准请求 ("muc#request"), 房间配置 ("muc#roomconfig"), 以及用于房间信息的服务发现扩展 ("muc#roominfo"). 这些保留的字段定义如下.

muc#register FORM_TYPE

注册处提交

<form_type>
  <name>http://jabber.org/protocol/muc#register</name>
  <doc>XEP-0045</doc>
  <desc>
    Forms enabling user registration with a
    Multi-User Chat (MUC) room or admin approval
    of user registration requests.
  </desc>
  <field 
     var='muc#register_allow'
     type='boolean'
     label='Allow this person to register with the room?'/>
  <field
      var='muc#register_email'
      type='text-single'
      label='Email Address'/>
  <field
      var='muc#register_faqentry'
      type='text-multi'
      label='FAQ Entry'/>
  <field
      var='muc#register_first'
      type='text-single'
      label='Given Name'/>
  <field
      var='muc#register_last'
      type='text-single'
      label='Family Name'/>
  <field
      var='muc#register_roomnick'
      type='text-single'
      label='Desired Nickname'/>
  <field
      var='muc#register_url'
      type='text-single'
      label='Your URL'/>
</form_type>

muc#request FORM_TYPE

注册处提交

<form_type>
  <name>http://jabber.org/protocol/muc#request</name>
  <doc>XEP-0045</doc>
  <desc>
    Forms enabling voice requests in a 
    Multi-User Chat (MUC) room or admin
    approval of such requests.
  </desc>
  <field var='muc#role'
         type='text-single'
         label='Requested role'/>
  <field var='muc#jid'
         type='text-single'
         label='User ID'/>
  <field var='muc#roomnick'
         type='text-single'
         label='Room Nickname'/>
  <field var='muc#request_allow'
         type='boolean'
         label='Whether to grant voice'/>
</form_type>

muc#roomconfig FORM_TYPE

注册处提交

<form_type>
  <name>http://jabber.org/protocol/muc#roomconfig</name>
  <doc>XEP-0045</doc>
  <desc>
    Forms enabling creation and configuration of
    a Multi-User Chat (MUC) room.
  </desc>
  <field
      var='muc#roomconfig_allowinvites'
      type='boolean'
      label='Whether to Allow Occupants to Invite Others'/>
  <field
      var='muc#roomconfig_changesubject'
      type='boolean'
      label='Whether to Allow Occupants to Change Subject'/>
  <field
      var='muc#roomconfig_enablelogging'
      type='boolean'
      label='Whether to Enable Public Logging of Room Conversations'/>
  <field
      var='muc#roomconfig_getmemberlist'
      type='list-multi'
      label='Roles and Affiliations that May Retrieve Member List'/>
  <field
      var='muc#roomconfig_lang'
      type='text-single'
      label='Natural Language for Room Discussions'/>
  <field
      var='muc#roomconfig_pubsub'
      type='text-single'
      label='XMPP URI of Associated Publish-Subcribe Node'/>
  <field
      var='muc#roomconfig_maxusers'
      type='list-single'
      label='Maximum Number of Room Occupants'/>
  <field
      var='muc#roomconfig_membersonly'
      type='boolean'
      label='Whether an Make Room Members-Only'/>
  <field
      var='muc#roomconfig_moderatedroom'
      type='boolean'
      label='Whether to Make Room Moderated'/>
  <field
      var='muc#roomconfig_passwordprotectedroom'
      type='boolean'
      label='Whether a Password is Required to Enter'/>
  <field
      var='muc#roomconfig_persistentroom'
      type='boolean'
      label='Whether to Make Room Persistent'/>
  <field
      var='muc#roomconfig_presencebroadcast'
      type='list-multi'
      label='Roles for which Presence is Broadcast'/>
  <field
      var='muc#roomconfig_publicroom'
      type='boolean'
      label='Whether to Allow Public Searching for Room'/>
  <field
      var='muc#roomconfig_roomadmins'
      type='jid-multi'
      label='Full List of Room Admins'/>
  <field
      var='muc#roomconfig_roomdesc'
      type='text-single'
      label='Short Description of Room'/>
  <field
      var='muc#roomconfig_roomname'
      type='text-single'
      label='Natural-Language Room Name'/>
  <field
      var='muc#roomconfig_roomowners'
      type='jid-multi'
      label='Full List of Room Owners'/>
  <field
      var='muc#roomconfig_roomsecret'
      type='text-private'
      label='The Room Password'/>
  <field
      var='muc#roomconfig_whois'
      type='list-single'
      label='Affiliations that May Discover Real JIDs of Occupants'/>
</form_type>

muc#roominfo FORM_TYPE

注册处提交

<form_type>
  <name>http://jabber.org/protocol/muc#roominfo</name>
  <doc>XEP-0045</doc>
  <desc>
    Forms enabling the communication of extended service discovery
    information about a Multi-User Chat (MUC) room.
  </desc>
  <field
      var='muc#roominfo_contactjid'
      type='jid-multi'
      label='Contact Addresses (normally, room owner or owners)'/>
  <field
      var='muc#roominfo_description'
      type='text-single'
      label='Short Description of Room'/>
  <field
      var='muc#roominfo_lang'
      type='text-single'
      label='Natural Language for Room Discussions'/>
  <field
      var='muc#roominfo_ldapgroup'
      type='text-single'
      label='An associated LDAP group that defines room membership; 
             this should be an LDAP Distinguished Name according to an
             implementation-specific or deployment-specific definition
             of a group.'/>
  <field
      var='muc#roominfo_logs'
      type='text-single'
      label='URL for Archived Discussion Logs'/>
  <field
      var='muc#roominfo_occupants'
      type='text-single'
      label='Current Number of Occupants in Room'/>
  <field
      var='muc#roominfo_subject'
      type='text-single'
      label='Current Subject or Discussion Topic in Room'/>
  <field
      var='muc#roominfo_subjectmod'
      type='boolean'
      label='The room subject can be modified by participants'/>
</form_type>

状态码登记处

过程

XMPP注册员为遵循 'http://jabber.org/protocol/muc#user' 名字空间的<status/> 元素的 'code' 属性维护注册表中的值 .

为了提交新值给这个注册表, 注册人将按以下格式定义一个XML段并把它包含在相关的XMPP扩展协议中,或者发到<registrar@xmpp.org>:

<statuscode>
  <number>the three-digit code number</number>
  <stanza>the stanza type of which it is a child (message or presence)</stanza>
  <context>the use case or situation in which the status is used</context>
  <purpose>a natural-language description of the meaning</purpose>
  <child>the descriptive child element (reserved for future use)</child>
</statuscode>

注册人可一次注册多个状态码,每个状态码包含在独立的<statuscode/>元素中。

初始提交

作为本文的一部分, 以下状态码已被注册了:

<statuscode>
  <number>100</number>
  <stanza>message or presence</stanza>
  <context>Entering a room</context>
  <purpose>Inform user that any occupant is allowed to see the user's full JID</purpose>
</statuscode>
<statuscode>
  <number>101</number>
  <stanza>message (out of band)</stanza>
  <context>Affiliation change</context>
  <purpose>Inform user that his or her affiliation changed while not in the room</purpose>
</statuscode>
<statuscode>
  <number>102</number>
  <stanza>message</stanza>
  <context>Configuration change</context>
  <purpose>Inform occupants that room now shows unavailable members</purpose>
</statuscode>
<statuscode>
  <number>103</number>
  <stanza>message</stanza>
  <context>Configuration change</context>
  <purpose>Inform occupants that room now does not show unavailable members</purpose>
</statuscode>
<statuscode>
  <number>104</number>
  <stanza>message</stanza>
  <context>Configuration change</context>
  <purpose>
    Inform occupants that a non-privacy-related room configuration change has occurred
  </purpose>
</statuscode>
<statuscode>
  <number>110</number>
  <stanza>presence</stanza>
  <context>Any room presence</context>
  <purpose>Inform user that presence refers to one of its own room occupants</purpose>
</statuscode>
<statuscode>
  <number>170</number>
  <stanza>message or initial presence</stanza>
  <context>Configuration change</context>
  <purpose>Inform occupants that room logging is now enabled</purpose>
</statuscode>
<statuscode>
  <number>171</number>
  <stanza>message</stanza>
  <context>Configuration change</context>
  <purpose>Inform occupants that room logging is now disabled</purpose>
</statuscode>
<statuscode>
  <number>172</number>
  <stanza>message</stanza>
  <context>Configuration change</context>
  <purpose>Inform occupants that the room is now non-anonymous</purpose>
</statuscode>
<statuscode>
  <number>173</number>
  <stanza>message</stanza>
  <context>Configuration change</context>
  <purpose>Inform occupants that the room is now semi-anonymous</purpose>
</statuscode>
<statuscode>
  <number>174</number>
  <stanza>message</stanza>
  <context>Configuration change</context>
  <purpose>Inform occupants that the room is now fully-anonymous</purpose>
</statuscode>
<statuscode>
  <number>201</number>
  <stanza>presence</stanza>
  <context>Entering a room</context>
  <purpose>Inform user that a new room has been created</purpose>
</statuscode>
<statuscode>
  <number>210</number>
  <stanza>presence</stanza>
  <context>Entering a room</context>
  <purpose>Inform user that service has assigned or modified occupant's roomnick</purpose>
</statuscode>
<statuscode>
  <number>301</number>
  <stanza>presence</stanza>
  <context>Removal from room</context>
  <purpose>Inform user that he or she has been banned from the room</purpose>
</statuscode>
<statuscode>
  <number>303</number>
  <stanza>presence</stanza>
  <context>Exiting a room</context>
  <purpose>Inform all occupants of new room nickname</purpose>
</statuscode>
<statuscode>
  <number>307</number>
  <stanza>presence</stanza>
  <context>Removal from room</context>
  <purpose>Inform user that he or she has been kicked from the room</purpose>
</statuscode>
<statuscode>
  <number>321</number>
  <stanza>presence</stanza>
  <context>Removal from room</context>
  <purpose>Inform user that he or she is being removed from the room 
    because of an affiliation change</purpose>
</statuscode>
<statuscode>
  <number>322</number>
  <stanza>presence</stanza>
  <context>Removal from room</context>
  <purpose>Inform user that he or she is being removed from the room 
    because the room has been changed to members-only and the user 
    is not a member</purpose>
</statuscode>
<statuscode>
  <number>332</number>
  <stanza>presence</stanza>
  <context>Removal from room</context>
  <purpose>Inform user that he or she is being removed from the room 
    because of a system shutdown</purpose>
</statuscode>

URI查询类型

作为由XMPP URI Query Components 29授权的机构,XMPP注册员维护着一个用于 XMPP URIs 的查询和键-值对的注册表(见<http://www.xmpp.org/registrar/querytypes.html>)。

join

"join" 查询类型被注册为一个 MUC相关的动作, 伴随一个可选的键 "password".

例子 199. Join动作: IRI/URI

xmpp:darkcave@chat.shakespeare.lit?join

应用必须 MUST 要么展示一个界面允许用户提供一个房间昵称,要么基于配置好的选项或昵称发现来获取这个房间昵称.

例子 200. Join动作: 结果节

<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

join 动作可以 MAY 为这房间包含一个密码. 自然的, 对一个包含了房间密码的 URI 的访问必须 MUST 得到适当的控制.

例子 201. Join动作包含密码: IRI/URI

xmpp:darkcave@chat.shakespeare.lit?join;password=cauldronburn

例子 202. Join动作包含密码: 结果节

<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <password>cauldronburn</password>
  </x>
</presence>

以下提交注册 "join" 查询类型.

<querytype>
  <name>join</name>
  <proto>http://jabber.org/protocol/muc</proto>
  <desc>enables joining a multi-user chat room</desc>
  <doc>XEP-0045</doc>
  <keys>
    <key>
      <name>password</name>
      <desc>the password required to enter a multi-user chat room</desc>
    </key>
  </keys>
</querytype>

invite

"invite" 查询类型被注册为一个 MUC相关的动作, 伴随一个可选的键 "jid".

例子 203. Invite动作: IRI/URI

xmpp:darkcave@chat.shakespeare.lit?invite;jid=hecate@shakespeare.lit

如果加入中的用户还未在房间里, 应用必须 MUST 发送两个节: 第一个加入房间,第二个邀请另一个人. 如果加入中的用户已经在房间里, 应用将只发送邀请节.

例子 204. Invite动作: 结果节(s)

<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>
 
<message to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='hecate@shakespeare.lit'/>
  </x>
</message>

URI 可以包含多个邀请:

例子 205. Invite动作包含多个邀请: IRI/URI

xmpp:darkcave@chat.shakespeare.lit?invite;jid=hecate@shakespeare.lit;jid=bard@shakespeare.lit

例子 206. Invite动作包含多个邀请: 结果节

<message to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='hecate@shakespeare.lit'/>
    <invite to='bard@shakespeare.lit'/>
  </x>
</message>

URI 也可以包含一个密码:

例子 207. Invite动作包含密码: IRI/URI

xmpp:darkcave@chat.shakespeare.lit?invite;jid=hecate@shakespeare.lit;password=cauldronburn

如果加入中的用户还未在房间里, 应用必须 MUST 发送两个节: 第一个加入房间,第二个邀请另一个人. 如果加入中的用户已经在房间里, 应用将只发送邀请节.

例子 208. Invite动作包含密码: 结果节(s)

<presence to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>
 
<message to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='hecate@shakespeare.lit'/>
    <password>cauldronburn</password>
  </x>
</message>

以下提交注册 "invite" 查询类型.

<querytype>
  <name>invite</name>
  <proto>http://jabber.org/protocol/muc</proto>
  <desc>enables simultaneously joining a groupchat room and inviting others</desc>
  <doc>XEP-0045</doc>
  <keys>
    <key>
      <name>jid</name>
      <desc>the Jabber ID of the invitee</desc>
    </key>
    <key>
      <name>password</name>
      <desc>the password required to enter a multi-user chat room</desc>
    </key>
  </keys>
</querytype>

商业规则

Addresses

为了提供关于从房间JIDs抓获的地址的一致性, Room IDs 必须 MUST 遵循 Stringprep 的 Nodeprep 规范并且 Room Nicknames 必须 MUST 符合 Stringprep (这些都定义在 RFC 3920) 的 Resourceprep 规范. 尽管在 RFC 3920 中没有显式的说明 , 一个 Room JID 的 Room ID (node) 和 Room Nickname (resource) 部分都必须 MUST 长度不为零. 另外, 一个 MUC 服务不能 MUST NOT 允许空的或不可见的房间昵称 Room Nicknames (即, 房间昵称Room Nicknames 只包含一个或多个空格).

取决于服务实现,是否更多地限制房间昵称 (例如, 通过应用情景例程, stringprep的Nodeprep规范, 或其他限制).

Message

  1. 如果一个房客想发送一个消息给所有其他房客, MUC 客户端必须 MUST 把 'type' 属性值设为 "groupchat". 服务可以 MAY 忽略不正确的消息类型, 或用 <bad-request/> 错误弹回.
  2. 如果一个MUC服务从一个角色为"none"的Jabber用户收到一个发送给该房间的消息或给某个房客的消息, 服务不能 MUST NOT 递送这个消息并应该 SHOULD 返回给这个消息给发送者并伴随一个 <forbidden/> 错误.
  3. 如果一个MUC服务 接收到一个发送给不存在的或尚未解锁的房间的消息, 服务应该 SHOULD 返回这个消息给发送者并伴随一个 <item-not-found/> 错误.
  4. 一个MUC服务应该 SHOULD 不做修改地传递扩展的消息 (例如, 一个消息主体的 XHTML 版本) 给房客; 然而, 一个 MUC 服务可以 MAY 不允许消息的特定扩展(参见本文的允许的通讯章节).
  5. 一个MUC客户端可以 MAY 生成扩展以满足 消息事件 30聊天状态通知 31 规范; 然而, 一个 MUC 服务可以 MAY 不允许这些扩展 (参见本文的允许的通讯章节).

Presence

  1. 一个房间必须 MUST 安静地忽略从一个角色为"none"的用户发来的不可用出席信息信息.
  2. 只有MUC服务自身应该 SHOULD 生成关于角色,岗位,全JIDs或遵循 'http://jabber.org/protocol/muc#user' 名字空间的状态码的扩展的出席信息 (基于服务所知道的关于房客的信息, 例如, 角色, 或由一个主持人或房间管理员的动作所产生的结果). 一个客户端不应该 SHOULD NOT 推定生成这类信息. 如果一个 MUC 服务从一个房客接收到这类扩展的出席信息, 它不能 MUST NOT 反射它给其他房客们. (一个客户端可以 MAY 为了提供一个密码而生成遵循 'http://jabber.org/protocol/muc#user' 名字空间的扩展的出席信息, 但自然的这是不反射给其他房客的.)
  3. 一个MUC服务应该 SHOULD 允许所有其他出席信息通过, 尽管它可以 MAY 选择阻塞扩展的出席信息; 参见本文的 允许的通讯章节.
  4. 为了适当地通知房客角色和岗位, 并使之更易于Jabber客户端跟踪房间里所有用户的当前状态, MUC服务实现必须 MUST 在所有出席信息节里提供关于角色和岗位的扩展的出席信息, 包括一个用户因为任何原因退出该房间时被发送的类型为"unavailable"的出席信息节.
  5. 如果一个权限被撤销, 服务必须 MUST 通知这件事,通过发送一个遵循 'http://jabber.org/protocol/muc#user' 名字空间的 <x/> 元素并包含一个 <item/> 子元素,该<item/> 子元素的 'role' 和/或 'affiliation' 属性值的设定指明是去了有关的权限. 所有将来的为这个房客发出的出席信息节必须 MUST 包含这个更新的角色和岗位, 直到除非它们再次改变.
  6. 一个MUC服务必须 MUST 发送扩展的出席信息给一个客户端,即使客户端在进入该房间时没有发送一个空的遵循 'http://jabber.org/protocol/muc' 名字空间的 <x/> 元素 ; 自然的, 一个客户端必须 MUST 忽略这类信息,如果它不懂得它的话(根据 RFC 3920).
  7. 在 muc#user 名字空间中被发送的关于角色和岗位的扩展的出席信息必须 MUST 包含全JID (不是纯JID) 作为 'jid' 属性的值.
  8. 如果想要,一个客户端可以 MAY 发送一个客户化的退出消息 (就像 IRC 频道里经常出现的那样) ,通过在退出时被发送的"unavailable"类型的出席信息节里包含一个 <status/> 元素.

IQ

  1. MUC被设计用于分享消息和出席信息, 而不是 IQs. 一个被发送的到房间本身JID的 IQ 由房间本身来处理并且不反射给所有房客.
  2. 如果一个房客想在一个非匿名房间发送一个 IQ 节给其他用户, 发送者应该 SHOULD 直接发送请求给接收者的纯JID或全JID, 而不是试图通过房间发送请求(即, 通过接收者的房间JID).
  3. 如果一个房客想在一个半匿名房间发送一个 IQ 节给其他用户, 发送者能直接发送这个节给接受者的房间JID并且服务可以 MAY 转发这个节给接收者的真实JID. 然而, 任何时候一个MUC服务不能 MUST NOT 泄露这个发送者的真实JID给接收者, 也不能泄露接收者的真实JID给发送者.
  4. 一个MUC客户端必须 MUST 在IQ set 中的遵循 'http://jabber.org/protocol/muc#admin' <item/> 子元素中只发送 'affiliation' 属性或 'role' 属性; 如果一个主持人, 管理员, 或所有者试图在相同的IQ set中修改相同条目的岗位或角色, 服务必须 MUST 返回一个 <bad-request/> 错误给发送者. 无论如何, 一个MUC服务可以 MAY 基于一个岗位的变更来修改一个角色,从而可以 MAY 发送出席信息更新,同时包含一个修改的角色和一个修改的岗位.
  5. 在关于角色的 IQ sets中, 一个MUC客户端必须 MUST 只包含 'nick' 属性; 在关于角色的 IQ results中, 一个 MUC 服务必须 MUST 包含 'nick', 'role', 'affiliation', 和'jid' 属性 (值为后来设置的用户的全JID).
  6. 在关于岗位的 IQ sets中, 一个MUC客户端必须 MUST 只包含 'jid' 属性(值为纯JID); 在关于岗位的 IQ results中, 一个MUC服务不能 MUST NOT 包含 'role' 属性, 必须MUST 包含 'affiliation' 属性和 'jid' 属性 (值为纯JID), 并且应该 SHOULD 包含 'nick' 属性 (除非岗位为 "outcast", 以为被排斥者不应该 SHOULD NOT 有保留的房间昵称).

实现注意事项

以下方针有助于客户端和组件开发者建立 MUC 实现.

服务端

  1. 在处理一个被主持的房间里游客发送的消息时, 一个MUC服务可以 MAY 通过一个主持人让每个消息排队等待批准并且可以 MAY 通知发送者消息正在等待批准; 然而, 这一行为是可选的 OPTIONAL, 并且一个消息批准协议的定义 (例如, 使用XEP-0004定义的数据表单) 超出了本文的范围.
  2. 对于一个 MUC 服务来说,在特定事件发生时提供房间内的消息是很常见的, 例如当标题变更时, 当一个房客加入或退出时, 或当一个房间被销毁时. 这类消息完全是可选的 OPTIONAL 并且留给实现或布署来决定, 但如果使用了,则必须 MUST 是从房间JID本身(<room@service>) 而不是从一个特定的房客(<room@service/nick>)发送的类型为 "groupchat" 类型的消息. 无论如何, 通常接收的客户端倾向于基于房间的事件以及MUC提供的特定状态码来生成类似的消息(例如, 用户加入或退出) ; 这将帮助确保这类消息的正确的本地化.
  3. 出于礼貌, 一个MUC服务可以 MAY 发送一个房间外的 <message/> 给一个被踢的或被禁止的房客, 并且可以 MAY 广播一个房间内的 <message/> 给所有剩余的房客通知他们该房客已被该房间踢出或禁止. 无论如何, 这类消息是可选的 OPTIONAL, 并且事实上是多余的,因为接收的客户端生成这类消息所必需的信息已经通过MUC服务发送的出席信息节(特别是状态码)得到了.
  4. 出于礼貌, 如果一个用户的岗位变更了而该用户不在房间里,一个MUC服务可以MAY发送一个房间外的 <message/> ; 这消息应该 SHOULD 被从房间发送给该用户的纯JID, 可以 MAY 包含一个 <body/> 元素描述岗位变更, 并且必须 MUST 包含一个状态码 101.
  5. 没有需求要一个MUC服务将为旧的"groupchat 1.0"用户提供特别的治疗, 例如包含等价于扩展的遵循 'http://jabber.org/protocol/muc#user' 名字空间的出席信息的消息.
  6. 房间类型可以 MAY 被配置成任何组合. 一个MUC服务可以 MAY 支持或允许任何想要的房间类型或它们的组合.
  7. 一个MUC服务可以 MAY 限制在初始配置完成之后配置选项展示给一个所有者的次数, 例如因为特定的选项除非重启服务无法生效.
  8. 一个MUC服务可以 MAY 提供一个接口给房间创建和配置(例如, 以一个特定的Jabber表单或一个网页), 这样表面上房间所有者是一个应用而不是一个自然人用户.
  9. 一个MUC服务可以 MAY 选择让一个特定的房间内资源提供接口给管理功能 (例如, 一个 "user" 名的机器人 "ChatBot"), 房客们可以和它直接互动, 从而允许管理员在一个私有消息里键入命令参数 '/command parameter' 给那个机器人 "user". 显然这种服务要求服务在房间创建时添加一个 'ChatBot' 用户到房间, 并且阻止任何房客在该房间使用房间昵称 'ChatBot' . 这可能在一些实现或布署中比较难以保证. 任何情况下, 任何这类接口是可选的 OPTIONAL.
  10. 如果服务接收到它之前发送给该用户的节相关的递送类错误,一个MUC服务应该 SHOULD 移除一个用户; 递送相关的错误即 <gone/>, <item-not-found/>, <recipient-unavailable/>, <redirect/>, <remote-server-not-found/>, 和 <remote-server-timeout/>.
  11. 一个MUC服务可以 MAY 选择在反射出席信息变更给一个房间的房客们之前,抛弃附加在<presence/> 节上的扩展的出席信息. 也就是, 一个实现可以 MAY 选择只反射该出席信息节的 <show/>, <status/>, 和 <priority/> 子元素,如 'jabber:client' 名字空间描述的 XML 架构之中, 结果导致那个在扩展的名字空间中的出席信息变更 "changes" (例如, gabber:x:music:info) 不被传递给房客. 如果一个服务禁止特定的扩展名字空间, 它应该 SHOULD 在本文 允许的通讯章节描述的知名的服务发现节点 'http://jabber.org/protocol/muc#traffic' 提供一个允许的通讯的描述.
  12. 一个MUC服务可以 MAY 在反射消息给一个房间的房客之前选择抛弃附加在 <message/> 节的扩展信息. 一个这类扩展信息的例子是轻量级文本标记,定义于 XHTML-IM [XEP-0045#附录G:备注|32]]. 如果一个服务禁止特定的扩展名字空间, 它应该 SHOULD 在本文 允许的通讯章节描述的知名的服务发现节点 'http://jabber.org/protocol/muc#traffic' 提供一个允许的通讯的描述.
  13. 一个MUC服务可以 MAY 选择锁定 "lock down" 房间昵称 (例如, 硬编码房间昵称给该房客的纯JID). 如果这么干, 该服务必须 MUST 把被锁定的昵称看作一个保留的房间昵称并且必须 MUST 支持本文发现保留的房间昵称章节定义的协议.

允许的通讯

大家知道, 一个服务 (更准确地说, 一个正确配置的房间)可以 MAY 抛弃一些或所有的扩展的附加在从发送者通过房间反射给所有房客的 <message/> 和 <presence/> 节的名字空间. 如果房间这么干, 它应该 SHOULD 允许发送者通过发送 disco#info 查询知名的服务发现节点 'http://jabber.org/protocol/muc#traffic' 来发现允许的扩展的列表, 在结果中返回支持的名字空间每个用一个 <feature/> 元素表示. 如果该房间不允许任何扩展的名字空间, 它必须 MUST 如 XEP-0030 所述返回一个空的 query . 如果该房间不支持 "#traffic" 节点, 它必须 MUST 返回一个 <feature-not-implemented/> 错误应答给查询发送到 'http://jabber.org/protocol/muc#traffic' 节点的查询.

以下例子展示一个只允许 'http://jabber.org/protocol/xhtml-im' 和 'http://jabber.org/protocol/rosterx' 名字空间的房间, 而不包括其他的名字空间.

例子 209. 用户查询服务关于允许的名字空间

<iq from='wiccarocks@shakespeare.lit/laptop'
    to='heath@chat.shakespeare.lit'
    id='allow1'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='http://jabber.org/protocol/muc#traffic'/>
</iq>

例子 210. 服务返回允许的名字空间

<iq from='heath@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    id='allow1'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='http://jabber.org/protocol/muc#traffic'>
    <feature var='http://jabber.org/protocol/xhtml-im'/>
    <feature var='http://jabber.org/protocol/rosterx'/>
  </query>
</iq>

如果一个服务不抛弃任何名字空间或不实现这个特性, 它必须 MUST 返回一个 <service-unavailable/> 错误:

例子 211. 服务返回服务不可用错误

<iq from='heath@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    id='allow1'
    type='error'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='http://jabber.org/protocol/muc#traffic'/>
  <error type='cancel'>
    <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

客户端

  1. Jabber客户端可以 MAY 展示房间角色,通过在一个房间名册里为每个角色显示特定的群. 这将使房客清楚图形化的知道哪个房客是主持人, 参与者, 和游客. 无论如何, 这样一个展示是可选的 OPTIONAL.
  2. Jabber客户端可以 MAY 实现多样化的界面以提供快捷方式 "shortcuts" 给功能,例如修改某人昵称, 踢人或禁止用户, 发现一个房客的全JID, 或修改主题. 一个选项包含了类IRC 的命令例如 '/nick', '/kick', '/ban', 和 '/whois'; 另一个是使用户能用鼠标右击房间名册里的项目. 所有这些界面形式是可选的 OPTIONAL. 然而, 为方便起见, 下面提供了一个 IRC 命令到 MUC 协议的映射.

IRC命令映射

IRC 客户端使用大量常用的快捷方式 "shortcut" 命令,以一个斜杠开始, 例如 '/nick' and '/ban'. 下表提供一个 类IRC 命令到 MUC 协议的映射, 用于希望支持类似功能的 Jabber 客户端.

表10: IRC命令映射

命令 功能 MUC协议
/ban <roomnick> [comment] 在房间里以房间昵称禁止用户(客户端翻译房间昵称为纯JID)
<iq id='someid'
    to='room@service'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item affiliation='outcast'
          jid='bare-jid-of-user'>
      <reason>comment</reason>
    </item>
  </query>
</iq>
/invite <jid> [comment] 以JID邀请用户到此房间
<message to='room@service'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='jid'>
      <reason>comment</reason>
    </invite>
  </x>
</message>
/join <roomname> [pass] 在服务里加入房间(房间昵称同本房间内的昵称)
<presence to='room@service/nick'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <password>pass</password>
  </x>
</presence>
/kick <roomnick> [comment] 以房间昵称从房间里踢人
<iq id='someid'
    to='room@service'
    type='set'>
  <query xmlns='http://jabber.org/protocol/muc#admin'>
    <item nick='roomnick' role='none'>
      <reason>comment</reason>
    </item>
  </query>
</iq>
/msg <roomnick> <foo> 发送私有消息"foo"给房间昵称
<message to='room@service/nick' type='chat'>
  <body>foo</body>
</message>
/nick <newnick> 变更在此房间内的昵称为"newnick"
<presence to='room@service/newnick'/>
/part [comment] 退出本房间(一些 IRC 客户端也支持 /leave)
<presence to='room@service/nick'
          type='unavailable'>
  <status>comment</status>
</presence>
/topic <foo> 变更此房间主题为"foo"
<message to='room@service' type='groupchat'>
  <subject>foo</subject>
</message>


注意: 因为 MUC 房间昵称遵循stringprep的Resourceprep脚本, 它们被允许包含一个空格字符, 而 IRC 昵称不允许. 尽管一个给定的客户端可以 MAY 支持引用字符串用于这个目的 (导致命令类似 '/ban "king lear" insanity is no defense'), 最常见的引用字符(类似 " 和 ') 也是被Resourceprep允许的 , 从而导致增加了复杂性和包含空格和引号的房间昵称中引号的潜在问题. 所以不建议 NOT RECOMMENDED Jabber客户端支持包含了空格符的房间昵称的类IRC的快捷方式命令.

注意: 很多Jabber客户端也实现了 '/me ' 命令,如 The /me Command 33 所述. 这个命令不会导致任何 MUC 或 IRC 协议的动作所以不显式在上表中.

XML架构

http://jabber.org/protocol/muc

<?xml version='1.0' encoding='UTF-8'?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/muc'
    xmlns='http://jabber.org/protocol/muc'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:element name='x'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='history' minOccurs='0'/>
        <xs:element name='password' type='xs:string' minOccurs='0'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='history'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='maxchars' type='xs:int' use='optional'/>
          <xs:attribute name='maxstanzas' type='xs:int' use='optional'/>
          <xs:attribute name='seconds' type='xs:int' use='optional'/>
          <xs:attribute name='since' type='xs:dateTime' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
 
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
 
</xs:schema>

http://jabber.org/protocol/muc#user

<?xml version='1.0' encoding='UTF-8'?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/muc#user'
    xmlns='http://jabber.org/protocol/muc#user'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:element name='x'>
    <xs:complexType>
      <xs:choice minOccurs='0' maxOccurs='unbounded'>
        <xs:element ref='decline' minOccurs='0'/>
        <xs:element ref='destroy' minOccurs='0'/>
        <xs:element ref='invite' minOccurs='0' maxOccurs='unbounded'/>
        <xs:element ref='item' minOccurs='0'/>
        <xs:element name='password' type='xs:string' minOccurs='0'/>
        <xs:element ref='status' minOccurs='0' maxOccurs='unbounded'/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='decline'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='reason' minOccurs='0'/>
      </xs:sequence>
      <xs:attribute name='from' type='xs:string' use='optional'/>
      <xs:attribute name='to' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='destroy'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='reason' minOccurs='0'/>
      </xs:sequence>
      <xs:attribute name='jid' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='invite'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='reason' minOccurs='0'/>
      </xs:sequence>
      <xs:attribute name='from' type='xs:string' use='optional'/>
      <xs:attribute name='to' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='item'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='actor' minOccurs='0'/>
        <xs:element ref='reason' minOccurs='0'/>
        <xs:element ref='continue' minOccurs='0'/>
      </xs:sequence>
      <xs:attribute name='affiliation' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='admin'/>
            <xs:enumeration value='member'/>
            <xs:enumeration value='none'/>
            <xs:enumeration value='outcast'/>
            <xs:enumeration value='owner'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='jid' type='xs:string' use='optional'/>
      <xs:attribute name='nick' type='xs:string' use='optional'/>
      <xs:attribute name='role' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='moderator'/>
            <xs:enumeration value='none'/>
            <xs:enumeration value='participant'/>
            <xs:enumeration value='visitor'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='actor'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='jid' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='continue'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='thread' type='xs:string' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='status'>
    <xs:complexType>
      <xs:attribute name='code' use='required'>
        <xs:simpleType>
          <xs:restriction base='xs:int'>
            <xs:minInclusive value='100'/>
            <xs:maxInclusive value='999'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='reason' type='xs:string'/>
 
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
 
</xs:schema>

http://jabber.org/protocol/muc#admin

<?xml version='1.0' encoding='UTF-8'?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/muc#admin'
    xmlns='http://jabber.org/protocol/muc#admin'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:element name='query'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='item' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='item'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='actor' minOccurs='0'/>
        <xs:element ref='reason' minOccurs='0'/>
      </xs:sequence>
      <xs:attribute name='affiliation' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='admin'/>
            <xs:enumeration value='member'/>
            <xs:enumeration value='none'/>
            <xs:enumeration value='outcast'/>
            <xs:enumeration value='owner'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='jid' type='xs:string' use='optional'/>
      <xs:attribute name='nick' type='xs:string' use='optional'/>
      <xs:attribute name='role' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='moderator'/>
            <xs:enumeration value='none'/>
            <xs:enumeration value='participant'/>
            <xs:enumeration value='visitor'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='actor'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='jid' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='reason' type='xs:string'/>
 
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
 
</xs:schema>

http://jabber.org/protocol/muc#owner

<?xml version='1.0' encoding='UTF-8'?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/muc#owner'
    xmlns='http://jabber.org/protocol/muc#owner'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:import 
      namespace='jabber:x:data'
      schemaLocation='http://www.xmpp.org/schemas/x-data.xsd'/>
 
  <xs:element name='query'>
    <xs:complexType>
      <xs:choice xmlns:xdata='jabber:x:data' minOccurs='0'>
        <xs:element ref='xdata:x'/>
        <xs:element ref='destroy'/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='destroy'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name='password' type='xs:string' minOccurs='0'/>
        <xs:element name='reason' type='xs:string' minOccurs='0'/>
      </xs:sequence>
      <xs:attribute name='jid' 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:schema>

http://jabber.org/protocol/muc#unique

<?xml version='1.0' encoding='UTF-8'?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/muc#unique'
    xmlns='http://jabber.org/protocol/muc#unique'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0045: http://www.xmpp.org/extensions/xep-0045.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:element name='unique' type='xs:string'/>
 
</xs:schema>

鸣谢

作者感谢以下个人,为他们很多对于本协议草案的帮助性的评论: David Sutton, Peter Millard, Joe Hildebrand, Craig Kaes, Alexey Shchepin, David Waite, Jean-Louis Seguineau, Jacek Konieczny, Gaston Dombiak, 以及其他在 jdev@conference.jabber.org 会议室和在 Standards 邮件列表里的人.

附录

附录A:文档信息

系列:XEP

序号:0045

发布者:XMPP标准基金会

状态:草案

类型:标准跟踪

版本:1.24

最后更新:2008-07-16

批准机构:XMPP理事会

依赖标准:XMPP Core, XMPP IM, XEP-0004, XEP-0030, XEP-0068, XEP-0082, XEP-0128

替代标准:无

被替代标准:无

缩略名:muc

muc名字空间的XML方案: <http://www.xmpp.org/schemas/muc.xsd>

muc#admin名字空间的XML方案: <http://www.xmpp.org/schemas/muc-admin.xsd>

muc#owner名字空间的XML方案: <http://www.xmpp.org/schemas/muc-owner.xsd>

muc#unique名字空间的XML方案: <http://www.xmpp.org/schemas/muc-unique.xsd>

muc#user名字空间的XML方案: <http://www.xmpp.org/schemas/muc-user.xsd>

注册表: <http://www.xmpp.org/registrar/muc.html>

原文控制: HTML RSS

本文的其它格式: XML PDF

附录B:作者信息

Peter Saint-Andre

Email: stpeter@jabber.org

JabberID: stpeter@jabber.org

URI: https://stpeter.im/

附录C:法律通告

版权

XMPP扩展协议的版权(1999-2008)归XMPP标准化基金会(XSF)所有.

权限

特此授权,费用全免,对任何获得本协议副本的人,对使用本协议没有限制,包括不限制在软件程序中实现本协议,不限制在网络服务中布署本协议,不限制拷贝,修改,合并,发行,翻译,分发,转授,或销售本协议的副本,被允许使用本协议做了以上工作的人士,应接受前述的版权声明和本许可通知并且必须包含在所有的副本或实质性部分的规格中.除非单独的许可,被重新分发的修改工作,不得含有关于作者,标题,编号,或出版者的规格的误导性资料,并不得宣称修改工作是由本文的作者,作者所属的任何组织或项目,或XMPP标准基金会签注。

免责声明'

## 特别注意:本协议是提供的“原样”的基础,没有担保或任何形式的条件,明示或暗示,包括,但不限于任何担保或关于名称,非侵权性,适销性或适合作某一特定目的的条件. ##

责任限制

在任何情况下以及没有任何法律规定时,不论是侵权行为(包括疏忽),合同或其它方面,除非根据适用法律的要求(如蓄意和有严重疏忽行为)或以书面形式同意,XMPP标准基金会或任何作者不对本协议所造成的损失承担责任,包括任何直接,间接,特殊,偶发,或任何从本协议出,入,连接的字符产生的或实现,布署或其他对本协议的使用导致的相应的损害赔偿(包括但不限于善意的损失,停止作业,电脑失灵或故障,或任何和所有其他商业损害或损失) ,即使XMPP标准基金会或作者已被告知此类损害的可能性。

知识产权的一致性

XMPP扩展协议完全遵守XSF的知识产权策略(可在<http://www.xmpp.org/extensions/ipr-policy.shtml>找到副本或写信给XMPP标准基金会, 1899 Wynkoop Street, Suite 600, Denver, CO 80202 USA).

附录D:和XMPP的关系

可扩展的消息和出席信息协议 (XMPP) 定义于 XMPP Core (RFC 3920) 和 XMPP IM (RFC 3921) 规范里,由 XMPP标准基金会贡献到由依据RFC 2026成立的互联网工程人物组管理的互联网标准流程 Internet Standards Process. 本文定义的任何协议已在互联网标准流程之外开发,并且被理解为 XMPP 的扩展而不是一个XMPP本身的演化, 开发, 或修改.

附录E:讨论地点

主要的XMPP扩展协议讨论地点是 <standards@xmpp.org> 讨论列表.

在 xmpp.org 的其它讨论列表中的讨论可能也有合适的; 所有的列表见 <http://xmpp.org/about/discuss.shtml> .

勘误表可以发送邮件到 <editor@xmpp.org>.

附录F:需求一致性

以下用于本文的需求关键字的解释见于 RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".


附录G:备注

  1. RFC 1459: Internet Relay Chat <http://tools.ietf.org/html/rfc1459>.
  2. RFC 2810: Internet Relay Chat: Architecture <http://tools.ietf.org/html/rfc2810>.
  3. RFC 2811: Internet Relay Chat: Channel Management <http://tools.ietf.org/html/rfc2811>.
  4. RFC 2812: Internet Relay Chat: Client Protocol <http://tools.ietf.org/html/rfc2812>.
  5. RFC 2813: Internet Relay Chat: Server Protocol <http://tools.ietf.org/html/rfc2813>.
  6. XEP-0133: Service Administration <http://xmpp.org/extensions/xep-0133.html>.
  7. XEP-0030: Service Discovery <http://xmpp.org/extensions/xep-0030.html>.
  8. XEP-0059: Result Set Management <http://xmpp.org/extensions/xep-0059.html>.
  9. XEP-0128: Service Discovery Extensions <http://xmpp.org/extensions/xep-0128.html>.
  10. RFC 3920: 可扩展的消息和出席信息协议 (XMPP): Core <http://tools.ietf.org/html/rfc3920>.
  11. XEP-0203: Delayed Delivery <http://xmpp.org/extensions/xep-0203.html>.
  12. XEP-0091: Legacy Delayed Delivery <http://xmpp.org/extensions/xep-0091.html>.
  13. XEP-0082: XMPP Date and Time Profiles <http://xmpp.org/extensions/xep-0082.html>.
  14. RFC 3921: 可扩展的消息和出席信息协议 (XMPP): Instant Messaging and Presence <http://tools.ietf.org/html/rfc3921>.
  15. XEP-0249: Direct MUC Invitations <http://xmpp.org/extensions/xep-0249.html>.
  16. XEP-0077: In-Band Registration <http://xmpp.org/extensions/xep-0077.html>.
  17. XEP-0004: Data Forms <http://xmpp.org/extensions/xep-0004.html>.
  18. 一些评论者抱怨公开房间的所有者和管理员存在潜在的滥用; 很不幸的, 能力越大责任越大.
  19. XEP-0050: Ad-Hoc Commands <http://xmpp.org/extensions/xep-0050.html>.
  20. XEP-0060: Publish-Subscribe <http://xmpp.org/extensions/xep-0060.html>.
  21. 这和房间配置的行为不同, 这里 'muc#roomconfig_roomowners' 字段指定房间所有者的完整列表, 不是delta.
  22. 这和房间配置的行为不同, 这里 'muc#roomconfig_roomadmins' 字段指定房间管理眼的完整列表, 不是delta.
  23. XEP-0086: Error Condition Mappings <http://xmpp.org/extensions/xep-0086.html>.
  24. RFC 2616: Hypertext Transport Protocol -- HTTP/1.1 <http://tools.ietf.org/html/rfc2616>.
  25. RFC 1893: Enhanced Mail System Status Codes <http://tools.ietf.org/html/rfc1893>.
  26. 互联网编号分配机构 (IANA) 是用于互联网协议的唯一性参数值分配的核心协调者, 例如号码和URI计划. 更多信息, 见 <http://www.iana.org/>.
  27. XMPP登记员 XMPP Registrar 维护着一个保留的协议名字空间以及用于由XMPP标准基金会批准的XMPP扩展协议的上下文参数的注册项的列表. 更多信息, 见 <http://xmpp.org/registrar/>.
  28. XEP-0068: Field Data Standardization for Data Forms <http://xmpp.org/extensions/xep-0068.html>.
  29. XEP-0147: XMPP URI Query Components <http://xmpp.org/extensions/xep-0147.html>.
  30. XEP-0022: Message Events <http://xmpp.org/extensions/xep-0022.html>.
  31. XEP-0085: Chat State Notifications <http://xmpp.org/extensions/xep-0085.html>.
  32. XEP-0071: XHTML-IM <http://xmpp.org/extensions/xep-0071.html>.
  33. XEP-0245: The /me Command <http://xmpp.org/extensions/xep-0245.html>.

附录H: 修订历史

注意: 本协议的旧版本可能在 http://xmpp.org/extensions/attic/ 还可用

版本 1.24 (2008-07-16)

增加了更多原因reason元素的例子; 移除了关于黑名单包含的昵称部分; 增加了拒绝服务注意事项.

(psa)

版本 1.23 (2008-01-14)

  • 定义了 getmemberlist 房间配置选项
  • 增加了直接邀请协议
  • 修正了当房间满的时候房间承认所有者/管理员的逻辑
  • 定义了和LDAP群关联的服务发现扩展字段
  • 指定了房间配置字段能被列入扩展的房间信息之中
  • 指定了消息格式用于用户不在房间时的岗位变更
  • 增加了例子展示结果集管理
  • 推荐出席信息错误中包含的MUC子元素
  • 为一对一聊天和多用户聊天的连续性描述了ThreadID的使用, 包括在邀请中为 continue 元素定义 thread 属性.

(psa)

版本 1.22 (2007-04-10)

更新了延迟消息递送以反映 XEP-0203 演化到草案和 XEP-0091 的过时.

(psa)

版本 1.21 (2006-09-13)

  • 澄清了MUC扩展的介入,在房间加入/创建请求触发数据表单流但没有MUC扩展可导致自动房间创建以向后兼容旧的 groupchat 1.0 协议.
  • 指定昵称变更时如果昵称被锁定则返回 <not-acceptable/> 错误.
  • 要求客户端在进入房间之前发现房间配置并指定相关的安全事项, 包括使用隐私相关的状态码 170, 171, 172, 173, 和 174.
  • 指定在房间配置选项不能被执行或违反服务策略时使用 <not-acceptable/> 错误.
  • 强制要求房间昵称不能只包含空格.
  • 移除所有服务发现用例到专用章节.
  • 修改 urn:xmpp:delay 支持从 SHOULD 改为 MUST.
  • 澄清 _whois 房间配置选项定义房间类型.
  • 定义 XEP-0128 房间信息字段用于讨论记录, 关联的 pubsub 节点, 以及联系人 JID.
  • 指出修改角色到主持人导致岗位变更为管理员或所有者成为推荐的, 而不是必需的.
  • 增加了国际化事项中关于数据表单的本地化的部分.
  • 指出实现可以持久化角色括月整个访问并且应该在被主持的房间里这样做.
  • 增加了协议和服务发现特性用于在新建房间之前请求唯一的房间名.
  • 更多澄清保留的房间昵称和昵称锁定的性质.
  • 定义数据表单用于请求发言权和批准发言申请.
  • 增加了多个邀请的例子用于XMPP URI.
  • 澄清了出席信息,讨论历史的顺序, 等等.
  • 增加了状态码用于房客拥有的房间昵称, 服务修改的房间昵称, 并警告房间讨论被公开记录.
  • 澄清关于房间记录和非匿名房间的隐私和匿名事项.

(psa)

版本 1.20 (2005-09-08)

同意了踢人和禁止用户的能力, 并定义了一个用户不能被一个比自己岗位低的主持人或管理员踢或禁止.

(psa)

版本 1.19 (2005-04-21)

定义了怎样发送并发多邀请; 纠正了一些和岗位变更状态一致性的错误; 修改了消息事件禁令表单从 MUST NOT 到 SHOULD NOT; 修正了和 #traffic disco 节点相关的错误处理; 允许了 <password/> 作为<destroy/>的一个子元素; 修改了最大用户数错误从 <not-allowed/> 到 <service-unavailable/>; 指定了 maxchars 属性的字符数是指完整的 XML 节; 为 FORM_TYPEs;增加了 disco 特性 为状态码定义了注册表; 为遵守协议分开了新建即时房间的用例; 调整了 XML 架构以反映之前的修改; 重写了绪论; 澄清了小的文本错误.

(psa)

Version 1.18 (2004-11-02)

Corrected several errors in the affiliation state chart and in the examples (wrong FORM_TYPE values); mentioned /me command. (psa) Version 1.17 (2004-10-04)

Added text about allowable extension namespaces and related service discovery mechanisms; specified well-known service discovery nodes; added conformance terms to clarify some descriptions; modified affiliation state chart to allow more flexible state changes; per list dicussion, added ability to convert a one-to-one chat into a conference, including sending of history; specified error to use when max users limit is reached; specified form for admin approval of user registration requests and modified FORM_TYPE from http://jabber.org/protocol/muc#user to http://jabber.org/protocol/muc#register; modified FORM_TYPE for room configuration from http://jabber.org/protocol/muc#owner to http://jabber.org/protocol/muc#roomconfig. (psa) Version 1.16 (2004-06-30)

Added example and registry submission for service discovery extension. (psa) Version 1.15 (2004-06-24)

Removed jabber:iq:browse references; clarified order of presence stanzas sent to new occupant on entering room; specified format of in-room messages (type='groupchat', from='room@service'); clarified allowable attributes in various list-related operations; made admin/owner revocation text and examples consistent with state chart; clarified ownership revocation conflict scenarios; changed the 'muc#roomconfig_inviteonly' field to 'muc#roomconfig_membersonly'; changed attribute order in examples to match XML canonicalization rules; corrected several errors in the schemas. (psa) Version 1.14 (2004-05-03)

Corrected discovery of registered roomnicks; added note about error to return if nicks are locked down. (psa) Version 1.13 (2004-03-31)

Fixed an error in the muc#user schema. (psa) Version 1.12 (2004-03-01)

Corrected a few errors in the examples; added IQ results in order to clarify workflows. (psa) Version 1.11 (2004-02-05)

Clarified JID matching rules (same as for privacy lists in XMPP IM). (psa) Version 1.10 (2004-01-07)

Added XMPP error handling; fully specified all conformance terms. (psa) Version 1.9 (2003-12-14)

Removed protocol for requesting voice in a moderated room (should be performed using Ad-Hoc Commands). (psa) Version 1.8 (2003-12-04)

Added protocol for requesting voice in a moderated room; added (informational) mapping of IRC commands to MUC protocols. (psa) Version 1.7 (2003-10-21)

Added room configuration option for restricting presence broadcast to certain roles. (psa) Version 1.6 (2003-10-03)

Added history management protocol on entering a room. (psa) Version 1.5 (2003-09-11)

Specified that ban occurs by JID, not roomnick; allowed privileged users to send messages to the room even if not present in the room; added note that service should remove occupant if a delivery-related stanza error occurs; enabled user to disco the room in order to discover registered roomnick; specified that "banning" by domain or regex is a service-level configuration matter and therefore out of scope for MUC; specified that role should be decremented as appropriate if affiliation is lowered; added some clarifying text to room creation workflow; added implementation note about sending an out-of-band message if a user's affiliation changes while the user is not in the room; fixed stringprep references (room nicks use Resourceprep); clarified relationship between Room ID (i.e., node identifier of Room JID, which may be opaque) and natural-language Room Name; specified Field Standardization profile per XEP-0068; defined XMPP Registrar submissions; added schema locations. (psa) Version 1.4 (2003-02-16)

Added XML schemas. (psa) Version 1.3 (2003-02-11)

Added reference to nodeprep Internet-Draft. (psa) Version 1.2 (2003-01-30)

Commented out revision history prior to version 1.0 (too long); clarified business rules regarding when nicks, full JIDs, and bare JIDs are used in reference to roles and affiliations; consistently specified that extended presence information in the muc#user namespace must include the full JID as the value of the 'jid' attribute in all cases; cleaned up text and examples throughout; added open issue regarding syntax of room nicknames. (psa) Version 1.1 (2002-12-16)

Added protocol for declining an invitation; replaced <created/> element with status code 201; modified the destroy room protocol so that <destroy/> is a child of <query/>; clarified usage of 'nick' attribute when adding members; prohibited use of message events. (psa) Version 1.0 (2002-11-21)

Per a vote of the Jabber Council, revision 0.23 was advanced to Draft on 2002-11-21. (For earlier revision history, refer to XML source.) (psa) Version 0.23 (2002-11-06)

Added examples for disco#items queries sent to a room; prohibited 'type' attribute on invite messages sent from client to room; added dependencies on browse and disco; changed 'room user' to 'occupant'; fixed many small errors throughout. (psa) Version 0.22 (2002-11-04)

Added example for disco#items; added support for cancellation of room configuration using type='cancel' from XEP-0004; noted 403 error for invites sent by non-admins in members-only room. (psa) Version 0.21 (2002-11-01)

Clarified several small ambiguities; made <body/> optional on invites sent from the service to the invitee; added error scenarios for changing nickname and for destroying the room; specified that the service must return the full member list for a members-only room (not only the members in the room); updated the disco examples to track protocol changes. (psa) Version 0.20 (2002-10-29)

Specified that messages sent to change the room subject must be of type "groupchat"; updated the legal notice to conform to the XSF IPR policy. (psa) Version 0.19 (2002-10-28)

Added ability to create an instant room within MUC (not by using gc-1.0 protocol); cleaned up disco examples. (psa) Version 0.18 (2002-10-27)

Added experimental support for disco; added sections for security, IANA, and JANA considerations; corrected typographical errors; cleaned up some DocBook formatting. (psa) Version 0.17 (2002-10-23)

Added the optional <actor/> element (with 'jid' attribute) to <item/> elements inside presence stanzas of type "unavailable" that are sent to users who are kicked or banned, as well as within IQs for tracking purposes; reverted all list editing use cases (ban, voice, member, moderator, admin, owner) to use of MUC format rather than 'jabber:x:data' namespace; added several guidelines regarding generation and handling of XML stanzas; cleaned up the change room subject use case; changed several ambiguous uses of 'would', 'can', and 'will' to 'should', 'may', or 'must'; fixed several small errors in the text, examples, and DTDs. (psa) Version 0.16 (2002-10-20)

Added the <item/> element to presence stanzas of type "unavailable" in order to improve the tracking of user states in the room; consolidated <invitee/> and <invitor/> elements into an <invite/> element with 'from' and 'to' attributes; made <reason/> element always a child of <item/> or <invite/> in the muc#user namespace; moved the alternate room location in room destruction to a 'jid' attribute of the <alt/> element; further specified several error messages; disallowed simultaneous modifications of both affiliations and roles by a moderator or admin; added several more rules regarding handling of XML stanzas; added use cases for granting and revoking administrative privileges; adjusted DTD to track all changes. (psa) Version 0.15 (2002-10-18)

Fully incorporated the change to affiliations + roles; moved a number of admin use cases to a new section for moderator use cases; added participant use case for requesting membership; added admin use cases for adding members, removing members, granting and revoking moderator privileges, and modifying the moderator list; organized the sections in a more logical manner. (psa) Version 0.14 (2002-10-17)

Significantly modified the privileges model by distinguishing between in-room "roles" and long-lived "affiliations"; specified the privileges of the various roles and affiliations; included state transition charts for both roles and affiliations; removed use of MUC protocol for editing ban, voice, and admin lists (but not for the actions of banning users and granting/revoking voice); added delivery rule regarding IQ stanzas; changed kick so that the action is based on changing the role to "none". (psa) Version 0.13 (2002-10-16)

Corrected the change nickname examples (newnick sent on unavailable, no nick sent on available). (psa) Version 0.12 (2002-10-16)

Removed SHA1 passwords; specified that room shall add passwords on invitations to password-protected rooms (not supplied by invitor). (psa) Version 0.11 (2002-10-16)

Changed 'participant' to 'room user' and 'discussant' to 'participant'; clarified presence rule about client generation of extended presence information; added role of 'none'. (psa) Version 0.10 (2002-10-15)

Fixed extended presence on entering or creating a room (plain '...muc' with no fragment); harmonized #user with #admin regarding the use of the <item/> element and associated attributes (jid, nick, etc.), and added 'role' attribute; modified management of voice, ban, admin, and member lists to use <query/> wrapper and new <item/> structure; changed the 'member' role to 'discussant', added 'outcast' role for banned users, and added new 'member' role to enable management of member lists; changed invitation-only rooms to members-only rooms and made appropriate adjustments to apply member lists to both members-only rooms and open rooms; modified nickname change protocol slightly to send the old nickname in the unavailable presence and the new nickname in the available presence; removed prohibition on members-only rooms that are password-protected; removed the <query/> wrapper for the <destroy/> element; updated the DTDs. (psa) Version 0.9 (2002-10-13)

Added extended presence ('...#user') on entering a room for MUC clients; changed namespace on room creation request to '...#owner'; added a service discovery example using jabber:iq:browse; added information about discussion history; made small fixes to several examples; further defined the presence rules; transferred all implementation notes to a dedicated section; added a Terminology section. (psa) Version 0.8 (2002-10-10)

Made further changes to the room creation workflow (finally correct); removed feature discovery use case (this needs to be addressed by a real service discovery protocol!); added ability for room owners to edit the admin list; removed <body/> from invitations generated by the service; removed messages sent to kicked and banned users (handled by unavailable presence with status code); added a number of implementation notes; converted all examples to Shakespeare style. (psa) Version 0.7.6 (2002-10-09)

Fixed the room creation workflow; changed some terminology ("join" to "enter" and "leave" to "exit"). (psa) Version 0.7.5 (2002-10-08)

Specified and improved the handling of invitation-only rooms. In particular, added the ability for room admins to edit the invitation list and added a configuration option that limits the ability to send invitations to room admins only. (psa) Version 0.7.4 (2002-10-07)

Changed namespaces from http://jabber.org/protocol/muc/owner etc. to http://jabber.org/protocol/muc#owner etc. per Jabber Council discussion. (psa) Version 0.7.3 (2002-10-07)

Changed namespaces to HTTP URIs; left role handling up to the implementation; further clarified presence rules. (psa) Version 0.7.2 (2002-10-06)

Disallowed kicking, banning, and revoking voice with respect to room admins and room owners; replaced <x/> with <query/> in the Discovering Room Features and Destroying a Room use cases; corrected some small errors and made many clarifications throughout. (psa) Version 0.7.1 (2002-10-04)

Removed <whois/> command (unnecessary since participants with appropriate privileges receive the full JID of all participants in presence stanzas); completed many small fixes throughout. (psa) Version 0.7 (2002-10-03)

More clearly delineated participant roles and defined the hierarchy thereof (owner, admin, member, visitor); replaced <voice/> element in extended presence with <item role='member'/>; changed initial room configuration to use IQ rather than message; adjusted presence rules (especially regarding extended presence information); cleaned up examples throughout; updated DTD to track changes. (psa) Version 0.6 (2002-09-21)

More clearly defined the scope; removed fully anonymous rooms; changed meaning of semi-anonymous rooms and of non-anonymous rooms; added mechanism for notification of full JIDs in non-anonymous rooms; replaced the <admin/> element in extended presence with a <role/> element (more extensible); changed room passwords to cleartext; added status codes for various messages received from the service; added lists of valid error and status codes associated with the 'http://jabber.org/protocol/muc#user' namespace; added a <reason/> element for invitations; made kick and ban reasons child elements rather than attributes; replaced stopgap feature discovery mechanism with jabber:iq:negotiate; added extended presence element to room creation request and clarified the room creation process; specified presence reflection rules; added method for destroying a room; adjusted DTDs to track all changes. (psa) Version 0.5.1 (2002-09-20)

Added DTDs; changed feature discovery to use <x/> element rather than query and made service response come in IQ result; fixed reference to JID spec; changed 'grant' to 'add' and 'revoke' to 'remove' for consistency in the item attributes; made several other small changes. (psa) Version 0.5 (2002-09-19)

Changed the kick, ban, and voice protocols; added a few more configuration options; specified the restrictions for roomnicks; and added a stopgap service discovery protocol. (psa) Version 0.4 (2002-09-18)

Changed all non-GC-1.0 use cases to jabber:gc:* namespaces or jabber:x:data; added use cases for ban list management and room moderation; added protocol for sending notice of admin and voice privileges in presence; cleaned up text and many examples. (psa) Version 0.3 (2002-09-17)

Changed admin use cases; cleaned up participant and owner use cases. (psa) Version 0.2 (2002-09-12)

Broke content out into three actors (participant, owner, and admin) and added more detail to owner and admin use cases. (psa) Version 0.1 (2002-09-09)

Initial version. (psa)

END

个人工具