修改主持人列表

管理员可能希望修改主持人列表. 为此, 管理员首先通过请求房间内所有角色为'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. 服务通知用户不能新建房间

<presencefrom='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用户新建一个房间并声明对多用户聊天的支持

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

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

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

<presencefrom='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 usersTo accept the default configuration, click OK. Toselect a different configuration, please completethis form.</instructions><fieldtype='hidden'var='FORM_TYPE'><value>http://jabber.org/protocol/muc#roomconfig</value></field><fieldlabel='Natural-Language Room Name'type='text-single'var='muc#roomconfig_roomname'/><fieldlabel='Short Description of Room'type='text-single'var='muc#roomconfig_roomdesc'/><fieldlabel='Natural Language for Room Discussions'type='text-single'var='muc#roomconfig_lang'/><fieldlabel='Enable Public Logging?'type='boolean'var='muc#roomconfig_enablelogging'><value>0</value></field><fieldlabel='Allow Occupants to Change Subject?'type='boolean'var='muc#roomconfig_changesubject'><value>0</value></field><fieldlabel='Allow Occupants to Invite Others?'type='boolean'var='muc#roomconfig_allowinvites'><value>0</value></field><fieldlabel='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><fieldlabel='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><fieldlabel='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><fieldlabel='Make Room Publicly Searchable?'type='boolean'var='muc#roomconfig_publicroom'><value>1</value></field><fieldlabel='Make Room Persistent?'type='boolean'var='muc#roomconfig_persistentroom'><value>0</value></field><fieldlabel='Make Room Moderated?'type='boolean'var='muc#roomconfig_moderatedroom'><value>0</value></field><fieldlabel='Make Room Members-Only?'type='boolean'var='muc#roomconfig_membersonly'><value>0</value></field><fieldlabel='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><fieldlabel='Password'type='text-private'var='muc#roomconfig_roomsecret'/><fieldlabel='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 haveadministrative privileges in the room. Pleaseprovide one Jabber ID per line.</value></field><fieldlabel='Room Admins'type='jid-multi'var='muc#roomconfig_roomadmins'/><field type='fixed'><value>You may specify additional owners for thisroom. Please provide one Jabber ID per line.</value></field><fieldlabel='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 tothe configuration of your room.</instructions><fieldtype='hidden'var='FORM_TYPE'><value>http://jabber.org/protocol/muc#roomconfig</value></field><fieldlabel='Natural-Language Room Name'type='text-single'var='muc#roomconfig_roomname'><value>A Dark Cave</value></field><fieldlabel='Short Description of Room'type='text-single'var='muc#roomconfig_roomdesc'><value>The place for all good witches!</value></field><fieldlabel='Enable Public Logging?'type='boolean'var='muc#roomconfig_enablelogging'><value>0</value></field><fieldlabel='Allow Occupants to Change Subject?'type='boolean'var='muc#roomconfig_changesubject'><value>0</value></field><fieldlabel='Allow Occupants to Invite Others?'type='boolean'var='muc#roomconfig_allowinvites'><value>0</value></field><fieldlabel='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><fieldlabel='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><fieldlabel='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><fieldlabel='Make Room Publicly Searchable?'type='boolean'var='muc#roomconfig_publicroom'><value>0</value></field><fieldlabel='Make Room Persistent?'type='boolean'var='muc#roomconfig_persistentroom'><value>0</value></field><fieldlabel='Make Room Moderated?'type='boolean'var='muc#roomconfig_moderatedroom'><value>0</value></field><fieldlabel='Make Room Members Only?'type='boolean'var='muc#roomconfig_membersonly'><value>0</value></field><fieldlabel='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><fieldlabel='Password'type='text-private'var='muc#roomconfig_roomsecret'><value>cauldronburn</value></field><fieldlabel='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 haveadministrative privileges in the room. Pleaseprovide one Jabber ID per line.</value></field><fieldlabel='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 thisroom. Please provide one Jabber ID per line.</value></field><fieldlabel='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. 服务通知失去管理员岗位

<presencefrom='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. 服务通知所有用户有人获得管理员岗位

<presencefrom='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. 服务通知失去所有者岗位

<presencefrom='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. 服务通知所有用户有人获得所有者权限

<presencefrom='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. 服务发送所有权通知给所有房客

<presencefrom='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. 服务发送所有权通知给所有房客

<messagefrom='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. 服务通知失去所有权

<presencefrom='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. 服务发送失去所有权通知给所有房客

<messagefrom='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. 服务发送管理员权限通知给所有房客

<presencefrom='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. 服务发送管理员权限通知给所有房客

<messagefrom='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. 服务通知失去管理员权限

