实战项目xmpp版即时聊天第01天smack类库详细介绍_第1页
实战项目xmpp版即时聊天第01天smack类库详细介绍_第2页
实战项目xmpp版即时聊天第01天smack类库详细介绍_第3页
实战项目xmpp版即时聊天第01天smack类库详细介绍_第4页
实战项目xmpp版即时聊天第01天smack类库详细介绍_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Smack 类库详细介绍Smack 是一个为使用 XMPP 服务器聊天和发送即时消息交流而提供的库。 Smack 的主要优势:使用简单且拥有强大的 API。向用户发送一条文本消息只需用一下三行代码即可完成 XMPPConnection connection = new XMPPConnection(); connection.login(mtucker, password);connection.createChat(jsmit).sendMessage(Howdy!);不像其它库那样,强制你在信息报级(packet level)编码。Smack 提供智能的、更高级别的结构,例如:Chat 和

2、GroupChat 类,这写能让你的程序效率更高。你不需要熟悉 XMPP XML 格式,甚至不熟 XML。提供简单的机器到机器的通讯。Smack 允许你对每一条消息设置任何数字的属性,包括 Java 对象的属性。 Apache 许可的开放源码,你可将其用于商业的和非商业的应用。关于 XMPPXMPP (eXtensible Messaging and Presence Protocol)是一个开放的,如何使用本文档本文档假定你已经熟悉 XMPP 即时消息的主要特征。我们推荐你在阅读该文档时打开 Javadoc API 作为参考。开始 Smack本文档将向你介绍 Smack API,并大概介绍几

3、个重要的类和概念。必备的条件你只需要有 JDK 1.2 或之后的版本 1 和已经内嵌在 smack.jar 文件中的 XML 分析器,不需要第三部分库。1JDK 1.2 and 1.3 的用户若想使用 SSL 连接必须在他的类路径下有 JSSE 库。建立一个连接XMPPConnection 类是为 XMPP 服务器建立连接的类。若要创建 SSL 连接,需使用 SSLXMPPConnection 类,以下是创建连接的例子。/ Create a connection to the server. XMPPConnection conn1 = new XMPPConnection();/ Creat

4、e a connection to the server on a specific port. XMPPConnection conn2 = new XMPPConnection(, 5222);/ Create an SSL connection to .XMPPConnection connection = new SSLXMPPConnection();如果创建了一个连接,你应该使用 XMPPConnection.login(String username, String password)方法(参数为用户名和密码)进行登陆。一旦登陆成功,你就可以通过创建一个新的 Chat 或Grou

5、pChat 对象与其它用户聊天。使用花名册(Working with the Roster)花名册让你很清楚的知道其它可用的用户。用户可以被分成像“朋友”、“合作者”这样的组,从而知道其它的用户在线还是离线。可以使用 XMPPConnection.getRoster()方法检索花名册。你可以用花名册(roster)类查找花名册的所有条目,它们所属的组以及每个条目当前呈现的状态。读、写信息包(Reading and Writing Packets)从客户端发送到 XMPP 的每一条消息称为一个信息包,并作为 XML 发送。The org.jivesoftware.smack.packet 包含封

6、装了三个 XMPP 允许的、不同的基本包类型(message, presence, and IQ)的类。像 Chat 和GroupChat 这样的类提供更高级别的结构,它可以自动的创建和发送信息包,当然你也可以直接创建和发送信息包。以下代码是一个将你的当前状态改为“隐身“,从而不被别人看到的例子:/ Create a new presence. Pass in false to indicate were unavailable. Presence presence = new Presence(Presence.Type.UNAVAILABLE); presence.setStatus(Go

7、ne fishing);/ Send the packet (assume we have a XMPPConnection instance called con). con.sendPacket(presence);Smack 提供以下两种方法阅读收到的信息包:PacketListener 和PacketCollector。它们都使用PacketFilter 的实例来决定应该处理哪个信息包。信息包监听器(packet listener)用于事件类型的设计,而信息包收集器(packet collector)有一个信息包的结果队列,你可以对其实施 polling 和 blocking 操作。所

