查看源代码
来自Jabber/XMPP中文翻译计划
XEP-0084
的源代码
跳转到:
导航
,
搜索
根据下列原因,你没有权限编辑本页:
您刚才请求的操作只有这个用户组中的用户才能使用:
用户
您可以查看并复制此页面的源代码:
[[Category:XMPP扩展]] [[Category:翻译中]] '''本文的英文原文来自[http://www.xmpp.org/extensions/xep-0084.html XEP-0084]''' '''XEP-0084: 用户头像''' 摘要: 本文定义了一个XMPP协议扩展,用于交换用户头像,一个小的和自然人用户相关的图像或图标. 该协议定义了头像元数据和图像数据本身的承载格式. 承载格式典型地使用定义于XEP-0163的 XMPP发布-订阅个人事件脚本 协议来传输 作者: Peter Saint-Andre, Peter Millard, Thomas Muldowney, Julian Missig 版权: © 1999 - 2010 XMPP标准化基金会(XSF). 参见[[XEP-0084#附录C:法律通告|法律通告]]. 状态: 草案 类型: 标准跟踪 版本: 1.1 最后更新日期: 2008-11-05 ---- 注意: 这里定义的协议是XMPP标准化基金会的一个'''草案标准'''.对本协议的执行是被鼓励的,也适于布署到生产系统,但是在它成为最终标准之前可能还会有一些变动. ---- ==绪论== 很多通讯应用允许那个应用的用户拥有一个相关的小图片或图标. 通常, 这样一个 "avatar" 不一定是一个用户的真正长相的图片, 而可能是一个用户期望的自己的图像 (经常很怪诞) 或该用户暂时的状态 (例如心情或活动). 本文定义一个方法来把头像合并到目前的 Jabber/XMPP 系统,即把该功能架在 [[XEP-0060|XMPP发布-订阅]] [[XEP-0084#附录G:备注|1]] 扩展 ("pubsub")之上, 特别是 [[XEP-0163|个人事件协议]] [[XEP-0084#附录G:备注|2]] 子集 ("PEP"), 它被定义用于符合 [[RFC3921|RFC 3921]] [[XEP-0084#附录G:备注|3]]的 XMPP 即时消息和出席信息系统的场景. 本协议在这里定义使用两种 pubsub 节点(nodes): 一个 node 用于元数据 "metadata",关于头像状态的 (称为 元数据节点 "metadata node") ;另一个是用于头像数据本身 (称为 数据节点 "data node"). 这个从数据中分离出来的元数据 metadata 节省了带宽,并且使发布者和订阅者能够缓存头像数据. (例如, 一个用户可能在两个或三个头像之间切换, 这种情况下用户的联系人们可以显示这些图片的一个本地缓存版本而不用每次检索或接收完整的图片.) 这个协议也允许头像数据存储在一个可通过HTTP (见 [http://tools.ietf.org/html/rfc2616 RFC 2616] [[XEP-0084#附录G:备注|4]]) 访问的 URL 上. [[XEP-0084#附录G:备注|5]] 如果一个 pubsub-aware 数据仓库不可用,作为一个回退机制这是有帮助的. 它也使头像图片能被托管在公共的网站上 (例如, 一个面向终端用户的社区网站) 并从那个网站检索到而不是直接由发布的客户端以任何方式来处理. 最后, 本协议也使 XMPP 应用能选择性地和托管了用户头像的第三方服务(例如, 在线游戏系统和虚拟世界)集成. 一旦 XMPP 发布-订阅 的 PEP子集被足够广泛地实现和布署,本协议准备将来取代 [http://xmpp.org/extensions/xep-0008.html 基于IQ的头像] [[XEP-0084#附录G:备注|6]] 和 [[XEP-0153|基于vCard的头像]] [[XEP-0084#附录G:备注|7]]. ==需求== 本文涉及以下的头像发布的用例: # 发布头像数据 # 更新当前头像的元数据 # 禁止头像 本文涉及以下头像订阅的用例: # 发现头像可用性 # 接收头像变更通知 # 通过pubsub获取头像数据 # 通过HTTP获取头像数据 ==基本处理流程== 发布和更新用户头像的流程如下: # 用户用 "image/png" content-type 格式发布头像数据到数据节点 data node,并可选的地发布其他格式 content-types 到 HTTP URLs. # 用户发布已更新头像通知到元数据节点 metadata node, 伴随 ItemID ,它是"image/png" content-type 的图像数据的 SHA-1 哈希值 (注意: 这是该图像数据本身的一个哈希, 而不是base64编码过的那个版本). # 订阅者接收通知. # 可选的 (且如果必要), 订阅者使用 pubsub retrieve-items 特性 (或通过 HTTP)从数据节点 data node 获取由 ItemID 标识的头像数据. # 可选的, 用户禁止头像显示. 这个处理流程在随后的章节描述得更加完整. 注意: 在发布头像数据和元数据之前, 用户必须 MUST 根据定义于 '''XEP-0163''' 的流程确定是否他或她的服务器支持pubsub的PEP子集,因为这个支持简化了头像发布. 以下例子假定PEP服务可用. ===用户发布数据=== 在更新头像元数据节点之前, 发布者必须 MUST m确保头像数据在数据节点或URL是可用的. 当发布头像数据到数据节点时, 发布者必须 MUST 确保 pubsub ItemID 是该"image/png" 格式数据的 SHA-1 哈希值 (这被订阅者用于决定是否可以使用本地缓存副本来显示). 以下例子展示发布头像数据到数据节点时发送的 XML 结构. '''例子 1. 发布头像数据到数据节点''' <source lang="xml"> <iq type='set' from='juliet@capulet.lit/chamber' id='publish1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='urn:xmpp:avatar:data'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <data xmlns='urn:xmpp:avatar:data'> qANQR1DBwU4DX7jmYZnncm... </data> </item> </publish> </pubsub> </iq> </source> '''例子 2. Pubsub服务应答成功 <source lang="xml"> <iq type='result' to='juliet@capulet.lit/chamber' id='publish1'/> </source> 如果头像将通过 HTTP 而不是 pubsub 数据节点可用, 发布者必须 MUST 要么检查这个 HTTP URL 是否存在头像数据,要么通过标准的 HTTP 方法发布它 (这些方法超出了本协议的范围; 反考 '''RFC 2616'''). ===用户发布元数据通知=== 任何时候发布者希望修改当前头像, 它必须 MUST 更新元数据节点. 以下例子显示的指定可用头像数据的元数据,仅针对一个格式 ("image/png") 并且只可在数据节点访问. '''例子 3. 发布头像元数据''' <source lang="xml"> <iq type='set' from='juliet@capulet.lit/chamber' id='publish2'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='urn:xmpp:avatar:metadata'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <metadata xmlns='urn:xmpp:avatar:metadata'> <info bytes='12345' id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' height='64' type='image/png' width='64'/> </metadata> </item> </publish> </pubsub> </iq> </source> 以下例子显示的指定可用头像数据的元数据,对一个 HTTP URL 可用. '''例子 4. 发布头像元数据''' <source lang="xml"> <iq type='set' from='juliet@capulet.lit/chamber' id='publish2'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='urn:xmpp:avatar:metadata'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <metadata xmlns='urn:xmpp:avatar:metadata'> <info bytes='23456' height='64' id='222f4b3c50d7b0df729d299bc6f8e9ef9066971f' type='image/gif' url='http://avatars.example.org/happy.gif' width='64'/> </metadata> </item> </publish> </pubsub> </iq> </source> ===订阅者接收元数据通知=== 接着用户的虚拟 virtual pubsub 服务将发送元数据通知给那些订阅了该用户的元数据节点的实体或那些声明拥有接收头像元数据能力的联系人(通过在 [[XEP-0115|实体能力]] [[XEP-0084#附录G:备注|8]] 中包含一个"urn:xmpp:avatar:metadata+notify"特性). '''例子 5. 订阅者接收头像元数据通知''' <source lang="xml"> <message to='romeo@montague.lit' from='juliet@capulet.lit'> <event xmlns='http://jabber.org/protocol/pubsub#event'> <items node='urn:xmpp:avatar:metadata'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <metadata xmlns='urn:xmpp:avatar:metadata'> <info bytes='12345' height='64' id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' type='image/png' width='64'/> </metadata> </item> </items> </event> <addresses xmlns='http://jabber.org/protocol/address'> <address type='replyto' jid='juliet@capulet.lit/chamber'/> </addresses> </message> </source> 如上所示, 取决于节点配置, 这个条目可以包含关于该发布资源的 [http://xmpp.org/extensions/xep-0033.html 扩展的节地址] [[XEP-0084#附录G:备注|9]] 信息(详见 '''XEP-0060''' ). ===订阅者获取数据=== 在接收到该通知后, 每个订阅者应该决定是否有一个该头像的本地缓存副本(它可以通过ItemID搜索一个图像标识符). 如果该订阅者已经有一个该头像的本地缓存副本, 它不能(MUST NOT)获取该图像数据. 如果该订阅者没有该头像图片的本地缓存副本, 它应该获取该数据. 它可以发送一个pubsub的 获取条目 请求给该数据节点, 指定适当的ItemID. '''例子 6. 订阅者通过ItemID请求最后的条目''' <source lang="xml"> <iq type='get' from='romeo@montague.lit/home' to='juliet@capulet.lit' id='retrieve1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='urn:xmpp:avatar:data'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'/> </items> </pubsub> </iq> </source> 运行在该用户的服务器上的PEP服务接着应该返回头像数据. '''例子 7. PEP服务返回头像数据''' <source lang="xml"> <iq type='result' from='juliet@capulet.lit' to='romeo@montague.lit/home' id='retrieve1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='urn:xmpp:avatar:data'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <data xmlns='urn:xmpp:avatar:data'> qANQR1DBwU4DX7jmYZnncm... </data> </item> </items> </pubsub> </iq> </source> 如果被发送给元数据节点的<info/>元素拥有一个'url'属性, 该头像数据位于一个URL. 所以, 为了获取那一内容类型的头像图片数据, 该请求实体必须发送一个HTTP请求给指定的URL. 干这事的方法超出了本协议的范围(见 '''RFC 2616''' ). ===发布者禁止头像发布=== 为了临时禁止头像发布, 该用户发布一个空的<metadata/>元素给该元数据节点. '''例子 8. 临时禁止头像发布''' <source lang="xml"> <iq type='set' from='juliet@capulet.lit/chamber' id='publish3'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='urn:xmpp:avatar:data'> <item> <metadata xmlns='urn:xmpp:avatar:metadata'/> </item> </publish> </pubsub> </iq> </source> 照旧, 该元数据的订阅者将接着收到该通知. '''例子 9. 订阅者获取头像元数据通知''' <source lang="xml"> <message to='romeo@montague.lit/home' from='juliet@capulet.lit'> <event xmlns='http://jabber.org/protocol/pubsub#event'> <items node='urn:xmpp:avatar:metadata'> <item> <metadata xmlns='urn:xmpp:avatar:metadata'/> </item> </items> </event> </message> </source> 注意: 在本协议的一个早期版本中, 用户通过发送包含一个<stop/>子元素的<metadata/>元素来表明它想禁止发布. 为了保持和其他PEP载荷格式的一致性, 对<stop/>元素的支持被废弃了. ==协议语法== pubsub的PEP子集要求在命名空间和节点之间将存在一对一的关系. 因为在这里定义的协议规定了两种节点的使用(一个用于头像数据一个用于头像元数据), 我们定义了两个命名空间, 每个都有一个相应的根元素: :* <data xmlns='urn:xmpp:avatar:data'/> :* <metadata xmlns='urn:xmpp:avatar:metadata'/> 更多定义如下. ===Data元素=== <data/>元素被用于通讯头像数据本身, 并只用于"image/png"内容类型(支持这个是必需的). <source lang="xml"> <data xmlns='urn:xmpp:avatar:data'> IMAGE DATA </data> </source> XML字符数据必须展示内容类型为"image/png"的头像的图片, 遵循[http://tools.ietf.org/html/rfc4648 RFC 4648][[XEP-0084#附录G:备注|10]]的第4章做Base64编码. (注意: Line feeds不应该(SHOULD NOT)被添加但是应该被接受.) <data/>元素不能(MUST NOT)拥有任何属性. 对<data/>元素的支持是必需的. ===Metadata元素=== <metadata/>元素被用于通讯关于该头像的信息. <metadata/>元素有两个允许的子元素: :* <info/> :* <pointer/> 更多定义如下. 另外, <metadata/>元素可以是空的(即, 不包含子元素); 这个格式被用于禁止头像发布. ====Info元素==== <info/>子元素被用于通讯头像元数据. 对<info/>元素的支持是必需的. <source lang="xml"> <metadata xmlns='urn:xmpp:avatar:metadata'> <info bytes='size-of-image-data-in-bytes' height='image-height-in-pixels' id='SHA-1-hash-of-image-data' type='content-type-of-image-data' url='HTTP-URL-for-image-data' width='image-width-in-pixels'/> </metadata> </source> <info/>子元素必须是空的. <info/>元素的已定义属性见下表. '''表1: Info Attributes''' {|border="1" cellspacing="0" !名称 !!定义 !!包含 |- |bytes ||图片数据的大小(以字节数计). ||必需 |- |height ||图片的高度(以像素计). ||推荐 |- |id ||对于指定的内容类型的图片数据的哈希值, 这里的哈希值的生成遵循[http://tools.ietf.org/html/rfc3174 RFC 3174] [[XEP-0084#附录G:备注|11]]定义的SHA-1机制(以二进制输出). ||必需 |- |type ||该图片数据的在IANA注册了的内容类型. ||必需 |- |url ||图片数据文件所在的 http: 或 https: URL ; 除非该图片数据文件能从HTTP获取,不能(MUST NOT)包含该属性. ||可选 |- |width ||该图片的宽度(以像素计) ||推荐 |} <metadata/>根元素可以包含多个<info/>元素. 每个<info/>元素必须为相同的头像图片指定元数据但是要以替代的内容类型(例如, "image/png", "image/gif", 和 "image/jpeg"), 并且格式之一必须是"image/png"以确保互操作性. 'type'属性的值必须是一个在IANA注册了的内容类型"image"或"video". [[XEP-0084#附录G:备注|12]] 对"image/png"内容类型的支持是必需的. 对"image/gif"和"image/jpeg"内容类型的支持是推荐的. 岁任何其他内容类型的支持是可选的. ====Pointer元素==== <pointer/>子元素被用于指向一个未通过pubsub或HTTP发布的头像, 但是相反由类似在线游戏系统或虚拟世界的第三方服务提供. <source lang="xml"> <metadata xmlns='urn:xmpp:avatar:metadata'> <pointer> ... APPLICATION-SPECIFIC DATA ... </pointer> </metadata> </source> 如果发布的应用有相关的信息,<pointer/>元素可以拥有以下属性: :* ''bytes'' -- 该图片数据的大小(以字节计). :* ''height'' -- 该图片的高度(以像素计). :* ''id'' -- 该图片数据用于指定内容类型的SHA-1哈希. :* ''type'' -- 该图片数据的在IANA注册了的内容类型. :* ''width'' -- 该图片的宽度(以像素计). <pointer/>元素的内容必须是一个正确使用命名空间的子元素以指定如何从第三方服务获取该头像的信息. 任何子元素的结构超出了本文的范围. 即使包含了<pointer>元素, 至少必须有一个<info/>元素的实例发生在它之前,这样不支持<pointer/>元素的实现能显示该头像的"后备"格式(最低限度, "image/png"). 对<pointer/>元素的支持是可选的. ==另外的例子== ===带多内容类型的Metadata=== 以下例子展示指定头像数据的元数据可用的多种格式("image/png", "image/gif", 和 "image/mng"), 这里"image/png"内容类型只可用在数据节点而其他内容类型可用于 HTTP URLs. '''例子 10. 发布头像元数据(多格式)''' <source lang="xml"> <iq type='set' from='juliet@capulet.lit/chamber' id='publish3'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='urn:xmpp:avatar:metadata'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <metadata xmlns='urn:xmpp:avatar:metadata'> <info bytes='12345' height='64' id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' type='image/png' width='64'/> <info bytes='12345' height='64' id='e279f80c38f99c1e7e53e262b440993b2f7eea57' type='image/png' url='http://avatars.example.org/happy.png' width='64'/> <info bytes='23456' height='64' id='357a8123a30844a3aa99861b6349264ba67a5694' type='image/gif' url='http://avatars.example.org/happy.gif' width='64'/> <info bytes='78912' height='64' id='03a179fe37bd5d6bf9c2e1e592a14ae7814e31da' type='image/mng' url='http://avatars.example.org/happy.mng' width='64'/> </metadata> </item> </publish> </pubsub> </iq> </source> 在前述的例子中, 以"image/png"内容类型封装的图片同时可用于一个pubsub数据节点和一个HTTP URL; 所以它被包含了两次(第二次带了一个'url'属性). ===带Pointer的Metadata=== 以下例子展示元数据指定在数据节点可用的"image/png"头像数据,同时也带有一个指针指向外部服务. '''例子 11. 发布头像元数据(带指针)''' <source lang="xml"> <iq type='set' from='juliet@capulet.lit/chamber' id='publish4'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='urn:xmpp:avatar:metadata'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <metadata xmlns='urn:xmpp:avatar:metadata'> <info bytes='12345' height='64' id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' type='image/png' width='64'/> <pointer> <x xmlns='http://example.com/virtualworlds'> <game>Ancapistan</game> <character>Kropotkin</character> </x> </pointer> </metadata> </item> </publish> </pubsub> </iq> </source> ==服务查询== ===查询头像可用性=== pubsub "auto-subscribe" 和 "filtered-notifications" 特性允许一个联系人自动订阅一个用户的头像. 无论如何, 一个联系人也能显式地决定是否另一个用户使用本协议发布头像,通过发送一个[[XEP-0030|服务查询]] [[XEP-0084#附录G:备注|13]] 条目 ("disco#items") 请求给该用户的春JID <localpart@domain.tld>. '''例子 12. 查询条目请求''' <source lang="xml"> <iq type='get' from='romeo@montague.lit/orchard' to='juliet@capulet.lit' id='items1'> <query xmlns='http://jabber.org/protocol/disco#items'/> </iq> </source> 如果该用户发布头像数据到一个PEP节点, 结果必须包含适当的条目. '''例子 13. 查询条目结果''' <source lang="xml"> <iq type='result' from='juliet@capulet.lit' to='romeo@montague.lit/orchard' id='items1'> <query xmlns='http://jabber.org/protocol/disco#items'> <item jid='juliet@capulet.lit' node='urn:xmpp:avatar:data'/> <item jid='juliet@capulet.lit' node='urn:xmpp:avatar:metadata'/> </query> </iq> </source> 该联系人接着可以根据'''XEP-0060'''中定义的协议订阅该元数据节点. 无论如何, 该联系人不应该(SHOULD NOT)订阅该数据节点(反之, 它应该简单地在需要的时候从那个节点获取条目, 如上所述). ==实现备注== ===多资源=== 如果一个用户同一时间有多个资源, 每个资源可以发布一个不同的头像. PEP服务应该包含上述的正在发布的资源的"replyto"地址,这样易于区分这个头像和前一个资源的头像. ===头像同步=== 当一个用户以一个新的资源登陆并且之前发布了一个头像, 它的客户端应该获取它最近发布的头像, 要么通过自动发送带有合适的实体可用性信息的出席信息(见 '''XEP-0115''')要么使用'''XEP-0060'''所述的"retrieve-items"方法. ===图片处理=== 决定获取哪个头像格式(例如, "image/gif"而不是"image/png")和决定获取的适当方法(例如, HTTP而不是pubsub)是接收的应用的责任. 接收的应用显示一个图片的时候不应该(SHOULD NOT)拉伸它. 如果一个头像对一个联系人不可用, 接收应用可以显示该联系人的相片, 例如, 在联系人的vCard中提供的(见[[XEP-0054|vcard-temp]] [[XEP-0084#附录G:备注|14]]) 或其他个人信息. ==安全事项== 关于和基础的传输协议相关的安全事项见'''XEP-0060'''和'''XEP-0163'''. 有可能SHA-1哈希机制的输出会导致冲突; 无论如何, 使用SHA-1生成头像数据的哈希不是安全的关键. ==IANA事项== 本文使用了IANA注册的内容类型, 但是不要求和[http://www.iana.org/ 互联网编号分配授权机构(IANA)] [[XEP-0084#附录G:备注|15]]交互. ==XMPP注册处事项== ===协议命名空间=== [http://xmpp.org/registrar/ XMPP注册处] [[XEP-0084#附录G:备注|16]] 已经把"urn:xmpp:avatar:data"和"urn:xmpp:avatar:metadata"包含在它的协议命名空间的注册项中(见 <http://xmpp.org/registrar/namespaces.html>). ==XML Schema== ===Data命名空间=== <source lang="xml"> <?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:xmpp:avatar:data' xmlns='urn:xmpp:avatar:data' elementFormDefault='qualified'> <xs:annotation> <xs:documentation> The protocol documented by this schema is defined in XEP-0084: http://www.xmpp.org/extensions/xep-0084.html </xs:documentation> </xs:annotation> <xs:element name='data' type='xs:base64Binary'/> </xs:schema> </source> ===Metadata命名空间=== <source lang="xml"> <?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:xmpp:avatar:metadata' xmlns='urn:xmpp:avatar:metadata' elementFormDefault='qualified'> <xs:annotation> <xs:documentation> The protocol documented by this schema is defined in XEP-0084: http://www.xmpp.org/extensions/xep-0084.html </xs:documentation> </xs:annotation> <xs:element name='metadata'> <xs:complexType> <xs:choice> <xs:sequence minOccurs='0' maxOccurs='1'> <xs:element ref='info' minOccurs='1' maxOccurs='unbounded'/> <xs:element ref='pointer' minOccurs='0' maxOccurs='unbounded'/> </xs:sequence> </xs:choice> </xs:complexType> </xs:element> <xs:element name='info'> <xs:complexType> <xs:simpleContent> <xs:extension base='empty'> <xs:attribute name='bytes' type='xs:unsignedShort' use='required'/> <xs:attribute name='height' type='xs:unsignedByte' use='optional'/> <xs:attribute name='id' type='xs:string' use='required'/> <xs:attribute name='type' type='xs:string' use='required'/> <xs:attribute name='url' type='xs:anyURI' use='optional'/> <xs:attribute name='width' type='xs:unsignedByte' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='pointer'> <xs:complexType> <xs:sequence> <xs:any namespace='##other'/> </xs:sequence> </xs:complexType> </xs:element> <xs:simpleType name='empty'> <xs:restriction base='xs:string'> <xs:enumeration value=''/> </xs:restriction> </xs:simpleType> </xs:schema> </source> ==作者备注== Peter Millard, 本协议从版本0.1到版本0.7的作者, 去世于 April 26, 2006. 剩下的作者们感谢他在用户头像方面的工作. ==附录== ===附录A:文档信息=== ===附录B:作者信息=== {{Template:XEP附录CDEF}} ===附录G:备注=== ===附录H:修订历史===
该页面使用的模板:
模板:XEP附录CDEF
(
查看源代码
) (保护)
返回到
XEP-0084
。
查看
页面
讨论
查看源代码
历史
个人工具
登录/创建账户
导航
首页
社区专页
新闻动态
最近更改
随机页面
帮助
XMPP资源
XMPP公共服务
XMPP客户端软件
XMPP服务器软件
友情链接
搜索
工具箱
链入页面
链出更改
特殊页面