xmpp协议的使用
- 格式:doc
- 大小:1.79 MB
- 文档页数:46
在android里面用的smack包其实叫做asmack,该包提供了两种不同的连接方式:socket和httpclient。
该并且提供了很多操作xmpp协议的API,也方便各种不同自定义协议的扩展。
我们不需要自己重新去定义一套接收机制来扩展新的协议,只需继承然后在类里处理自己的协议就可以了。
而本文今天主要说两点,一点就是消息是如何接收的,另一点就是消息是如何通知事件的。
总的思路1.使用socket连接服务器2.将XmlPullParser的数据源关联到socket的InputStream3.启动线程不断循环处理消息4.将接收到的消息解析xml处理封装好成一个Packet包5.将包广播给所有注册事件监听的类逐步击破(声明在看下面的文章时,最好先理解一下smack的使用,这样才能达到深入的理解)(谨记:上图只显示本文章解释所要用到的类和方法,减缩了一些跟本文主题无关的代码,只留一条贯穿着从建立连接到接收消息的线。
)解析这块东西打算从最初的调用开始作为入口,抽丝剥茧,逐步揭开。
1.PacketListener packetListener = new PacketListener() {@Overridepublic void processPacket(Packet packet) {System.out.println("Activity----processPacket"+ packet.toXML());}};PacketFilter packetFilter = new PacketFilter() {@Overridepublic boolean accept(Packet packet) {System.out.println("Activity----accept"+packet.toXML());return true;}};解释:创建包的监听以及包的过滤,当有消息到时就会广播到所有注册的监听,当然前提是要通过packetFilter的过滤。
XMPP协议即时通讯(Openfire服务器版)一、什么是XMPPXMPP(Extensible Messageing and Presence Protocol:可扩展消息与存在协议)是目前主流的IM(IM:instant messaging,即时消息)协议之一。
XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在XML 环境中灵活的发展性。
XMPP中定义了三个角色,客户端,服务器,网关。
通信能够在这三者的任意两个之间双向发生。
服务器同时承担了客户端信息记录,连接管理和信息的路由功能。
网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信),MSN,ICQ 等。
XMPP即时通信协议,采用C/S体系结构。
基本的网络形式是客户端连接到服务器,然后由服务器去连接到另一个客户端进行两个客户端之间的通信。
而他们传输的是XML流。
XMPP工作原理说明: 所有从一个客户端到另一个客户端的消息和数据都要通过服务器。
1、客户端连接服务器2、服务器利用本地目录系统的证书对其认证3、客户端制定目标地址,让服务器告知目标状态4、服务器查找,连接并进行相互认证5、客户端间进行交互二、搭建服务器(Openfire)通过上述的了解,我们知道要想进行通信,我们必须要有一个服务器。
服务器端采用Openfire作为服务器。
允许多个客户端同时登录并且并发的连接到一个服务器上。
服务器对每个客户端的连接进行认证,对认证通过的客户端创建会话,客户端与服务器端之间的通信就在该会话的上下文中进行。
首先安装Openfire点击继续点击安装安装成功后再偏好设置中就会有Openfire的图标。
点击Openfire的图标如果第一次安装Openfire,会发现Openfire的状态是停止的。
点击StartOpenfire,开启Openfire服务器注:如果Openfire一直打不开,请参考:/winer888/article/details/49886281当Status成为Running。
xmpp协议详解一:xmpp基本概念概述XMPP是一个开放式的XML协议,设计用于准实时消息和出席信息以及请求-响应服务。
通用的架构通常采用客户端服务器架构进行实现,其中客户端通过TCP方式使用XMPP访问服务器,服务器之间也采用TCP方式进行通信。
xmpp通用架构服务器充当xmpp通信的一个智能抽象层,负责•对受验证的客户端,服务器以及其他实体之间以xml流的形式的连接和会话进行管理。
•在这些实体间使用xml流对合理编址的xml节进行路由•存储和处理客户端使用的数据客户端通过TCP连接直接连接到服务器,并通过xmpp获得由服务器以及联合服务器所提供的全部功能。
多个不同的客户端可以同时登陆并且并发的连接到一个服务器,每个不同资源的客户端通过xmpp地址的资源标识符来区分。
建议的客户端和服务器连接的端口时5222网关网关是一个特殊用途的服务器端的服务,主要功能是把xmpp翻译成外部消息系统,并把返回的消息翻译成xmpp.网络每个服务器都是由一个网络地址来标识的并且服务器之间的通信是客户-服务器协议的直接拓展。
任意两个服务器之间的通信是可选的,如果被激活,那么这种通信应该通过XML流绑定到TCP连接上进行。
建议的服务器和服务器连接的端口时5269注xmpp系统涉及更多的域间连接,当你给不在同一个域中的联系人发送xmpp消息时,你的客户端连接到你的“家用”服务器,然后直接连接到你的联系人的服务器,而没有中间跳过。
地址空间概述因为xmpp通讯实在网络上,所以每个xmpp实体都需要一个地址,称为JabberID(JID)。
一个合法的JID包括一组排列好的元素,包括域名(domain identifier), 节点名(node identifier), 和资源名(resource identifier)。
user@host/resource这种结构,最常用来标识一个即时消息用户,这个用户所连接的服务器,以及这个用户用于连接对资源。
xmpp协议详解摘要:此文档定义了可扩展消息出席协议(XMPP)的核心特性:协议使用XML元素在任意两个网络端点间近实时的交换结构化信息。
当XMPP为交换XML数据提供一般化,可扩展的框架时,它主要用于建立满足RFC2779的即时消息与出席应用的需求。
1 介绍1.1 概要XMPP是一个开放的可扩展标记语言[XML]协议,用于近实时的消息、出席与请求-响应服务。
基本语法语义最初是由Jabber开源社区在1999年开发的。
2002年,XMPP工作组授权开发一个Jabber协议的改写本,将适用于IETF的即时消息(IM)与出席技术。
作为XMPP工作组的成果,此文档定义了XMPP 1.0的核心内容;提供即时消息与出席功能的扩展需求定义在RFC2779[IM-REQS]中,由XMPP:即时消息与出席[XMPP-IM]指定。
1.2 术语文档中的大写关键字:"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL"在BCP14, 在RFC 2119 [TERMS]中描述。
2 一般架构2.1 概述虽然XMPP并未与任何特定网络架构结合,但到目前为止,它大致上已经由一个客户-服务器的架构实现了。
其中,客户端利用XMPP访问基于[TCP]连接的一个服务器,并且,服务器间也通过TCP连接进行彼此间的通信。
XMPPClient------------Server------------ServerTCP TCP下图为此架构的高层视图(“-”表示使用XMPP通信,“=”表示使用任何其它协议通信)C1----S1---S2---C3|C2----+--G1===FN1===FC1符号表示如下:1)C1,C2,C3 = XMPP客户端2)S1,S2 = XMPP服务器3)G1 = 网关:在XMPP与外部协议(非XMPP)的消息网络间转换。
RFC3920可扩展的消息和出席信息协议(GMPP):核心协议关于本文的说明本文为互联网社区定义了一个互联网标准跟踪协议,并且申请讨论协议和提出了改进的建议。
请参照“互联网官方协议标准”的最新版本( STD1 )获得这个协议的标准化进程和状态。
本文可以不受限制的分发。
版权声明本文版权属于互联网社区(C)TheInternetSocietP(20GG).摘要本文定义了可扩展消息和出席信息协议(GMPP )的核心功能,这个协议采用 GML流实现在任意两个网络终端接近实时的交换结构化信息。
GMPP提供一个通用的可扩展的框架来交换GML数据,它主要用来建立即时消息和出席信息应用以实现RFC2779的需求。
目录1. 绪论2. 通用的架构3. 地址空间4. GML 流5. TLS的使用6. SASL的使用7. 资源绑定8. 服务器回拨9. GML 节10. 服务器处理GML节的规则11. GMPP中的GML用法12. 核心的兼容性要求13. 国际化事项14. 安全性事项15. IANA 事项16. 参考1. 绪论1.1. 概览GMPP是一个开放式的GML协议,设计用于准实时消息和出席信息以及请求- 响应服务。
其基本的语法和语义最初主要是由Jabber开放源代码社区于1999年开发的。
20GG年,GMPP工作组被授权接手开发和改编 Jabber协议以适应 IETF的消息和出席信息技术。
作为GMPP工作组的成果,本文定义了 GMPP1.0 的核心功能;在RFC2779[IMP-REQS]中指定的提供即时消息和出席信息功能的扩展,定义在GMPP-IM 协议[theEGte nsibleMessagi ngan dPrese nceProtocol(GMPP):l nsta ntMessagi ng andPresenee]中。
1.2. 术语本文中大写的关键字"MUST","MUSTNOT","REQUIRED","SHALL","SHALLNOT","SHOULD","SH OULDNOT","RECOMMENDED","MAP", 和"OPTIONAL"的确切含义符合BCP14,RFC2119[TERMS].2. 通用的架构2.1. 概览尽管GMPP没有结合任何特定的网络结构,通常认为它是客户-服务器架构的一种实现,在这里客户端用GMPP的方式访问服务器采用的是TCP连接,服务器之间的通信也是TCP连接。
RFC3920可扩展的消息和出席信息协议 (XMPP): 核心协议关于本文的说明本文为互联网社区定义了一个互联网标准跟踪协议,并且申请讨论协议和提出了改进的建议。
请参照“互联网官方协议标准”的最新版本(STD 1)获得这个协议的标准化进程和状态。
本文可以不受限制的分发。
版权声明本文版权属于互联网社区 (C) The Internet Society (2004).摘要本文定义了可扩展消息和出席信息协议(XMPP)的核心功能,这个协议采用XML 流实现在任意两个网络终端接近实时的交换结构化信息。
XMPP提供一个通用的可扩展的框架来交换XML数据,它主要用来建立即时消息和出席信息应用以实现RFC 2779 的需求。
目录1.绪论2.通用的架构3.地址空间4.XML流5.TLS的使用6.SASL的使用7.资源绑定8.服务器回拨9.XML节10.服务器处理XML节的规则11.XMPP中的XML用法12.核心的兼容性要求13.国际化事项14.安全性事项15.IANA事项16.参考1. 绪论1.1. 概览XMPP是一个开放式的XML协议,设计用于准实时消息和出席信息以及请求-响应服务。
其基本的语法和语义最初主要是由Jabber开放源代码社区于1999年开发的。
2002年,XMPP工作组被授权接手开发和改编Jabber协议以适应IETF的消息和出席信息技术。
作为XMPP工作组的成果,本文定义了 XMPP 1.0 的核心功能;在 RFC 2779 [IMP-REQS] 中指定的提供即时消息和出席信息功能的扩展,定义在 XMPP-IM 协议 [the Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence] 中。
1.2. 术语本文中大写的关键字 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 和 "OPTIONAL" 的确切含义符合 BCP 14, RFC 2119 [TERMS].2. 通用的架构2.1. 概览尽管XMPP没有结合任何特定的网络结构,通常认为它是客户-服务器架构的一种实现,在这里客户端用XMPP的方式访问服务器采用的是TCP连接,服务器之间的通信也是TCP连接。
XMPP与TLS安全协议简介XMPP(Extensible Messaging and Presence Protocol)是一种开放的标准通信协议,用于实时的基于XML(可扩展标记语言)的消息传输和在线状态监测。
而TLS(Transport Layer Security)是一种加密通信协议,用于保护互联网通信的安全性。
本文将简要介绍XMPP和TLS协议以及它们在保障通信安全方面的重要性。
一、XMPP简介XMPP是一种开放的、分布式的协议,最初用于即时通讯(IM)系统。
它通过基于XML的消息格式,使得用户能够实时地发送文本、音频、视频和其他形式的多媒体内容。
XMPP协议具有灵活、可扩展的特点,可以适应不同的业务需求。
它支持用户认证、状态通知、好友列表管理等功能,使得各种即时通讯应用得以实现。
二、TLS简介TLS(Transport Layer Security)是一种设计用于保护通信安全的加密协议。
其前身是SSL(Secure Sockets Layer),目前TLS已经成为SSL的更安全的继任者。
TLS协议通过在通信双方之间建立安全的连接,保护数据在传输过程中不被窃听、篡改或伪造。
TLS协议提供了许多安全机制,包括数据加密、身份验证和完整性检查等。
它使用了非对称加密和对称加密相结合的方式,确保了通信过程中的保密性和完整性。
TLS的广泛应用使得网页浏览、电子邮件、即时通讯等互联网应用能够在保护用户隐私的前提下进行。
三、XMPP与TLS协议XMPP协议本身并不具备数据加密和身份验证等安全机制,因此在实际应用中往往需要与TLS协议结合使用,以保障通信的安全性。
通过在XMPP与客户端之间建立TLS连接,通信双方之间的数据传输将得到加密保护,确保敏感信息不会被黑客窃取。
同时,TLS协议还提供了数字证书验证机制,用于验证通信双方的身份,防止中间人攻击。
使用TLS协议的XMPP通信可以保证数据传输的机密性和完整性,并且能够确认消息发送方的身份,增强通信的可信度和安全性。
XMPP 协议工作流程详解分类:翻译文章2014-04-23 11:11 2221人阅读评论(0) 收藏举报原文: .au/content/how-xmpp-works-step-step作者: Yilun Fan, 日期2011-01-05 13:09XMPP 核心协议/rfcs/rfc3920.htmlXMPP 要点.∙ 1. 客户端(C) 和服务器端(S) 通过TCP连接5222端口进行全双工通信.∙ 2. XMPP 信息均包含在XML streams中.一个XMPP会话, 开始于<stream> 标签, 并结束于</stream>标签.所有其他的信息都位于这俩标签之间.∙ 3. 出于安全目的考虑, 开始<stream>之后, 后续的内容会被适度的使用Transpor Layer Security (TLS) 协商传输和强制性的Simple Authentication 和SecurityLayer (SASL) 协商传输.∙ 4. SASL协商完成后, 一个新的stream 将会被迅速打开, 它将会更加安全和保密.第一步: 打开 streamClient: 客户端发送打开stream 的片段到服务器, 请求一个新的session.[html]view plaincopy1.<stream:stream to=''xmlns='jabber:client'xmlns:stream='http://e/streams'version='1.0'>这里“” 是客户端试图连接的服务器的域名.Server: Server 返回XML stream, 以<stream:freatures> 开头, 包含要求TLS 或者SASL 协商谈判之一, 或者2个都要求.[html]view plaincopy1.<stream:features>2.<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>3.<required/>4.</starttls>5.<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>6.<mechanism>DIGEST-MD5</mechanism>7.<mechanism>PLAIN</mechanism>8.<mechanism>EXTERNAL</mechanism>9.</mechanisms>10.</stream:features>第二步: 加密和认证.2.1 如果服务器需要 TLS 交涉.Client: 客户端发送STARTTLS 到服务器.[html]view plaincopy1.<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>Server: 服务器返回消息显示TLS 已被允许:[html]view plaincopy1.<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>或者TLS失败了:[html]view plaincopy1.<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/></stream:stream>在失败的情况下, 服务器会关闭TCP 连接.Client: 如果TLS 已被服务器正确处理, 客户端发送请求一个新的session:1.<stream:stream xmlns='jabber:client'xmlns:stream='/streams'to=''version='1.0'>Server: 服务器响应一个XML stream, 指示是否需要SASL 交涉.[html]view plaincopy1.<stream:stream xmlns='jabber:client'xmlns:stream='/streams'from=''id='c2s_234'version='1.0'>2.<stream:features>3.<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>4.<mechanism>DIGEST-MD5</mechanism>5.<mechanism>PLAIN</mechanism>6.<mechanism>EXTERNAL</mechanism>7.</mechanisms>8.</stream:features>2.2 SASL 交涉Client 客户端需要选择一个服务器上有效的认证方式来携带SASL交涉数据, 上面的情况, “DIGEST-MD5“, “PLAIN” 和“EXTERNAL” 是一些可选项.“PLAIN” 认证模式是三者之中最简单的了. 它是这样工作的:Client: 客户端按照自己选择的认证模式发送一个将用户名和密码以base64编码的stream.用户名和密码按这种格式组织:[html]view plaincopy1.“\0UserName\0Password”.例如我想以用户名为“mbed@”登录, 密码是“mirror”. 那么, 在进行base64编码之前, 用户名和密码按照上面的格式组织为一个新的字符串,“\0mbed\0mirror”, 再进行base64编码, 得到字符串“AG1iZWQAbWlycm9y”.然后, 客户端发送下列stream 到服务器.1.<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'mechanism='PLAIN'>AG1iZWQAbWlycm9y</auth>Server: 如果服务器接受了认证信息, 服务器会发回带“success”标签的stream.[html]view plaincopy1.<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>或者:Server: 如果密码和用户名不匹配, 或者上面的base64编码有错误, 服务器发回错误信息的stream.[html]view plaincopy1.<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>“DIGEST-MD5” 认证模式的具体方法可以在这里找到: /rfc/rfc2831.txt.第三步: 资源绑定(可选)Client: 客户端要求服务器绑定一个资源(可以理解为客户端的类型, 比如电脑, 手机, Web 应用等):[html]view plaincopy1.<iq type='set'id='bind_1'>2.<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>3.</iq>或者Client: 客户端自己绑定一个资源:[html]view plaincopy1.<iq type='set'id='bind_2'>2.<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>3.<resource>someresource</resource>4.</bind>5.</iq>Server: 服务器发回另外一个<iq>片段, 如果“type” 标签的内容是“result”, 说明绑定是成功的, 否则说明绑定失败.[html]view plaincopy1.<iq type='result'id='bind_2'>2.<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>3.<jid>somenode@/someresource</jid>4.</bind>5.</iq>第四步: 请求一个新的session在SASL 交涉完成之后或者可选资源绑定之后, 客户端必须建立一个session 来开始即时消息发送和接收.Client: 客户端向服务器发送请求:[html]view plaincopy1.<iq to=''type='set'id='sess_1'>2.<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>3.</iq>Server: 服务器发回一个<iq> 片段表明session 是否成功创建.创建成功的消息类似于:[html]view plaincopy1.<iq from=''type='result'id='sess_1'/>如果服务器未能创建session, 服务器将会回复一个如下消息或者其他类型的错误消息.[html]view plaincopy1.<iq from=''type='error'id='sess_1'>2.<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>3.<error type='auth'>4.<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>5.</error>6.</iq>第五步: 客户端和服务器交换 XMPP 片段如果以上步骤均成功完成, 那么客户端就可以发送XMPP 片段到服务器和接收XML stream了.客户端可以发送<iq> 片段来向服务器请求roster 或者其他信息. 并可以使用<presence> 片段来改变客户端的presence 状态(比如在线, 离开等)即时消息和其他的负载可以通过发送<message> 片段来完成.第六步: 关闭 stream最后, 如果客户端想要结束聊天和关闭XMPP session, 客户端需要发送一个关闭stream 的片段到服务器.[html]view plaincopy1.<presence type='unavailable'/>2./stream:stream>然后, 服务器将会改变客户端的presence 状态为“Offline” , 并且关闭和客户端的TCP 连接.。
一、开发背景1、国际背景随着技术的高速发展,即时通信已经成为一种广泛使用的通信方式。
1996年i lis公司推出了世界上第一个即时通信系统 ICQ,不到10年间,即时通信( g ing,简称IM)以发展成为了最流行的网络应用之一。
特别是近几年的迅速发展,即时通信的功能日益丰富,它不再是个单纯的聊天工具,它已经发展成集交流、资讯、娱乐、音乐、电视、游戏、电子商务等为一体的综合化信息平台。
2、国内背景目前国内外及时通信软件IM( n ger )形势风起云涌,可谓战况空前,IM作为继和Web之后最主要的互联网基础应用之一,为商家必争之地。
国内的形势由于QQ的垄断性优势明显,表面稍显平静,实则暗流涌动。
目前来看,胖企鹅公司以压倒性优势占据了国内IM市场近八成份额,并且紧紧抓住低端市场,用户数量庞大,盈利丰厚。
其他的微软(WLM)、网易O、新浪UC、 、等占有率较为惨烈,还有雅虎即时通、AIM、ICQ以及传闻中的a idu IM和搜狐搜Q以及一些目前并不出名的如校内网的校内通,Lava-lava等等等等,凡在国内叫得上号的叫不上号的互联网企业,几乎没有不推IM的,甚至连中国移动都力推飞信,希望分得一杯羹。
然而这些即时通讯不能实现互联互通,限制了用户的扩展。
3、为什么选择X MPP协议虽然现在即时通信软件有很多,但是它们之间不能互联互通也阻碍了及时通信用户的继续扩展。
因此,在现阶段的各种即使通信服务,没有统一的标准,无法实现互联互通的局面下,而c ol)协议的出现,实现了整个及时通信服务协议的互通。
有了这个协议之后,使用任何一个组织或者个人提供的即使通信服务,都能够无障碍的与其他的及时通信服务的用户进行交流。
例如g le 公司5年推出的e talk就是一款基于X MPP协议的即使通信软件。
目前IM即时通信有四种协议:1.即时信息和空间协议(IMPP)2.空间和即时信息协议(PRIM)3.针对即时通讯和空间平衡扩充的进程开始协议S IP4.XMPP协议:该协议的前身是b er,我们采取M PP协议主来实现M主要是考虑协议是以M L为基础的,它继承了在X ML环境中灵活的发展性。
XMPP——Smack[1]连接、登陆及账户操作临毕业前,应需求,花了三天写了个小的聊天工具,貌似简陋得很….若有机会再完善吧,目前毕业季,处理毕业事宜,还要准备即将的入职。
眼瞅着大学四年就这么结束了,哎。
开始吧,四篇博文简单介绍下基本实现,由于时间有限,功能不是十分丰富,有兴趣的同学自己研究下协议和具体的实现需求:基于XMPP的IM工具,需实现和gtalk实现通信,需实现同spark的通信,需架设服务器,实现同自身客户端的通信,传文件,视频聊天写完未实现需要改进的地方:离线消息,离线文件一、XMPPXMPP : The Extensible Messaging and Presence Protocol中文全称:可扩展通讯和表示协议简介:可扩展通讯和表示协议(XMPP) 可用于服务类实时通讯、表示和需求 - 响应服务中的 XML 数据元流式传输。
XMPP 以 Jabber 协议为基础,而 Jabber 是即时通讯中常用的开放式协议。
二、SmackSmack是一个开源,易于使用的XMPP(jabber)客户端类库。
Smack API, 是一个Java 的XMPP Client Library,也是由Jive Software开发。
优点:编程简单。
缺点:API并非为大量并发用户设计,每个客户要1个线程,占用资源大,1台机器只能模拟有限(数千个)客户.smack是一个用 java 写的XMPP客户端代码库, 是 spark 的核心.二、连接及断开基本方法XMPPConnection connection = new XMPPConnection("");connection.connect();实现的方法[java] view plaincopyprint?1.public static XMPPConnection getConnection(String domain) throws XMPPException {2.XMPPConnection connection = new XMPPConnection(domain);3.connection.connect();4.return connection;5.}6.public static XMPPConnection getConnection(String domain,int port) throws XMPPException {7.ConnectionConfiguration config = new ConnectionConfiguration(domain,port);8.XMPPConnection connection = new XMPPConnection(config);9.connection.connect();10.return connection;11.}断开connection.disconnect();四、登陆connection.login("**********************", "*****");五、账户操作可以对账户进行基本操作,包括注册,注销,修改密码[c-sharp] view plaincopyprint?1./**2.* 注册用户3.* @param connection4.* @param regUserName5.* @param regUserPwd6.* @return7.*/8.public static boolean createAccount(XMPPConnection connection,String regUserName,String regUserPwd)9.{10.try {11.connection.getAccountManager().createAccount(regU serName, regUserPwd);12.return true;13.} catch (Exception e) {14.return false;15.}16.}17./**18.* 删除当前用户19.* @param connection20.* @return21.*/22.public static boolean deleteAccount(XMPPConnection connection)23.{24.try {25.connection.getAccountManager().deleteAccount();26.return true;27.} catch (Exception e) {28.return false;29.}30.}31./**32.* 删除修改密码33.* @param connection34.* @return35.*/36.public static boolean changePassword(XMPPConnection connection,String pwd)37.{38.try {39.connection.getAccountManager().changePassword(pwd);40.return true;41.} catch (Exception e) {42.return false;43.}44.}。
XMPP协议中文参考指南绪论概览XMPP是一个流化XML[XML]元素的协议,用于准实时的交换消息和出席信息。
XMPP 的核心功能定义在Extensible Messaging and Presence Protocol (XMPP): Core [XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]. 这些功能-- 主要是XML流, 使用TLS和SASL,以及流的根元素之下的<message/>, <presence/>, 和<iq/> 子元素-- 为各种类型的准实时应用提供了一个构造基础, 它可以被放在核心的顶层,使用特定XML名字空间[XML-NAMES]发送特定的应用数据. 本文描述XMPP核心功能的扩展和应用,XMPP核心功能提供了RFC 2779 [IMP-REQS]定义的基本的即时消息和出席信息功能。
需求为了达到本文的目的, 基本的即时消息和出席信息应用的需求定义在[IMP-REQS],它是一个高阶的规定,一个用户必须完成以下用例:∙和其他用户交换消息∙和其他用户交换出席信息∙管理和其他用户之间的订阅和被订阅∙管理联系人列表中的条目(在XMPP 中这被称为"roster")∙屏蔽和特定的其他用户之间的通信(出或入)这些功能领域的详细定义在[IMP-REQS]中, 感兴趣的用户可以直接阅读原文关于需求方面的内容。
[IMP-REQS]也规定出席信息服务必须从即时消息服务中分离; 例如, 它必须可能用这个协议来提供一个出席信息服务,一个即时消息服务,或同时提供两者. 尽管本文假定实现和部署希望提供统一的即时消息和出席信息服务, 但没有要求一个服务必须同时提供出席信息服务和即时消息服务, 并且协议也提供了把出席信息服务和即时消息服务分离成为独立服务的可能性.注意: 虽然基于XMPP的即时消息和出席信息符合[IMP-REQS]的要求,但它不是特意为那个协议设计的,因为基础协议是在RFC 2779成文之前通过Jabber开放源代码社区的一个开放的开发过程发展出来的. 也请注意尽管在Jabber社区发展的协议中定义了许多其他方面的功能,但是这些协议不包含在本文之中,因为它们不是[IMP-REQS]所要求的.术语本文继承了[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]定义的术语.大写关键字"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 和"OPTIONAL" 在本文中的含义定义在BCP 14, RFC 2119 \[TERMS\].XML 节的语法符合'jabber:client'和'jabber:server'名字空间的XML节的基本语义和通用属性已经在[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]中定义了. 无论如何, 这些名字空间也定义了yixie其他的子元素, 比如通用属性'type'的值, 对于即时消息和出席信息应用就是特殊的. 因而, 在选择用于这类应用的特定用例之前, 我们在这里需要先描述一下XML节的语法, 用来补充[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]中的讨论.消息语法符合'jabber:client' or 'jabber:server'名字空间的消息节用于"推" 信息到另一个实体.在即时消息应用中通常的用法是包含,一个单独的消息,在一个聊天会话中的消息,一个多用户聊天室的上下文中的消息,标题或其他警告和错误的消息,消息的类型一个消息节的'type' 属性是建议的(RECOMMENDED); 如果包含了它,它指明这个消息的会话上下文,从而提供一个关于表达的线索(例如, 在一个GUI中). 如果包含了它, 'type' 属性必须(MUST)是以下的值之一 :∙chat -- 消息是在一对一聊天会话的语境被发送. 一个兼容的客户端应该(SHOULD)在一个允许两个实体进行一对一聊天的界面中显示消息,包括适当的会话历史.∙error -- 发生了一个和上次发送者发送的消息有关的错误(关于节错误语法的详细信息, 参考[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]).一个兼容客户端应该(SHOULD)在一个适当的界面展示它以通知发送者这个错误的种类.∙groupchat -- 消息是在一个多用户聊天环境的语境下发送的(类似\[IRC\]). 一个兼容客户端应该(SHOULD)在允许多对多聊天的界面显示这个消息,包括, 包括这个聊天室的名册和适当的会话历史. 基于XMPP的群聊协议的完整定义超出了本文的范围.∙headline -- 一个消息可能是由一个递送或广播内容的自动化服务生成的(新闻, 体育, 市场信息, RSS feeds, 等等.). 这个消息是不需要回复的, 一个兼容客户端应该(SHOULD) 在一个适当的和单独消息,聊天会话,或群聊会话不同的界面显示这个消息(例如, 不给接收者提供回复能力).normal -- 这个消息是一个在一对一会话或群聊会话之外的单独消息, 并且它希望接收者能够回复.一个兼容客户端应该(SHOULD)在一个允许接收者回复的界面显示这个消息, 但不需要会话历史.一个IM 应用应该(SHOULD)支持所有前述的消息类型;如果一个应用接收了一个没有'type'属性的消息或这个应用不理解'type'属性的值, 它必须(MUST)认为这个消息是一个"normal" 类型(如,"normal" 是缺省的). "error"类型必须(MUST)仅仅在应答一个和从别的实体接收到的消息有关的错误时生成.尽管'type'属性是可选的(OPTIONAL), 处于礼貌原因对于消息的任何回复总是和原来的消息同一类型;此外, 一些特殊的应用(例如, 一个多用户聊天服务) 可以(MAY)根据它们的判断强制特定消息类型的使用(例如, type='groupchat').子元素正如扩展名字空间extended namespaces(第二章第四节)所述, 一个消息节可以(MAY)包含任何适当名字空间的子元素.和缺省名字空间声明一致, 缺省消息节的名字空间是'jabber:client' 或'jabber:server', 定义了某几个允许的消息节的子元素. 如果消息节的类型是"error", 它必须(MUST)包含一个<error/>子元素; 详细情况, 见[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]. 否则, 消息节可以(MAY)包含以下子元素的任何一种并且无需显式地声明名字空间:1.<subject/>2.<body/>3.<thread/>主题<subject/> 元素包含了人类可读的XML 字符数据指明这个消息的主题. <subject/>元素不能(MUST NOT)拥有任何属性, 除了'xml:lang'属性. <subject/> 元素可以(MAY)包含多个实例用于为同一主题提供备用版本, 但是仅在每个实例的拥有的'xml:lang'属性的值互不相同的时候才可以. <subject/> 元素不能(MUST NOT)包含混合的内容(定义在\[XML\]第三章第二节第二小节).主体<body/> 元素包含人类可读的XML字符数据表达消息的文本内容; 这个子元素通常会有但是是可选的(OPTIONAL). <body/>元素不能(MUST NOT)拥有任何属性, 除非是'xml:lang'属性. <body/> 元素可以(MAY)包含多个实例用于为同一主体提供备用版本,但是仅在每个实例的拥有的'xml:lang'属性的值互不相同的时候才可以. <body/>元素不能(MUST NOT)包含混合的内容(定义在\[XML\]第三章第二节第二小节).线索<thread/> 元素包含非人类可读的XML字符数据表达一个标识符用于跟踪两个实体之间的一个会话线索(有时相当于一个"即时消息会话"). <thread/>元素的值是由发送者生成的并且应该(SHOULD)在任何回复中拷贝回来. 如果使用了它, 它必须(MUST)在这个流的会话线索中是唯一的并且必须(MUST)和那个会话相一致(一个从同一个全JID但不同线索ID接收到消息的客户端必须(MUST)假定这个有问题的消息存在于已有的会话线索之外. <thread/>元素的使用是可选的(OPTIONAL)并且不是用于标识独立的消息,而是标识会话. 一个消息节不能(MUST NOT)包含超过一个的<thread/>元素. <thread/>元素不能(MUST NOT)拥有任何属性. <thread/>属性的值必须(MUST)被实体处理成不透明的; 不能从它得到任何语义学上的含义,并且只能对它做精确的比较. <thread/>元素不能(MUST NOT)包含混合内容(定义在[XML]第三章第二节第二小节).出席信息语法符合'jabber:client' 或'jabber:server'名字空间的出席信息节用于表达一个实体当前的网络可用性(离线或在线, 包括之后的各种亚状态和可选的用户名义的描述性文本), 并且通知其他实体它的可用性. 出席信息节也用于协商和管理对于其他实体的出席信息的订阅.出席信息的类型出席信息节的'type'属性是可选的(OPTIONAL). 一个不拥有任何'type'属性的出席信息节用来通知服务器发送者已经在线并且可以进行通信了, 'type' 属性表示缺乏可用性, 请求管理对其他实体的出席信息的订阅, 请求其他实体的当前出席信息, 或发生了和上次发出的出席信息节有关的错误. 如果包含了它, 'type'属性必须(MUST)拥有以下值之一:∙unavailable -- 通知实体将不可通信.∙subscribe -- 发送者希望订阅接收者的出席信息.∙subscribed -- 发送者允许接收者接收他们的出席信息.∙unsubscribe -- 发送者取消订阅另一个实体的出席信息.∙unsubscribed -- 订阅者的请求被拒绝或以前的订阅被取消.∙probe -- 对一个实体当前的出席信息的请求; 只应(SHOULD)由服务器代替一个用户生成.∙error -- 处理或递送之前发送的出席信息节的时候发生了错误.关于出席信息语义学的详细信息和基于XMPP的即时消息和出席信息应用程序的订阅模式,参考交换出席信息Exchanging Presence Information(第五章) 和管理订阅Managing Subscriptions(第六章).子元素如扩展名字空间extended namespaces(第二章第四节)所述, 一个出席信息节可以(MAY)包含任何适当名字空间的子元素.和缺省名字空间声明一致, 缺省出席信息节的名字空间是'jabber:client' 或'jabber:server', 定义了某几个允许的出席信息节的子元素. 如果出席信息节的类型是"error", 它必须(MUST)包含一个<error/>子元素; 详细情况, 见[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]. 如果出席信息节不拥有'type'属性,它可以(MAY)包含以下任何子元素(注意<status/>子元素可以(MAY)在一个类型为"unavailable"或"subscribe"(出于历史原因)的出席信息中被发送):1.<show/>2.<status/>3.<priority/>展示可选的(OPTIONAL)<show/>元素包含非人类可读的XML字符数据表达一个特定的实体或资源的特定的可用性状态. 一个出席信息节不能(MUST NOT)包含多于一个<show/>元素. <show/>元素不能(MUST NOT)拥有任何属性. 如果提供了, 这个XML 字符数据值必须(MUST)是以下之一(额外的可用性类型可以通过出席信息的适当名字空间来定义):∙away -- 实体或资源临时离开.∙chat -- 实体或资源在聊天中是激活的.∙dnd -- 实体或资源是忙(dnd = "不要打扰").∙xa -- 实体或资源是长时间的离开(xa = "长时间离开").如果没有提供<show/>元素, 实体被假定是在线和可用的.状态可选的(OPTIONAL)<status/>元素包含XML字符数据表达一个可用性状态的自然语言描述. 它通常用于联合show元素以提供可用性状态的详细描述(例如, "会议中").<status/>元素不能(MUST NOT)拥有任何属性,除了'xml:lang'属性. <status/>元素可以(MAY)包含多个实例但是每个实例的'xml:lang'属性值必须各不相同.优先权可选的(OPTIONAL)<priority/>元素包含非人类可读的XML字符数据指明资源的优先级别. 这个值必须(MUST)是一个介于-128和+127之间的数字. 一个出席信息小节不能(MUST NOT)包含超过一个的<priority/>元素. <priority/>元素不能(MUST NOT)拥有任何属性. 如果没有优先权被提供,一个服务器应该(SHOULD)认为优先级是零. 关于即时消息和出席信息系统中节路由的优先级的语义, 参考处理XML节的服务器规则Server Rules for Handling XML Stanzas(第十一章).IQ语法IQ节提供一个结构化的请求-应答机制. 这个机制的基本语义学(例如, 'id'属性是必需的(REQUIRED))定义在[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920], 然而完成特定用例所需要的特定语义的所有案例定义在扩展名字空间extended namespace(第二章第四节)之中(注意'jabber:client'和'jabber:server'名字空间没有定义除通用的<error/>子元素之外的任何IQ节子元素). 本文定义了两个这样的名字空间,一个用于名册管理Roster Management(第七章)而另一个用于屏蔽通信Blocking Communication(第十章); 无论如何, 一个IQ节可以(MAY)包含符合任何扩展名字空间的结构化信息.扩展名字空间因为在"jabber:client"或"jabber:server"名字空间中定义的三个XML节类型(也包括它们的属性和子元素)提供了一个基本功能级用于消息和出席信息, XMPP使用XML名字空间来扩展节用于提供额外的功能, 所以一个消息或出席信息节可以(MAY)包含一个或更多可选的子元素表达扩展消息含义的内容(例如, 一个XHTML格式版本的消息主体), 并且一个IQ节可以(MAY)包含一个这样的子元素. 这个子元素可以(MAY)有任何名字并且可以(MUST)拥有一个'xmlns'名字空间声明(不同于"jabber:client", "jabber:server", 或"/streams")定义所有包含在子元素中的数据.对于任何特定的扩展名字空间的支持在任何实现中的一部分是可选的(OPTIONAL)(除了在这里定义的扩展名字空间以外). 如果一个实体不理解这样一个名字空间, 实体被期望的行为依赖于这个实体是(1) 接收者或(2) 一个正在路由到接收者的实体接收者: 如果一个接收者接收了一个包含不理解的子元素的节, 它应该(SHOULD)忽略那个特定的XML数据,例如, 它应该(SHOULD)不处理它或不向用户或相关的应用程序(如果有的话)显示它. 具体来说:∙如果一个实体接收了一个消息或出席信息节包含一个不理解的名字空间, 在节的未知名字空间的这部分应该(SHOULD)被忽略.∙如果一个实体接收了一个消息节中仅有的一个子元素是不理解的, 它必须(MUST)忽略整个节.∙如果一个实体接收了一个类型"get"或"set"的IQ节包含一个不理解的子元素, 这个实体应该(SHOULD)返回一个类型为"error"的<service-unavailable/>错误条件的IQ节.路由: 如果一个路由实体(通常是一个服务器)处理一个包含它不理解的子元素的节, 它应该(SHOULD)原封不动地把它转给接收者而忽略相关的XML数据.会话的建立绝大部分基于XMPP的消息和出席信息应用是由一个客户端-服务器体系结构实现的,为了参加期望的即时消息和出席信息活动,需要客户端在服务器上建立一个会话. 无论如何, 在客户端能够建立一个即时消息和出席信息会话之前有很多前提必须(MUST)满足. 它们是:1.流验证-- 客户端在尝试建立一个会话或发送任何XML节之前必须(MUST)完成[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]中定义的流验证.2.资源绑定-- 完成流验证之后, 一个客户端必须(MUST)绑定一个资源到流上,使得客户端的地址符合<user@domain/resource>格式, 然后实体以[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]规定的术语来说就是一个已连接的资源"connected resource".如果一个服务器支持会话, 在完成一个[XMPP-CORE|XMPP文档列表/XMPP正式RFC 标准/RFC3920]定义的流验证之后它必须(MUST)在它向客户端声明的流特性中包含一个符合'urn:ietf:params:xml:ns:xmpp-session'名字空间的<session/>元素:服务器向客户端声明会话确定特性:<stream:streamxmlns='jabber:client'xmlns:stream='/streams'id='c2s_345'from=''version='1.0'><stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></stream:features>收到需要会话确立的通知之后(并且是在完成资源绑定之后), 客户端如果想使用即时消息和出席信息功能必须(MUST)建立一个会话; 它向服务器发送一个符合'urn:ietf:params:xml:ns:xmpp-session'名字空间的类型为"set"并包含空的<session/>子元素的IQ节以完成这一步骤:步骤1: 客户端向服务器请求会话:<iq to=''type='set'id='sess_1'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>步骤2: 服务器通知客户端会话已经建立:<iq from=''type='result'id='sess_1'/>建立会话之后, 一个已连接的资源([XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920]术语)就被称为一个激活的资源"active resource".许多错误条件是可能的. 例如, 服务器可能遭遇一个内部条件阻碍了它建立会话, 用户名或授权身份可能缺乏建立会话的许可, 或同一个名字相关的这个资源ID已经有一个激活的资源.如果服务器遭到一个内部条件阻碍了它建立会话, 它必须(MUST)返回一个错误.步骤 2 (替代): 服务器应答一个错误(内部服务器错误):<iq from=''type='error'id='sess_1'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><error type='wait'><internal-server-errorxmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>如果用户名或资源不被允许建立一个会话, 服务器必须(MUST)返回一个错误(例如, 被禁止).步骤 2 (替代): 服务器应答错误(用户名或资源不被允许建立一个会话):<iq from=''type='error'id='sess_1'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><error type='auth'><forbiddenxmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>如果已经同一名字已经存在一个激活的资源,服务器必须(MUST) (1) 终止这个激活的资源并允许新请求的会话, 或者(2) 不允许新申请的会话并继续激活的资源. 服务器做哪一步取决于具体的实现, 尽管建议的(RECOMMENDED)实现情景#1. 在情景#1, 服务器应该(SHOULD)发送一个<conflict/>流错误给激活的资源, 终止用于这个激活的资源的XML流和相关的TCP连接, 并返回一个类型为"result" 的IQ节(表示成功)给新申请的会话. 在情景#2, 服务器应该(SHOULD)发送一个<conflict/>节错误给新申请的会话但是继续那个连接的XML流使得新申请的会话在发送另一个会话建立申请之前有机会协商出一个不冲突的资源ID.步骤 2 (替代): 服务器通知现有的激活的资源资源冲突(情景#1): <stream:error><conflict xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error></stream:stream>步骤 2 (替代): 服务器通知新申请的的会话资源冲突(情景#2):<iq from=''type='error'id='sess_1'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/><error type='cancel'><conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>建立一个会话之后, 客户端应该(SHOULD)按以下描述来发送初始化出席信息并请求它的名册, 尽管这些动作是可选的(OPTIONAL).注意: 在允许建立即时消息和出席信息会话之前, 一个服务器可能(MAY)需要先提供帐号. 可能的提供帐号的方法包括由服务器管理员新建帐号以及使用'jabber:iq:register'名字空间进行带内帐号注册; 后一个方法超出了本文的范围, 但是记录在\[JEP-0077\](译者注:这个协议已改名为XEP-0077), 由Jabber Software Foundation \[JSF\]发行(译者注:这个组织也已改名为XSF).交换消息交换消息是XMPP的一个基本用途并且随之而来的是一个用户生成一个发给另一个实体的消息节. 正如用于处理XML节的服务器规则Server Rules for Handling XML Stanzas(第十一章)中所定义的, 发送者的服务器负责递送消息给预定的接收者(如果接收者在同一个服务器上)或路由消息给接收者的服务器(如果接收者在不同的服务器上).关于消息节的语法和它们已定义的属性和子元素信息, 参考消息语法Message Syntax(第二章第一节).指明一个预定的接收者一个即时消息客户端应该(SHOULD)通过提供一个JID或<message/>节中不同于发送者的'to'属性来指定一个消息的预定接收者. 如果这个消息是在回复之前接收到的消息,而接收到的消息是从JID格式为<user@domain/resource>(例如,在一个聊天会话的上下文中)实体发来的, 这个回复消息的'to'地址的值应该(SHOULD)是<user@domain/resource>而不是<user@domain>,除非发送者知道(通过出席信息)预定的接收者的资源将不再可用. 如果消息是在任何现存的聊天会话或接收到的消息之外被发送的,'to'地址的值应该(SHOULD)格式为<user@domain>而不是<user@domain/resource>.指定一个消息类型大家知道, 对于一个消息节来说拥有'type'属性(它的值代表了消息的会话上下文(参见Type(第二章第一节第一小节)))是建议的(RECOMMENDED).以下例子展示一个'type'属性的合法值:例子: 一个已定义类型的消息:<messageto='romeo@'from='juliet@/balcony'type='chat'xml:lang='en'><body>Wherefore art thou, Romeo?</body></message>指定一个消息主体一个消息节可以(MAY)(并且经常会)包含一个<body/>子元素,它的XML字符数据表达消息的主要含义(见Body(第二章第一节第二小节第二小小节)).例子: 一个带主体的消息:<messageto='romeo@'from='juliet@/balcony'type='chat'xml:lang='en'><body>Wherefore art thou, Romeo?</body><body xml:lang='cz'>PročeŽ jsi ty, Romeo?</body></message>指定一个消息主题一个消息节可以(MAY)包含一个或多个<subject/>子元素指明消息的主题(见Subject(第二章第一节第二小节第一小小节)).例子: 一个带主题的消息:<messageto='romeo@'from='juliet@/balcony'type='chat'xml:lang='en'><subject>I implore you!</subject><subjectxml:lang='cz'>Úpěnlivě prosim!</subject><body>Wherefore art thou, Romeo?</body><body xml:lang='cz'>PročeŽ jsi ty, Romeo?</body></message>指定一个会话线索一个消息可以(MAY)包含一个<thread/>子元素指定消息处于哪个会话线索, 用于跟踪会话(见Thread(第二章第一节第二小节第三小小节)).例子: 一个带线索的会话:<messageto='romeo@/orchard'from='juliet@/balcony'type='chat'xml:lang='en'><body>Art thou not Romeo, and a Montague?</body><thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread></message><messageto='juliet@/balcony'from='romeo@/orchard'type='chat'xml:lang='en'><body>Neither, fair saint, if either thee dislike.</body><thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread></message><messageto='romeo@/orchard'from='juliet@/balcony'type='chat'xml:lang='en'><body>How cam'st thou hither, tell me, and wherefore?</body><thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread></message>交换出席信息交换出席信息通过使用出席信息节直接和XMPP相关. 无论如何, 我们看到在这里和消息处理形成一个对比:尽管一个客户端可以(MAY)通过包含一个'to'地址直接给另一个实体发送出席信息, 通常出席信息通知(例如,不包含'type'的或类型为"unavailable"的并且没有'to'地址的出席信息节) 被客户端发送给它的服务器然后由服务器广播给任何订阅了发送实体的出席信息的实体(在RFC 2778 \[IMP-MODEL\]术语中, 这些实体称为订阅者). 这个广播模式不适用于和订阅相关的节或类型为"error"的出席信息, 而仅适用于以上定义的出席信息通知. (注意: 虽然出席信息可以(MAY)由一个自动化服务代替用户提供, 通常它还是由用户的客户端提供.)关于出席信息节的语法以及它们的已定义的属性和子元素的信息, 参考[XMPP-CORE|XMPP文档列表/XMPP正式RFC标准/RFC3920].客户端和服务器出席信息职责初始化出席信息建立起一个会话之后, 一个客户端应该(SHOULD)发送初始化出席信息给服务器来通知它的通信可用性.如这里定义的, 初始化出席信息节(1) 必须(MUST) 不拥有'to'地址(这表示它是由服务器代替客户端发送的广播) 并且(2) 必须(MUST) 不拥有'type'属性(者表示拥护的可用性). 在发送初始化出席信息之后, 一个激活的资源被称为可用的资源"available resource".从一个客户端接收到初始化出席信息之后, 如果这个用户没有一个或更多的已存在的可用资源(如果这个用户已经有一个或更多可用的资源, 服务器明显不需要发送出席信息探测, 因为它已经拥有需要的信息),用户的服务器必须(MUST)做以下的步骤:1.从用户的全JID(例如,<user@/resource>)发送出席信息探针(例如,'type'属性值为'probe'的出席信息节)给已被这个用户订阅了的所有联系人以确定它们是否可用; 这些联系人就是那些显示在用户的名册中的JID并且'subscription'属性值为"to"或"both"(注意: 用户的服务器不能(MUST NOT)发送出席信息探针给用户已经屏蔽入站出席信息通知的联系人, 具体的描述在屏蔽入站出席信息通知Blocking Inbound Presence Notifications(第十章第十节).)2.从用户的全JID (e.g.,<user@/resource>)广播初始化出席信息给所有订阅了该用户的出席信息的联系人; 这些联系人就是那些显示在用户的名册中的JID并且'subscription'属性值为"from"或"both"(注意: 用户的服务器不能(MUST NOT)发送出席信息探针给用户已经屏蔽出站出席信息通知的联系人, 具体的描述在屏蔽出站出席信息通知Blocking Outbound PresenceNotifications(第十章第十一节).)另外, 用户的服务器必须(MUST)从用户的新的可用的资源向用户任何现存的可用的资源(如果有的话)广播初始化出席信息.从用户接收到初始化出席信息之后, 联系人的服务器必须(MUST)递送这个用户的出席信息节给所有联系人的可用资源相应的全JID(<contact@/resource>), 但是仅适用于用户在联系人名册中并且订阅状态为"to"或"both"并且联系人的纯JID 或全JID没有被屏蔽入站出席信息通知(定义在屏蔽入站出席信息通知Blocking Inbound Presence Notifications(第十章第十节)).如果用户的服务器接收到一个类型为"error"的出席信息节,而这个节是用来回复服务器代替用户向联系人发送的初始化出席信息, 它不应该(SHOULD NOT)发送更多的出席信息更新给那个联系人(直到并且除非它从这个联系人接收到一个出席信息节).。
HTTP协议和XMPP协议应用层协议:每个应用层的都是为了解决某一类应用问题。
而问题的解决又必须通过位于不同主机中的多个应用进程之间的通信和协同工作来完成。
应用进程之间必须遵守严格的规则。
应用层协议应当定义如下几个:•应用进程之间交换的报文类型,如请求报文和响应报文•报文中各个字段及其详细描述•包含在字段中的信息的含义•进程何时、如何发送报文,以及对报文进行响应的规则1.HTTP协议万维网使用统一资源定位符URL来标志万维网上的各种文档,并使每一个文档在整个因特网的范围内具有唯一的标识符URL;万维网客户程序和服务器程序必须遵守严格的协议即HTTP协议。
HTTP协议是一个应用层协议,它使用TCP连接进行可靠的传送。
另外为了提取显示文档,使用超文本标记语言HTML1.1 HTTP操作过程1.2 用户点击firefox浏览器的某个页面后触发的事件1.浏览器分析链接指向页面的URL2.向DNS请求解析URL对于的IP地址3.域名系统解析出IP地址4.浏览器与服务器建立TCP连接(服务器端的端口是80)5.浏览器发出Get文件命令6.服务器对Get请求作出相应,把文件index.html发送给浏览器7.释放TCP链接8.浏览器显示index.html中的所有文本信息1.3 HTTP协议使用了面向连接的TCP作为传输层协议保证了数据的可靠传输.HTTP不必考虑数据在传输过程中被丢弃后又怎样被重传.但是HTTP协议本身是无连接的.,也就是说通信双方在交换HTTP报文之前不需要先建立HTTP链接HTTP协议是无状态的,服务器不记得曾经访问过的这个用户.1.4 HTTP1.0和HTTP1.1•HTTP1.0的缺点:每请求一个文档就要两倍RTT的开销。
若一个主页上有很多链接对象需要进行连接,那么每一次连接下载都需要2*RTT时间。
另一种开销就是万维网客户和服务器每一次建立新的TCP连接都要分配缓存和变量。
使用不行TCP连接可以缩短响应时间。
GMPP协议及其服务器端的Openfire插件开发GMPP背景知识GMPP是一种基于GML的协议,它继承了在 GML环境中灵活的发展性。
因此,基于GMPP的应用具有超强的可扩展性。
绊过扩展以后的GMPP可以通过发送扩展的信息来处理用户的需求,以及在GMPP的顶端建立如内容发布系统和基于地址的服务等应用程序。
而且,GMPP包含了针对服务器端的软件协议,使乊能不另一个进行通话,这使得开发者更容易建立客户应用程序戒给一个配好系统添加功能。
GMPP (可扩展消息处理现场协议)是基于可扩展标记语言(GML )的协议,它用于即时消息(IM )以及在线现场探测。
它在促进服务器乊间的准即时操作。
这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器丌同。
GMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。
GMPP目前被IETF国际标准组织完成了标准化工作。
标准化的核心绌果分为两部分;核心的GML流传输协议基于GMLFreeEIM流传输的即时通讯扩展应用 GMPP的核心GML流传输协议的定义使得GMPP 能够在一个比以往网络通信协议更规范的平台上。
借劣于GML易于解析和阅读的特性,使得 GMPP的协议能够非常漂亮。
GMPP的即时通讯扩展应用部分是根据IETF在这乊前对即时通讯的一个抽象定义的,不其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。
GMPP的扩展协议Jingle 使得其支持语音和视频。
基本网络结构GMPP中定义了三个角色,客户端,服务器,网关。
通信能够在这三者的任意两个之间双向发生。
服务器同时承担了客户端信息记录,连接管理和信息的路由功能。
网关承担着不异构即时通信系统的互联互通,异构系统可以包括SMS (短信),MSN,ICQ等。
基本的网络形式是单客户端通过 TCP/IP连接到单服务器,然后在乊上传输 GML。
功能传输的是不即时通讯相关的指令。
XMPP即时通讯XMPP:XMPP是基于XML的点对点通讯协议,The Extensible Messaging and Presence Protocol(可扩展通讯和表⽰协议)。
XMPP可⽤于服务类实时通讯,表⽰和需求响应服务中的XML数据元流失传输。
XMPP以Jabber协议为基础,⽽Jabber是即时通讯中常⽤的开放式协议。
基本结构。
XMPP是⼀个典型的C/S架构,⽽不是像⼤多数即时通讯软件⼀样,使⽤P2P客户端到客户端的架构,也就是说在⼤多数情况下,当两个客户端进⾏通讯时,他们的消息都是通过服务器传递的。
采⽤这种架构,主要是为了简化客户端,将⼤多数⼯作放在服务器端进⾏。
XMPP中定义了三个⾓⾊,客户端,服务器,⽹关。
通信能够在这三者的任意两个之间双向发⽣。
服务器同时承担了客户端信息记录,连接管理和信息的路由功能。
⽹关承担着与异构即时通讯系统的互联互通,异构系统可以包括SMS(短信),MSN,ICQ等。
基本的⽹络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML流。
1.1XMPP中的常⽤对象XMPPStream:xmpp基础服务类XMPPRoster:好友列表类XMPPRosterCoreDataStoreage:好友列表(⽤户账号)在core data中的操作类XMPPvCardCoreDataStorage:好友名⽚(昵称、签名、性别、年龄等信息)在core data中的操作类XMPPvCardTemp:好友名⽚实体类,从数据库⾥⾯取出来的都是它xmppvCardAvatarModule:好友头像XMPPReconnect:如果失去连接,⾃动重连XMPPRoom:提供多⽤户聊天⽀持XMPPPubSub:发布订阅1.2登录操作,也就是连接xmpp服务器XMPP的地址叫做JabberID(简写为JID),它⽤来标识XMPP⽹络中的各个XMPP实体,JID由三个部分组成:domain、node identifier和resource。
XMPP协议使用开源jabber(XMPP)协议及openfire架设内部即时通讯服务分类:C# jabber/XMPP 2010-12-11 14:59 89人阅读评论(0) 收藏举报Jabber 是著名的即时通讯服务服务器,它是一个自由开源软件,能让用户自己架即时通讯服务器,可以在Internet上应用,也可以在局域网中应用。
XMPP(可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探测。
它在促进服务器之间的准即时操作。
这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。
XMPP的技术来自于Jabber,其实它是 Jabber 的核心协定,所以XMPP有时被误称为Jabber协议。
Jabber是一个基于XMPP协议的IM应用,除Jabber 之外,XMPP还支持很多应用。
下面就是如何架设内部即时通讯服务的步骤:第一步:安装Jabber服务器软件Jabber服务软件有很多,具体可以参考jabber官方网站的列表:Jabber官网地址:/常用Jabber服务器软件:/software/servers.shtml其中最为方便安装搭建的无疑是Openfire(Wildfire),一款基于GPL协议开源软件,Openfire有linux、windows和MAC的不同版本,软件需要java环境支持,不过软件本身自带了环境包,你可以根据你的需要下载不同的版本。
下载地址:/downloads/index.jsp#openfire最新版本:Openfire 3.3.21、Windows版本安装方法:下载:openfire_3_3_2.exe带java环境版本安装:直接运行安装文件,程序默认安装至c:/Program Files/Openfire运行:/bin/openfire.exe2、Linux/Unix版本安装方法如果使用rpm包安装,下载:openfire-3.3.2-1.i386.rpm运行:#rpm -ivh openfire_3_0_0.rpm默认安装路径位于:/opt/openfire使用源码包安装,下载:openfire_3_0_0.tar.gz(不带java环境,请自行安装)#tar -xzvf openfire_3_0_0.tar.gz# mv openfire /opt启动方法:#/opt/openfire/bin/openfire.sh第二步:配置jabber服务器Openfire(Wildfire)支持完全的web安装,如果你在本地按安装只需要在浏览器中输入http://localhost:9090(远程服务器为http://你的服务器地址:9090)即可开始即时通讯服务器配置。
在android里面用的smack包其实叫做asmack,该包提供了两种不同的连接方式:socket和httpclient。
该并且提供了很多操作xmpp协议的API,也方便各种不同自定义协议的扩展。
我们不需要自己重新去定义一套接收机制来扩展新的协议,只需继承然后在类里处理自己的协议就可以了。
而本文今天主要说两点,一点就是消息是如何接收的,另一点就是消息是如何通知事件的。
总的思路1.使用socket连接服务器2.将XmlPullParser的数据源关联到socket的InputStream3.启动线程不断循环处理消息4.将接收到的消息解析xml处理封装好成一个Packet包5.将包广播给所有注册事件监听的类逐步击破(声明在看下面的文章时,最好先理解一下smack的使用,这样才能达到深入的理解)(谨记:上图只显示本文章解释所要用到的类和方法,减缩了一些跟本文主题无关的代码,只留一条贯穿着从建立连接到接收消息的线。
)解析这块东西打算从最初的调用开始作为入口,抽丝剥茧,逐步揭开。
1.PacketListener packetListener = new PacketListener() {@Overridepublic void processPacket(Packet packet) {System.out.println("Activity----processPacket"+ packet.toXML());}};PacketFilter packetFilter = new PacketFilter() {@Overridepublic boolean accept(Packet packet) {System.out.println("Activity----accept"+packet.toXML());return true;}};解释:创建包的监听以及包的过滤,当有消息到时就会广播到所有注册的监听,当然前提是要通过packetFilter的过滤。
2.connection = new XMPPConnection();XMPPConnection在这构造函数里面主要配置ip地址和端口(super(new ConnectionConfiguration("169.254.141.109", 9991));)3.connection.addPacketListener(packetListener, packetFilter);connection.connect();注册监听,开始初始化连接。
4.public void connect() {// Stablishes the connection, readers and writersconnectUsingConfiguration(config);}5.private void connectUsingConfiguration(ConnectionConfigurationconfig) {String host = config.getHost();int port = config.getPort();try{this.socket= new Socket(host, port);} catch(UnknownHostException e) {e.printStackTrace();} catch(IOException e) {e.printStackTrace();}initConnection();}通过之前设置的ip和端口,建立socket对象6.protected void initDebugger() {Class<?> debuggerClass = null;try{debuggerClass = Class.forName("com.simualteSmack.ConsoleDebugger");Constructor<?> constructor = debuggerClass.getConstructor(Connection.class, Writer.class, Reader.class);debugger= (SmackDebugger) constructor.newInstance(this, writer,reader);reader= debugger.getReader();} catch(ClassNotFoundException e1) {//TODO Auto-generated catch blocke1.printStackTrace();} catch(Exception e) {throw new IllegalArgumentException("Can't initialize the configured debugger!", e);}}private void initReaderAndWriter() {try{reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));} catch(UnsupportedEncodingException e) {//TODO Auto-generated catch blocke.printStackTrace();} catch(IOException e) {//TODO Auto-generated catch blocke.printStackTrace();}initDebugger();}private void initConnection() {// Set the reader and writer instance variablesinitReaderAndWriter();packetReader = new PacketReader(this);addPacketListener(debugger.getReaderListener(), null);// Start the packet reader. The startup() method will block until we// get an opening stream packet back from server.packetReader.startup();}从三个方法可以看出,建立reader和writer的对象关联到socket的InputStream,实例化ConsoleDebugger,该类主要是打印出接收到的消息,给reader设置了一个消息的监听。
接着建立PacketReader对象,并启动。
PacketReader主要负责消息的处理和通知7.public class PacketReader {Private ExecutorService listenerExecutor;private boolean done;Private XMPPConnection connection;Private XmlPullParser parser;Private Thread readerThread;Protected PacketReader(final XMPPConnection connection) {this.connection= connection;this.init();}/*** Initializes the reader in order to be used. The reader is initialized* during the first connection and when reconnecting due to an abruptly * disconnection.*/protected void init() {done= false;readerThread= new Thread() {public void run() {parsePackets(this);}};readerThread.setName("Smack Packet Reader ");readerThread.setDaemon(true);// create an executor to deliver incoming packets to listeners.// we will use a single thread with an unbounded queue.listenerExecutor= Executors.newSingleThreadExecutor(new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r,"smack listener processor");thread.setDaemon(true);return thread;}});resetParser();}/*** Starts the packet reader thread and returns once a connection to the * server has been established. A connection will be attempted for a maximum* of five seconds. An XMPPException will be thrown if the connection fails.**/public void startup() {readerThread.start();}/*** Shuts the packet reader down.*/public void shutdown() {done= true;// Shut down the listener executor.listenerExecutor.shutdown();}private void resetParser() {try{parser=XmlPullParserFactory.newInstance().newPullParser();parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);parser.setInput(connection.reader);} catch(XmlPullParserException xppe) {xppe.printStackTrace();}}/*** Parse top-level packets in order to process them further.**@param thread* the thread that is being used by the reader to parse incoming * packets.*/private void parsePackets(Thread thread) {try{Int eventType = parser.getEventType();do{if(eventType == XmlPullParser.START_TAG) {if(parser.getName().equals("message")) { processPacket(PacketParserUtils.parseMessage(parser));}System.out.println("START_TAG");} else if(eventType == XmlPullParser.END_TAG) {System.out.println("END_TAG");}eventType = parser.next();} while(!done&& eventType != XmlPullParser.END_DOCUMENT&& thread == readerThread);} catch(Exception e) {e.printStackTrace();if(!done) {}}}private void processPacket(Packet packet) {if(packet == null) {return;}// Loop through all collectors and notify the appropriate ones.for(PacketCollector collector : connection.getPacketCollectors()) {collector.processPacket(packet);}// Deliver the incoming packet to listeners.listenerExecutor.submit(new ListenerNotification(packet));}/*** A runnable to notify all listeners of a packet.*/private class ListenerNotification implements Runnable {Private Packet packet;Public ListenerNotification(Packet packet) {this.packet= packet;}public void run() {for(ListenerWrapper listenerWrapper : connection.recvListeners.values()) {listenerWrapper.notifyListener(packet);}}}}创建该类时就初始化线程和ExecutorService ,接着调用resetParser() 方法为parser 设置输入源(这里是重点,parser的数据都是通过这里获取),调用startup启动线程,循环监听parser,如果接收到消息根据消息协议的不同将调用PacketParserUtils类里的不同方法,这里调用parseMessage()该方法主要处理message的消息,在该方法里分析message消息并返回packet包。