Smack类库详细介绍
来源:互联网 发布:怎样注册淘宝账号 编辑:程序博客网 时间:2024/05/29 18:32
Smack是一个为使用XMPP服务器聊天和发送即时消息交流而提供的库。
Smack的主要优势:
l
XMPPConnection connection = new XMPPConnection("jabber.org");
connection.login("mtucker", "password");
connection.createChat("jsmith@jivesoftware.com").sendMessage("Howdy!;
l
l
l
l
关于XMPP
XMPP (eXtensible Messaging and PresenceProtocol)是一个开放的,
如何使用本文档
本文档假定你已经熟悉XMPP即时消息的主要特征。我们推荐你在阅读该文档时打开JavadocAPI作为参考。
开始Smack
本文档将向你介绍Smack API,并大概介绍几个重要的类和概念。
必备的条件
你只需要有JDK 1.2或之后的版本1和已经内嵌在smack..jar文件中的XML分析器,不需要第三部分库。
1JDK 1.2 and 1.3的用户若想使用SSL连接必须在他的类路径下有JSSE库。
建立一个连接
XMPPConnection类是为XMPP服务器建立连接的类。若要创建SSL连接,需使用SSLXMPPConnection类,以下是创建连接的例子。
// Create a connection to thejabber.org server.
XMPPConnection conn1 =newXMPPConnection("jabber.org");
// Create a connection to thejabber.org server on a specific port.
XMPPConnection conn2 =newXMPPConnection("jabber.org",5222);
// Create an SSL connection tojabber.org.
XMPPConnection connection =newSSLXMPPConnection("jabber.org");
如果创建了一个连接,你应该使用XMPPConnection.login(String username,String password)方法(参数为用户名和密码)进行登陆。一旦登陆成功,你就可以通过创建一个新的Chat 或GroupChat对象与其它用户聊天。
使用花名册(Working with theRoster)
读、写信息包(Reading and WritingPackets)
// Create a new presence. Pass in false to indicate we're unavailable.
Presence presence = new Presence(Presence.Type.UNAVAILABLE);
presence.setStatus("Gone fishing");
// Send the packet (assume we have a XMPPConnection instance called "con").
con.sendPacket(presence);
Smack提供以下两种方法阅读收到的信息包:PacketListener和PacketCollector。它们都使用PacketFilter的实例来决定应该处理哪个信息包。信息包监听器(packetlistener)用于事件类型的设计,而信息包收集器(packetcollector)有一个信息包的结果队列,你可以对其实施polling和blocking操作。所以,信息包监听器在你收到任何一个信息包,且你想对其进行操作时是有用的,而信息包收集器在你想等待某个特殊的信息包时是有用的。信息包收集器和监听器可以通过XMPPConnection的实例来创建。
Messaging Basics
Messaging using Chat andGroupChat
互相发送消息是即时通讯的核心,以下是两个在收发消息是用的类:
- org.jivesoftware.smack.Chat– 用于两个人之间发送消息
- org.jivesoftware.smack.GroupChat –用于加入聊天室,很多人之间相互发送消息。
Chat和GroupChat类都用org.jivesoftware.smack.packet .Message信息包类发送消息。在某些情况下,也许你希望绕过更高级别的Chat和GroupChat类直接发送和接受消息。
聊天(Chat)
聊天时在两个用户间创建了一个新的线程(使用一个线程ID)。以下程序片示例了如何如何与一个用户进行开始聊天并发送一段文本消息:
// Assume we've created an XMPPConnection name "connection".
Chat newChat = connection.createChat("jsmith@jivesoftware.com");
newChat.sendMessage("Howdy!");
Chat.sendMessage(String)方法可以很方便的创建一个消息对象,方法体使用字符串类型的参数,然后发送消息。如果想在发送消息前对消息设置额外的只,可以使用Chat.createMessage()and Chat.sendMessage(Message)方法,如下例所示:
// Assume we've created an XMPPConnection name "connection".
Chat newChat = connection.createChat("jsmith@jivesoftware.com");
Message newMessage = newChat.createMessage();
newMessage.setBody("Howdy!");
message.setProperty("favoriteColor", "red");
newChat.sendMessage(newMessage);
使用Chat对象可以轻松的收听其它聊天者的回复。以下程序片是parrot-bot,它映射会其它用户类型的所有事情:
// Assume we've created an XMPPConnection name "connection".
Chat newChat = connection.createChat("jsmith@jivesoftware.com");
newMessage.setBody("Hi, I'm an annoying parrot-bot! Type something 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()方法获得下一条消息,它必需一直等待直到收到下一条消息。也有其它的方法可以等待特定的时间来接受下一条消息,或者你也可以增加一个监听器,它可以在每次收到消息时通知你。
群聊(GroupChat)
群聊在通过一个服务器连接到聊天室,你可以向一组人发送消息或接收他们的消息。在你能接收和发送消息前,你必须使用一个昵称登陆到聊天室。以下程序段可以连接到一个聊天室并发送消息:
// Assume we've created an XMPPConnection name "connection".
GroupChat newGroupChat = connection.createGroupChat("test@jivesoftware.com");
// Join the group chat using the nickname "jsmith".
newGroupChat.join("jsmith");
// Send a message to all the other people in the chat room.
newGroupChat.sendMessage("Howdy!");
,群聊时收发消息和私聊时工作原理大体一致。同样,也有方法可以获得聊天室里其它用户的列表。
Roster and
花名册让你很清楚的知道其它可用的用户。用户可以被分成像“朋友”、“合作者”这样的组。其它的即使通讯系统将花名册作为好友列表、联系列表等。
花名册条目(Roster Entries)
花名册里的每一个用户都以一条花名册条目的形式呈现,包括以下几部分:
- 一个XMPP地址(例如:jsmith@example.com).
- 分配给你的用户名 (例如:"Joe").
- 该条目在花名册中所属组的列表。如果该条目不属于任何一个组,将被称为“尚未分类的条目。
以下程序段可以打印出花名册中的所有条目:
Roster roster = con.getRoster();
for (Iterator i=roster.getEntries(); i.hasNext(); ) {
System.out.println(i.next());
}
也有获得个人条目、尚未分类条目的列表、一个或者所有组的方法。
呈现(Presence)
花名册中的每一个条目都有相关的呈现方式。Roster.getPresence(Stringuser)方法将通过用户的状态或当用户不在线或不同意将其在线状态显示出来时使用空对象(null)返回一个Presence对象。
注意:一般情况下,用户是否同意显示其状态依赖于用户所在的花名册,但这不是在所有情况下都成立的。
用户也有一个在线或离线的状态,如果用户在线,他们的显示信息中将会有一些扩展的信息,例如他当前正在做什么,是否希望被打扰等等,详细内容可以参看Presence类。
Listening for Roster and PresenceChanges
Roster类的典型用途是用树状形式显示组和每一个条目以及它的当前状态。如下图所示是Exodus XMPP客户端的花名册。
显示的信息很可能会经常改变,也有可能是花名册的条目被改变甚至被删除。为了监视花名册的改变和显示的信息,应该使用一个花名册监听器(RosterListener)。以下代码使用Roster(它可以打印出花名册中的任何变化)注册了一个RosterListener。标准的客户端应该使用相似的代码更新花名册的用户信息(roster UI)以正确显示变化的信息。
final Roster roster = con.getRoster();
roster.addRosterListener(new RosterListener() {
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)
花名册和显示使用基于许可的模型,这要求用户在加入别人的花名册前必须得到允许。这样,确保只有被允许的人才可以看到自己所显示的信息,从而保护了用户的隐私。因此,在你想添加一个新的条目,且对方没有接受你的请求前,该条目将处于等待状态。
如果另一个用户请求同意显示,从而你他们可以将你加入他们的花名册,你必须接受或拒绝请求。Smack通过以下三种方式之一操作同意显示请求:
- 自动接受所有的同意显示请求。
- 自动拒绝所有的同意显示请求。
- 手动处理同意显示请求。
可以使用Roster.setSubscriptionMode(intsubscriptionMode)方法设置模式。简单的客户通常使用一个自动接受或拒绝同意显示请求的模式,而用更多特征的用户应该使用手动处理同意显示请求的模式,并让终端用户接受或拒绝每一个请求。如果使用手动模式,应该声明一个信息包监听器(PacketListener)来监听有Presence.Type.SUBSCRIBE类型的显示信息包。
处理收到的信息包(Processing Incoming Packets)
Smack提供一个使用以下两个结构的灵活框架来处理收到的信息包:
- org.jivesoftware.smack.PacketCollector – 一个允许你同步的等待新的信息包的类
- org.jivesoftware.smack.PacketListener – 一个异步的通知你收到信息包的接口
信息包监听器(packet listener)用于事件类型的设计,而信息包收集器(packetcollector)有一个信息包的结果队列,你可以对其实施polling和blocking操作。所以,信息包监听器在你收到任何一个信息包,且你想对其进行操作时是有用的,而信息包收集器在你想等待某个特殊的信息包时是有用的。信息包收集器和监听器可以通过XMPPConnection的实例来创建。
由org.jivesoftware.smack.filter.PacketFilter接口来决定哪个特殊的信息包将被转交给信息包收集器(PacketCollector)或信息包监听器(PacketListener)。可以在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 PacketTypeFilter(Message.class),
new FromContainsFilter("mary@jivesoftware.com"));
// Assume we've created an XMPPConnection name "connection".
// First, register a packet collector using the filter we created.
PacketCollector myCollector = connection.createPacketCollector(filter);
// Normally, you'd do something with the collector, like wait for 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 the incoming packet here.
}
};
// Register the listener.
connection.addPacketListener(myListener, filter);
标准信息包过滤器(Standard Packet Filters)
Smack包含一套丰富的信息包过滤器,你也可以通过信息包过滤器接口(PacketFilter interface)编写程序来创建自己的过滤器。缺省的过滤器集包括:
- PacketTypeFilter – 某个特殊的类类型的信息包过滤器
- PacketIDFilter – 拥有特殊的信息包ID(packet ID)的过滤器
- ThreadFilter – 拥有特殊线程ID(thread ID)的信息包的过滤器
- ToContainsFilter –发送到某个特殊地址的信息包的过滤器
- FromContainsFilter--发送到某个特殊地址的信息包的过滤器
- PacketExtensionFilter– 拥有特殊的信息包扩展的信息包的过滤器
- AndFilter –对两个过滤器实施逻辑与操作的过滤器
- OrFilter --对两个过滤器实施逻辑或操作的过滤器
- NotFilter --对一个过滤器实施逻辑非操作的过滤器
Provider Architecture: Packet Extensions and CustomIQ's
Smack提供的体系是堵塞自定义的XML信息包扩展和IQ包分析器的系统(The Smack provider architecture is asystem for plugging in custom XML parsing of packet extensions andIQ packets)。标准的Smack扩展(Smack Extensions)是使用提供者的体系结构搭建的。存在以下两种类型的提供者:
- IQProvider –将IQ请求(IQ requests)解析成Java对象(Java objects)
- PacketExtension – 将附属在信息包上的XML子文档解析成信息包扩展实例(PacketExtensioninstances)
IQProvider
默认情况下,Smack致知道如何处理只有类似以下几个名字空间的子信息包的IQ信息包(IQ packets):
- jabber:iq:auth
- jabber:iq:roster
- jabber:iq:register
因为许多IQ类型是XMPP及其扩展部分的一部分,所以提供一个可插入的IQ分析机制。IQ Providers被程序自动的注册或通过创建在你的JAR 文件的META-INF目录下创建一个mack.providers文件。该文件是一个包含一个或多个iqProvider条目(iqProvider entries)的XML文档,如下例所示:
<?xml version="1.0"?>
<smackProviders>
<iqProvider>
<elementName>query</elementName>
<namespace>jabber:iq:time</namespace>
<className>org.jivesoftware.smack.packet.Time</className>
</iqProvider>
</smackProviders>
每一个IQ provider都和一个元素名(element name)和名字空间(namespace)相联系。在上面的例子中,元素名是query,名字空间是abber:iq:time。如果有多重提供者条目(multiple providerentries)尝试注册并控制相同的名字空间,那么从类路径(classpath)载入的第一个条目将有优先权。
IQ provider类可以实现IQProvide接口,或者继承IQ类。在前面的例子中,每一个IQProvider负责解析原始的XML流从而创建一个IQ实例。在下面的例子中,bean introspection将被用于尝试自动使用在IQ packet XML中发现的值设置IQ实例的属性。一个XMPP时间信息包如下所示:
<iq type='result' to='joe@example.com' from='mary@example.com' id='time_1'>
<query xmlns='jabber:iq:time'>
<utc>20020910T17:58:35</utc>
<tz>MDT</tz>
<display>Tue Sep 10 12:58:35 2002</display>
</query>
</iq>
为了让这个信息包自动的映射成上面的providers file中所列的时间对象(Time object),它必须有以下几个方法:setUtc(String), setTz(String),和 setDisplay(String)。自动检查(introspection)的服务将试着自动的将字符串值转化成a boolean, int, long, float,double,或Class 类型。转化成何种类型由IQ实例的需要来决定。
PacketExtensionProvider
信息包插件提供者(Packet extension providers)为信息包提供一个可插入的系统,这些信息包是一个IQ, message和presence packets的自定义名字空间的子元素。每一个插件提供者(extension provider)使用一个元素名(element name)和名字空间(namespace)在smack.providers文件中注册,如下例所示:
<?xml version="1.0"?>
<smackProviders>
<extensionProvider>
<elementName>x</elementName>
<namespace>jabber:iq:event</namespace>
<className>org.jivesoftware.smack.packet.MessageEvent</className>
</extensionProvider>
</smackProviders>
如果有多重提供者条目(multiple provider entries)尝试注册并控制相同的名字空间,那么从类路径(classpath)载入的第一个条目将有优先权。
一旦在一个信息包中发现信息包插件,解析器将传递到正确的提供者。每一个提供者可以实现PacketExtensionProvider接口或者是一个标准的Java Bean。在前面的例子中,每一个插件提供者(extension provider)负责解析原始的XML流去构造一个实例。在下面的例子中,bean introspection将被用于尝试自动使用在信息包插件子元素(packet extensionsub-element)中的值设置类的属性。
当一个插件提供者(extension provider)没有用元素名(element name)和名字空间(namespace)对注册是,Smack将存储所有在缺省信息包插件(DefaultPacketExtension)对象中的最高级别元素(top-level elements),并匹配到信息包上。
信息包属性(Packet Properties)
Smack提供简单的机制来将任意的属性附加到信息包上。每一个属性有个字符串类型的名字和一个值,这个值或者是Java原始数据类型(int, long, float, double,boolean)的,或者是任何可序列化的对象(Serializableobject)(当一个java对象实现了Serializable接口时,它就是可序列化的)。
使用API(Using theAPI)
所有主要对象都有属性支持,例如消息对象(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("favoriteNumber", 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 Integer, then convert
// it to an int.
int favoriteNumber = ((Integer)message.getProperty("favoriteNumber")).intValue();
将对象作为属性(Objects asProperties)
将对象作为属性值是改变数据的一个非常有力和简单的方法。但是,你应该记住以下几点:
l
l
l
l
XML格式(XML Format)
当前的用于发送属性的XML格式不是标准的,所以可能不会得到使用Smack的客户的认可。XML如下所示(为了更清晰添加了注释):
<!-- All properties are in a x block. -->
<properties xmlns="http://www.jivesoftware.com/xmlns/xmpp/properties">
<!-- First, a property named "prop1" that's an integer. -->
<property>
<name>prop1</name>
<value type="integer">123</value>
<property>
<!-- Next, a Java object that's been serialized and then converted
from binary data to base-64 encoded text. -->
<property>
<name>blah2</name>
<value type="java-object">adf612fna9nab</value>
<property>
</properties>
当前支持的数据类型有:integer, long, float, double, boolean, string, 和java-object。
使用Smack调试(Debugging withSmack)
Smack包含两个内置的调试控制台,他们允许你在服务器和客户机建跟踪XML的踪迹。简单的调试器(litedebugger)是smack.jar的一部分,加强的调试器(enhanceddebugger)包含在(smackx-debug.jar)中。
可以用两种不同的方法激活调试模式:
1.
XMPPConnection.DEBUG_ENABLED =true;
2.
java -Dsmack.debugEnabled=trueSomeApp
在你的应用程序中,如果你想明确的禁用调试模式,包括使用命令行参数,则在打开新的连接前在你的应用程序中添加以下一行代码:
XMPPConnection.DEBUG_ENABLED =false;
Smack使用一下的逻辑来决定使用哪个调制控制台:
1.
java-Dsmack.debuggerClass=my.company.com.MyDebugger SomeApp
2.
3.
增强的调试器(enhanceddebugger)
当调试模式可用时,将出现一个包含每一个创建的连接的标签调试窗口,该窗口包含以下信息:
- 连接标签(Connection tabs)-- 每一个标签显示连接相关的调试信息
- Smack信息标签(Smack info tab) -- 显示关于Smack的信息 (例如: Smack的版本(Smackversion),安装的组件(installedcomponents),等等)。
连接标签包含以下信息:
- 所有的信息包(All Packets)-- 显示由Smack解析的发送和收到的信息包的信息。
- 未经处理的发送信息包(Raw SentPackets) --未经处理的XMLtraffic(raw XMLtraffic)由Smack生成并发送至服务器 。
- 未经处理的接收信息包(Raw ReceivedPackets) --未经处理的XMLtraffic(raw XMLtraffic)由服务器发送给客户机。
- Ad-hoc 消息(Ad-hoc message)-- 允许发送各种类型的ad-hoc信息包(ad-hoc packets)。
- 信息—显示连接状态和统计信息。
简单的调试器(LiteDebugger )
当调试模式可用时,每创建一个连接将出现调试窗口,该窗口包含以下信息:
- 客户端的流量(Client Traffic) (红色的文本)--未经处理的XMLtraffic(raw XMLtraffic)由Smack生成并发送至服务器 。
- 服务器端的流量(ServerTraffic)(蓝色的文本)--未经处理的XML traffic(raw XML traffic)由服务器发送给客户机。
- 解释的信息包(InterpretedPackets)(绿色的文本) –显示来自服务器的由Smack解析的XML信息包(XMLpackets)
右击任何面板会出现一个菜单,上面有一个选项可以将这些内容拷贝到系统的剪贴板或者清除面板中的内容。
- Smack类库详细介绍
- Smack类库详细介绍
- Smack类库详细介绍
- Smack类库详细介绍
- Smack类库详细介绍
- Smack类库详细介绍
- Smack类库详细介绍
- Smack类库详细介绍
- Smack类库介绍
- IM开发【1】 - Smack类库详细介绍 - 基于XMPP的即时通讯机制
- IM开发【1】 - Smack类库详细介绍 - 基于XMPP的即时通讯机制
- smack类库介绍和使用
- 基于xmpp openfire smack开发之smack类库介绍和使用[2]
- 基于xmpp openfire smack开发之smack类库介绍和使用[2]
- 基于xmpp openfire smack开发之smack类库介绍和使用[2]
- 基于xmpp openfire smack开发之smack类库介绍和使用[2]
- 基于xmpp openfire smack开发之smack类库介绍和使用[2]
- 基于xmpp openfire smack开发之smack类库介绍和使用[2]
- Oracle 行链接(Row chaining) 与行迁移(Row Migration)
- 转:用Imagick替代php的GD库-强大~
- log4j的配置
- dev for openfire with eclipse
- Oracle Golden Gate体系架构详解(转载)
- Smack类库详细介绍
- android适配和设计问题一
- Oracle部分常用语句
- asmack问题记录
- eclipse配置java注释模板
- Openfire 集群,周期性挂掉猜测
- 怎么查看电脑开关机时间记录
- android 学习指南备忘
- 两个日期的时间差