<presencefrom='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. 服务通知失去管理员权限

<messagefrom='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/desktopaffiliationid='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. 服务移除每个房客

<presencefrom='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><presencefrom='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><presencefrom='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 24 和 RFC 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相关的名字空间:

  • 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 来标识的.

服务发现特性

有很多和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 aMulti-User Chat (MUC) room or admin approvalof user registration requests.</desc><field var='muc#register_allow'type='boolean'label='Allow this person to register with the room?'/><fieldvar='muc#register_email'type='text-single'label='Email Address'/><fieldvar='muc#register_faqentry'type='text-multi'label='FAQ Entry'/><fieldvar='muc#register_first'type='text-single'label='Given Name'/><fieldvar='muc#register_last'type='text-single'label='Family Name'/><fieldvar='muc#register_roomnick'type='text-single'label='Desired Nickname'/><fieldvar='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 adminapproval 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 ofa Multi-User Chat (MUC) room.</desc><fieldvar='muc#roomconfig_allowinvites'type='boolean'label='Whether to Allow Occupants to Invite Others'/><fieldvar='muc#roomconfig_changesubject'type='boolean'label='Whether to Allow Occupants to Change Subject'/><fieldvar='muc#roomconfig_enablelogging'type='boolean'label='Whether to Enable Public Logging of Room Conversations'/><fieldvar='muc#roomconfig_getmemberlist'type='list-multi'label='Roles and Affiliations that May Retrieve Member List'/><fieldvar='muc#roomconfig_lang'type='text-single'label='Natural Language for Room Discussions'/><fieldvar='muc#roomconfig_pubsub'type='text-single'label='XMPP URI of Associated Publish-Subcribe Node'/><fieldvar='muc#roomconfig_maxusers'type='list-single'label='Maximum Number of Room Occupants'/><fieldvar='muc#roomconfig_membersonly'type='boolean'label='Whether an Make Room Members-Only'/><fieldvar='muc#roomconfig_moderatedroom'type='boolean'label='Whether to Make Room Moderated'/><fieldvar='muc#roomconfig_passwordprotectedroom'type='boolean'label='Whether a Password is Required to Enter'/><fieldvar='muc#roomconfig_persistentroom'type='boolean'label='Whether to Make Room Persistent'/><fieldvar='muc#roomconfig_presencebroadcast'type='list-multi'label='Roles for which Presence is Broadcast'/><fieldvar='muc#roomconfig_publicroom'type='boolean'label='Whether to Allow Public Searching for Room'/><fieldvar='muc#roomconfig_roomadmins'type='jid-multi'label='Full List of Room Admins'/><fieldvar='muc#roomconfig_roomdesc'type='text-single'label='Short Description of Room'/><fieldvar='muc#roomconfig_roomname'type='text-single'label='Natural-Language Room Name'/><fieldvar='muc#roomconfig_roomowners'type='jid-multi'label='Full List of Room Owners'/><fieldvar='muc#roomconfig_roomsecret'type='text-private'label='The Room Password'/><fieldvar='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 discoveryinformation about a Multi-User Chat (MUC) room.</desc><fieldvar='muc#roominfo_contactjid'type='jid-multi'label='Contact Addresses (normally, room owner or owners)'/><fieldvar='muc#roominfo_description'type='text-single'label='Short Description of Room'/><fieldvar='muc#roominfo_lang'type='text-single'label='Natural Language for Room Discussions'/><fieldvar='muc#roominfo_ldapgroup'type='text-single'label='An associated LDAP group that defines room membership; this should be an LDAP Distinguished Name according to animplementation-specific or deployment-specific definitionof a group.'/><fieldvar='muc#roominfo_logs'type='text-single'label='URL for Archived Discussion Logs'/><fieldvar='muc#roominfo_occupants'type='text-single'label='Current Number of Occupants in Room'/><fieldvar='muc#roominfo_subject'type='text-single'label='Current Subject or Discussion Topic in Room'/><fieldvar='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:schemaxmlns: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 inXEP-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:schemaxmlns: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 inXEP-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:schemaxmlns: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 inXEP-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:schemaxmlns: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 inXEP-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:schemaxmlns: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 inXEP-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