8、以,信息包监听器在你收到任何一个信息包,且你想对其进行操作时是有用的,而信息包收集器在你想等待某个特殊的信息包时是有用的。信息包收集器和监听器可以通过 XMPPConnection 的实例来创建。Messaging BasicsMessaging using Chat and GroupChat互相发送消息是即时通讯的核心,以下是两个在收发消息是用的类: org.jivesoftware.smack.Chat 用于两个人之间发送消息 org.jivesoftware.smack.GroupChat 用于加入聊天室,很多人之间相互发送消息。Chat 和GroupChat 类都用org.jives

9、oftware.smack.packet .Message 信息包类发送消息。在某些情况下,也许你希望绕过更高级别的 Chat 和GroupChat 类直接发送和接受消息。聊天(Chat)聊天时在两个用户间创建了一个新的线程(使用一个线程 ID)。以下程序片示例了如何如何与一个用户进行开始聊天并发送一段文本消息:/ Assume weve created an XMPPConnection name connection.Chat newChat = connection.createChat(jsmitnewChat.sendMessage(Howdy!););Chat.sendMessag

10、e(String)方法可以很方便的创建一个消息对象,方法体使用字符串类型的参数,然后发送消息。如果想在发送消息前对消息设置额外的只,可以使用 Chat.createMessage() and Chat.send Message(Message)方法,如下例所示: / Assume weve created an XMPPConnection name co nnection.Chat newChat = connection.createChat(jsmit Message newMessage = newChat.createMessage(); newMessage.setBody(How

11、dy!); message.setProperty(favoriteColor, red); newChat.sendMessage(newMessage););使用 Chat 对象可以轻松的收听其它聊天者的回复。以下程序片是 parrot-bot,它映射会其它用户类型的所有事情: / As sume weve created an XMPPConnection name connection.Chat newChat = connection.createChat(jsmit);newMessage.setBody(Hi, Im an annoying parrot-bot! Type so

12、mething back to me.); while (true) / Wait for the next message the user types to us. Message message = newChat.nextMessage();/ Send back the same text the other user sent us. newChat.sendMessage(message.getBody();以上代码使用 Chat.nextMessage()方法获得下一条消息,它必需一直等待直到收到下一条消息。也有其它的方法可以等待特定的时间来接受下一条消息,或者你也可以增加一个

13、监听器,它可以在每次收到消息时通知你。群聊(GroupChat)群聊在通过一个服务器连接到聊天室,你可以向一组人发送消息或接收他们的消息。在你能接收和发送消息前,你必须使用一个昵称登陆到聊天室。以下程序段可以连接到一个聊天室并发送消息:/ Assume weve created an XMPPConnection name connection.GroupChat newGroupChat = connection.createGroupChat(tes/ Join the group chat using the nickname jsmith. newGroupChat.join(jsmi

14、th);/ Send a message to all the other people in the chat room. newGroupChat.sendMessage(Howdy!););,群聊时收发消息和私聊时工作原理大体一致。同样,也有方法可以获得聊天室里其它用户的列表。 Roster and Presence花名册让你很清楚的知道其它可用的用户。用户可以被分成像“朋友”、“合作者”这样的组。其它的即使通讯系统将花名册作为好友列表、联系列表等。当你成功登陆服务器后,可以使用 XMPPConnection.getRoster()获得 Roster 类的实例。花名册条目(Roster

15、Entries)花名册里的每一个用户都以一条花名册条目的形式呈现,包括以下几部分:一个 XMPP 地址(例如:).分配给你的用户名 (例如: Joe).该条目在花名册中所属组的列表。如果该条目不属于任何一个组,将被称为“尚未分类的条目。以下程序段可以打印出花名册中的所有条目:Roster roster = con.getRoster();for (Iterator i=roster.getEntries(); i.hasNext(); ) System.out.println(i.next();也有获得个人条目、尚未分类条目的列表、一个或者所有组的方法。呈现(Presence)花名册中的每一个

16、条目都有相关的呈现方式。Roster.getPresence(String user)方法将通过用户的状态或当用户不在线或不同意将其在线状态显示出来时使用空对象(null)返回一个 Presence 对象。注意:一般情况下,用户是否同意显示其状态依赖于用户所在的花名册,但这不是在所有情况下都成立的。用户也有一个在线或离线的状态,如果用户在线,他们的显示信息中将会有一些扩展的信息,例如他当前正在做什么,是否希望被打扰等等,详细内容可以参看 Presence 类。Listening for Roster and Presence ChangesRoster 类的典型用途是用树状形式显示组和每一个条

17、目以及它的当前状态。如下图所示是 Exodus XMPP 客户端的花名册。显示的信息很可能会经常改变,也有可能是花名册的条目被改变甚至被删除。为了监视花名册的改变和显示的信息,应该使用一个花名册监听器(RosterListener)。以下代码使用 Roster(它可以打印出花名册中的任何变化)注册了一个 RosterListener。标准的客户端应该使用相似的代码更新花名册的用户信息(roster UI)以正确显示变化的信息。final Roster roster = con.getRoster(); roster.addRosterListener(new RosterListener()

18、public void rosterModified() / Ignore event for this example.public void presenceChanged(String user) / If the presence is unavailable then null will be printed,/ which is fine for this example.System.out.println(Presence changed: + roster.getPresence(user););向花名册中添加条目(Adding Entries to the Roster)花

19、名册和显示使用基于许可的模型,这要求用户在加入别人的花名册前必须得到允许。这样,确保只有被允许的人才可以看到自己所显示的信息,从而保护了用户的隐私。因此,在你想添加一个新的条目,且对方没有接受你的请求前,该条目将处于等待状态。如果另一个用户请求同意显示,从而你他们可以将你加入他们的花名册,你必须接受或拒绝请求。Smack 通过以下三种方式之一操作同意显示请求:自动接受所有的同意显示请求。自动拒绝所有的同意显示请求。手动处理同意显示请求。可以使用 Roster.setSubscriptionMode(int subscriptionMode)方法设置模式。简单的客户通常使用一个自动接受或拒绝同意

20、显示请求的模式,而用更多特征的用户应该使用手动处理同意显示请求的模式,并让终端用户接受或拒绝每一个请求。如果使用手动模式,应该声明一个信息包监听器(PacketListener)来监听有 Presence.Type.SUBSCRIBE 类型的显示信息包。处理收到的信息包(Processinging Packets)Smack 提供一个使用以下两个结构的灵活框架来处理收到的信息包:org.jivesoftware.smack.PacketCollector 一个允许你同步的等待新的信息包的类 org.jivesoftware.smack.PacketListener 一个异步的通知你收到信息包的

21、接口信息包监听器(packet listener)用于事件类型的设计,而信息包收集器(packet collector)有一个信息包的结果队列,你可以对其实施 polling 和blocking 操作。所以,信息包监听器在你收到任何一个信息包,且你想对其进行操作时是有用的,而信息包收集器在你想等待某个特殊的信息包时是有用的。信息包收集器和监听器可以通过 XMPPConnection 的实例来创建。由org.jivesoftware.smack.filter.PacketFilter 接口来决定哪个特殊的信息包将被转交给信息包收集器(PacketCollector)或信息包监听器(PacketL

22、istener)。可以在 org.jivesoftware.smack.filter 包中找到许多预先定义的过滤器。以下代码阐释了如何注册一个信息包收集器(packet collector)和信息包监听器(packet listener):/ Create a packet filter to listen for new messages from a particular/ user. We use an AndFilter to combine two other filters.PacketFilter filter = new AndFilter(new PacketTypeFilt

23、er(Message.class),new FromContainsFilter(mar);/ Assume weve created an XMPPConnection name connection./ First, register a packet collector using the filter we created. PacketCollector myCollector = connection.createPacketCollector(filter);/ Normally, youd do something with the collector, like wait f

24、or new packets./ Next, create a packet listener. We use an anonymous inner class for brevity.PacketListener myListener = new PacketListener() public void processPacket(Packet packet) / Do something with theing packet here.;/ Register the listener. connection.addPacketListener(myListener, filter);标准信

25、息包过滤器(Standard Packet Filters)Smack 包含一套丰富的信息包过滤器,你也可以通过信息包过滤器接口(PacketFilter interface)编写程序来创建自己的过滤器。缺省的过滤器集包括:PacketTypeFilter 某个特殊的类类型的信息包过滤器 PacketIDFilter 拥有特殊的信息包 ID(packet ID)的过滤器 ThreadFilter 拥有特殊线程 ID(thread ID)的信息包的过滤器 ToContainsFilter 发送到某个特殊地址的信息包的过滤器 FromContainsFilter -发送到某个特殊地址的信息包的过滤

26、器 PacketExtensionFilter 拥有特殊的信息包扩展的信息包的过滤器 AndFilter 对两个过滤器实施逻辑与操作的过滤器OrFilter -对两个过滤器实施逻辑或操作的过滤器 NotFilter -对一个过滤器实施逻辑非操作的过滤器Provider Architecture: Packet Extensions and Custom IQsSmack 提供的体系是堵塞自定义的 XML 信息包扩展和 IQ 包分析器的系统(The Smack provider architecture is a system for plugging in custom XML parsing

27、 of packet extensions and IQ packets)。标准的 Smack 扩展(Smack Exte nsions)是使用提供者的体系结构搭建的。存在以下两种类型的提供者:IQProvider 将IQ 请求( IQ requests)解析成 Java 对象(Java objects)PacketExtension 将附属在信息包上的 XML 子文档解析成信息包扩展实例(PacketExtension instances) IQProvider默认情况下,Smack 致知道如何处理只有类似以下几个名字空间的子信息包的 IQ 信息包(IQ packets): jabber:i

28、q:authjabber:iq:roster jabber:iq:register因为许多 IQ 类型是XMPP 及其扩展部分的一部分,所以提供一个可插入的 IQ 分析机制。IQ Providers 被程序自动的注册或通过创建在你的 JAR 文件的 META-INF 目录下创建一个 viders 文件。该文件是一个包含一个或多个 iqProvider 条目(iqProvider entries)的 XML 文档,如下例所示:queryjabber:iq:timeorg.jivesoftware.smack.packet.Time每一个 IQ provider 都和一个元素名(element n

29、ame)和名字空间( namespace)相联系。在上面的例子中,元素名是 query,名字空间是 abber:iq:time。如果有多重提供者条目(multiple provider entries)尝试注册并控制相同的名字空间,那么从类路径(classpath)载入的第一个条目将有优先权。IQ provider 类可以实现 IQProvide 接口,或者继承 IQ 类。在前面的例子中,每一个 IQProvider 负责解析原始的 XML 流从而创建一个 IQ 实例。在下面的例子中,bean introspection 将被用于尝试自动使用在 IQ packet XML 中发现的值设置IQ

30、实例的属性。一个 XMPP 时间信息包如下所示: 20020910T17:58:35MDTTue Sep 10 12:58:35 2002 from=mary为了让这个信息包自动的映射成上面的 providers file 中所列的时间对象(Time object),它必须有以下几个方法: setUtc(String), setTz(String), 和 setDisplay(String)。自动检查(introspection)的服务将试着自动的将字符串值转化成 a boolean, int, long, float, double,或 Class 类型。转化成何种类型由 IQ 实例的需要来

31、决定。 PacketExtensionProvider信息包插件提供者(Packet extension providers)为信息包提供一个可插入的系统,这些信息包是一个 IQ, message 和 presence packets 的自定义名字空间的子元素。每一个插件提供者(extension provider)使用一个元素名(element n ame)和名字空间(namespace)在 viders 文件中注册,如下例所示: xjabber:iq:eventorg.jivesoftware.smack.packet.MessageEvent如果有多重提供者条目(multiple pro

32、vider entries)尝试注册并控制相同的名字空间,那么从类路径(classpath)载入的第一个条目将有优先权。一旦在一个信息包中发现信息包插件,解析器将传递到正确的提供者。每一个提供者可以实现 PacketExtensionProvider接口或者是一个标准的 Java Bean。在前面的例子中,每一个插件提供者(extension provider)负责解析原始的 XML 流去构造一个实例。在下面的例子中,bean introspection 将被用于尝试自动使用在信息包插件子元素(packet extension sub-element)中的值设置类的属性。当一个插件提供者(ex

33、tension provider)没有用元素名(element name)和名字空间(namespace)对注册是, Smack 将存储所有在缺省信息包插件(DefaultPacketExtension)对象中的最高级别元素(top-level elements),并匹配到信息包上。信息包属性(Packet Properties)Smack 提供简单的机制来将任意的属性附加到信息包上。每一个属性有个字符串类型的名字和一个值,这个值或者是 Java原始数据类型(int, long, float, double, boolean)的,或者是任何可序列化的对象(Serializable object

34、)(当一个 java 对象实现了 Serializable 接口时,它就是可序列化的)。使用 API(Using the API)所有主要对象都有属性支持,例如消息对象(Message objects)。以下代码阐释了如何设置属性: Message message = chat.createMessage();/ Add a Color object as a property. message.setProperty(favoriteColor, new Color(0, 0, 255);/ Add an int as a property. message.setProperty(favo

35、riteNumber, 4); chat.sendMessage(message);获得这些相同的属性要用到以下的代码: Message message = chat.nextMessage();/ Get a Color object property.Color favoriteColor = (Color)message.getProperty(favoriteColor);/ Get an int property. Note that properties are always returned as/ Objects, so we must cast the value to an

36、 Integer, then convert/ it to an favoriteNumber = (Integer)message.getProperty(favoriteNumber).intValue();将对象作为属性(Objects as Properties)将对象作为属性值是改变数据的一个非常有力和简单的方法。但是,你应该记住以下几点:l信息包插件(Packet extensions)是向 XMPP 增加额外数据的更权威的方式。使用属性在某种情况下也许会比较方便,但是,Smack 将会控制 XML。l当你将 Java 对象(Java object)作为属性发送时,

37、只有在客户机运行的 Java 能够解释数据。所以,可以考虑使用一系列的原始值来传递数据。l作为属性值发送的对象必须实现序列化接口(Serialiable)。除此之外,发送者和接受者都必须由相同版本的类,否则在反序列化(de-serializing the object)对象时将发生序列化异常。l序列化的对象将会非常大,将会占用很多的服务器资源和带宽。XML 格式(XML Format)当前的用于发送属性的 XML 格式不是标准的,所以可能不会得到使用 Smack 的客户的认可。XML 如下所示(为了更清晰添加了注释):prop1123blah2adf612fna9nab当前支持的数据类型有:i

38、nteger, long, float, double, boolean, string, 和 java-object。使用 Smack 调试(Debugging with Smack)Smack 包含两个内置的调试控制台,他们允许你在服务器和客户机建跟踪 XML 的踪迹。简单的调试器(lite debugger)是smack.jar 的一部分,加强的调试器(enhanced debugger)包含在(smackx-debug.jar)中。可以用两种不同的方法激活调试模式:1在创建连接前加入以下一行代码:XMPPConnection.DEBUG_ENABLED = true;2将Java 的系统属性 smack.debugEnabled 设置为 true。这一系统属性可通过下一命令行设置:java -Dsmack.debugEnabled=true SomeApp在你的应用程序中,如果你想明确的禁用调试模式,包括使用命令行参数,则在打开新的连接前在你的应用程序中添加以下一行代码:XMPPConnection.DEBUG_ENABLED =

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论