XMPP中文 XEP-0045: 多用户聊天(二)相关推荐

  1. Android基于XMPP Smack openfire 开发的聊天室

    公司刚好让做即时通讯模块,服务器使用openfire,偶然看到有位仁兄的帖子,拷贝过来细细研究,感谢此仁兄的无私,期待此仁兄的下次更新 转自http://blog.csdn.net/lnb333666 ...

  2. xmpp 中文 XEP-0084: 用户头像

    本文的英文原文来自XEP-0079 XEP-0079: 高级消息处理 摘要: 本文定义了一个XMPP协议扩展来实现实体请求,服务器执行的,高级XMPP message 节处理, 包括可靠数据传输, 时 ...

  3. XMPP中文 XEP-0030:服务发现

    本文的英文原文来自XEP-0030 XEP-0030:服务发现 摘要: 本文定义了一个XMPP协议扩展用于发现其他XMPP实体的信息.有两种信息可以被发现:(1) 一个实体的身份和能力, 包括它支持的 ...

  4. XMPP中文 XEP-0060: 发布-订阅(一)

    本文的英文原文来自XEP-0060 XEP-0060: 发布-订阅 摘要: 本文定义了一个XMPP协议扩展来实现实现通用的 发布-订阅 功能.这个协议使 XMPP实体能在一个pubsub服务创建节点( ...

  5. AT指令(中文详解版)(二)

    AT指令(中文详解版)(二) 常 用 AT 命 令 手 册   1.常用操作 1.1 AT 命令解释:检测 Module 与串口是否连通,能否接收 AT 命令: 命令格式:AT<CR> 命 ...

  6. Java实现--基于服务器的多用户聊天室

    多用户聊天室 1.项目简介 2.开发环境 3.项目具体功能 4.运行结果 5.其他功能实现运行结果 6.具体实现代码 登录页面: 客户端: 服务器端: 1.项目简介 基于服务器的多用户聊天室应用软件. ...

  7. 中文错别字检查添加了二维码入口

    中文错别字检查添加了二维码入口 最近在研究了一下有特色 二维码的生成, 于是借用到了中文错别字检查页面上了, 就是下面的这幅图片,怎么样,图中的 CBZ 三个字母还是清晰可以辨认的吧? 还准备把更多的 ...

  8. GPT2中文模型本地搭建(二)

    GPT2中文模型本地搭建(二) 1.简单介绍 1.1 bert4keras是什么,与Keras有什么关系? 1.2 常用的预训练模型加载框架有几种? 1.3 预训练模型常见版本 2.GPT2-ML 开 ...

  9. XMPP中文 XEP-0060: 发布-订阅(二)

    例子 130. 实体请求一个即时节点 <iq type='set'from='hamlet@denmark.lit/elsinore'to='pubsub.shakespeare.lit'id= ...

最新文章

  1. NDK编译生成so文件
  2. JQuery对象和JS对象区别与转换|| 事件绑定 入口函数 样式控制
  3. 评估应用使用oracle磁盘空间,Oracle磁盘空间使用统计
  4. 嵌入式成长轨迹23 【Linux应用编程强化】【Linux下的C编程 下】【Linux GUI编程】...
  5. php.c drcom,校园网绕过Drcom安装自动登录程序到路由器
  6. mac chrome 打包扩展程序
  7. mysql 增加建表权限,mysql_基本权限模型建表结构
  8. Ssm手机电脑自适应新闻博客系统实战开发
  9. Leetcode每日一题:234.palindrome-linked-list(回文链表)
  10. matlab 实现行程编码 对二值图像进行编解码
  11. 【转载】spring mvc 使用session
  12. 计算机组成原理汉字编码与校验设计实验报告(汉字国标码转区位码实验、汉字机内码获取实验、海明编码电路设计与海明解码)
  13. TA技术美术学习路线
  14. 跳动公差与其他几何公差(一)
  15. CSS3实现倒影效果
  16. u盘格式化不了怎么办?恢复U盘,方法很简单
  17. cpu soft lockup
  18. iphone导出视频 无法连接到设备_手机资讯:怎么将iPhone微信小视频存储到本地
  19. android fragment相机,简单的易于集成的Android相机Fragment – Camer...
  20. 火车票退票费计算,2013年起,火车票退票费比例下调:票面乘车站开车时间前48小时以上的按票价5%计退票费。同时,车票退票费的计算方法不再四舍五入到元为单位,而以5角为单位:尾数小于0.25元的舍去

热门文章

  1. NOIP2018酱油记
  2. 计算机程序必须装载哪,计算机程序必须装载到内存中才能执行
  3. 计算机描述不可用步骤,Win10 1909系统中提示打印机描述不可用解决方法
  4. CEO、COO、CFO、CTO、CIO是什么意思?
  5. win11无法输入中文解决办法
  6. Github:解决电脑无法登陆github.com问题
  7. 产品研发杂谈(GJB5000A)
  8. git tag与git tag -a的不同
  9. React是不是MVVM架构?
  10. 谈谈本地缓存的几种方式以及他们的区别?