转自:
http://blog.csdn.net/wqhjfree/article/details/7194428
PacketReader的作用主要用来接收云端推送的消息并解析然后调用相应的监听器完成相关的操作.
什么都别说, 先看代码:
//构造函数
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;
connectionID = null;
//开辟一个线程, 解析收到的数据包
readerThread = new Thread() {
public void run() {
parsePackets(this);
}
};
readerThread.setName("Smack Packet Reader (" + connection.connectionCounterValue + ")");
readerThread.setDaemon(true);
// Create an executor to deliver incoming packets to listeners. We'll
// use a single
// thread with an unbounded queue.
listenerExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable, "Smack Listener Processor ("
+ connection.connectionCounterValue + ")");
thread.setDaemon(true);
return thread;
}
});
resetParser();
}
/**
* 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));
} else if (parser.getName().equals("iq")) {
processPacket(PacketParserUtils.parseIQ(parser, connection));
} else if (parser.getName().equals("presence")) {
processPacket(PacketParserUtils.parsePresence(parser));
}
构造函数和init()方法PacketWriter一样, 不多说了. 直接看parsePackets(). 在parsePackets()是直接调用processPacket()方法解析, 我们再来看processPacket()方法:
/**
* Processes a packet after it's been fully parsed by looping through the
* installed packet collectors and listeners and letting them examine the
* packet to see if they are a match with the filter.
*
* @param packet the packet to process.
*/
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));
}
在processPacket()的最后一行是通过ExecutorService类型的一个listenerExecutor实例执行一个线程ListenerNotification完成的. 接下来:
/**
* 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() {
//循环读取注册了的监听器并通知处理packet
for (ListenerWrapper listenerWrapper : connection.recvListeners.values()) {
listenerWrapper.notifyListener(packet);
}
}
}
在ListenerNotification的run方法中, 是循环读取connection.recvListeners.values()获取ListenerWrapper
.
那么ListenerWrapper 是什么呢? 我们首先来看这里connection.recvListeners.values(),
这connection实际上
是一个XMPPConnection的一个实例, 而XMPPConnection继承了Connection, recvListeners实际上是Connection
的一个成员变量. 然后再来看ListenerWrapper类:
/**
* A wrapper class to associate a packet filter with a listener.
*
*/
protected static class ListenerWrapper {
private PacketListener packetListener;
private PacketFilter packetFilter;
/**
* Create a class which associates a packet filter with a listener.
*
* @param packetListener the packet listener.
* @param packetFilter the associated filter or null if it listen for
* all packets.
*/
public ListenerWrapper(PacketListener packetListener, PacketFilter packetFilter) {
this.packetListener = packetListener;
this.packetFilter = packetFilter;
}
/**
* Notify and process the packet listener if the filter matches the
* packet.
* @param packet the packet which was sent or received.
*/
public void notifyListener(Packet packet) {
if (packetFilter == null || packetFilter.accept(packet)) {
packetListener.processPacket(packet);
}
}
}
ListenerWrapper类实际上是一个包装类, 该类的作用是将packetListener 和packetFilter关联在一起.
那么
packetListener 和packetFilter分别是什么嗯,
查看smack帮助文档可知:
Smack提供灵活的框架来通过两种构造处理收到的 packet:
org.jivesoftware.smack.PacketCollector —— 一个让您同步等待新packet的类。
org.jivesoftware.smack.PacketListener —— 一个异步通知您引入的packet的接口。
packet监听器用于事件样式的编程,而packet收集器有一个可以做轮询和阻塞操作的packet的结果队列。 所以,
当您想对一个有可能随时到来的packet采取一些操作时,使用packet监听器;而当您想等待一个特别的packet到来
时,使用packet收集器。您可以使用XMPPConnection实例创建packet收集器和监听器。
org.jivesoftware.smack.filter.PacketFilter 接口决定哪个特别的将会被传递
到PacketCollector或PacketListener。org.jivesoftware.smack.filter package包中有许多预定义的过滤器。
packetListener 是一个能够处理随时可能到了的packet监听器,packetFilter能够判断packet是否由该packetListener处理
是的话则调用processPacket()方法处理packet. 至此整个过程处理完成
分享到:
相关推荐
【标题】"smack-resolver-dnsjava-4.0.0-rc2.zip" 提供的是 Smack 开源库的一个版本,其中包含了 DNSJava 的解析器模块。Smack 是一个用于 XMPP(Extensible Messaging and Presence Protocol)的 Java 库,它允许...
标题中的"smack-resolver-javax-4.1.0-alpha6.zip"是一个软件库的压缩包,Smack是一款开源的XMPP客户端库,而"javax"可能指的是它提供了与Java平台兼容的解析器组件。这个版本是4.1.0的Alpha6,意味着它是一个开发...
总之,Smack-3.4.1 是一个强大的XMPP客户端库,为Java开发者提供了全面的工具来构建即时通讯应用,其丰富的功能和良好的社区支持使其成为开发此类应用的首选之一。通过理解和使用Smack,开发者可以轻松地实现即时...
本压缩包"smack-core-4.0.0.zip"包含了Smack Core 4.0.0版本的源代码,这是一个著名的Java即时通讯(Instant Messaging)库,主要用于实现XMPP协议。Smack为开发者提供了丰富的API,使得构建XMPP应用变得更加便捷。 ...
smack4.1.0的依赖包minidns.jar。可用于smack4.1.3,亲测可用!
implementation 'org.igniterealtime.smack:smack-android-extensions:4.3.5' implementation 'org.igniterealtime.smack:smack-tcp:4.3.5' implementation 'org.igniterealtime.smack:smack-im:4.3.5' ...
**Smack-JAR在Android中的应用** Smack是一款开源的XMPP(Extensible Messaging and Presence Protocol)客户端库,用于创建即时通讯应用。它提供了一套完整的API,使得开发者能够轻松地构建XMPP服务器和客户端之间...
"smack-jar包"正是这个库的归档文件,包含了所有必要的类和资源,供开发者在自己的项目中使用。 首先,我们需要了解什么是jar包。Java Archive (JAR) 文件是一种特殊类型的归档文件,它包含了一组Java类文件以及...
这个"smack-1.0-master"压缩包包含的是Smack工具的源代码,主要版本为1.0,并且经过了特定的修改,能够支持`.smackcipso`、`smackload`、`smackaccess`和`smackctl`等工具的使用。下面将详细介绍这些工具和Smack系统...
org.jivesoftware.smack-3.2.2.jar
smack-im-4.2.2.jar smack-tcp-4.2.2.jar smack-extensions-4.2.2.jar smack-core-4.2.2.jar smack-android-extensions-4.2.2.jar jxmpp-jid-0.6.0.jar jxmpp-core-0.6.0.jar jxmpp-util-cache-0.6.0.jar等jar包
在这个项目中,我们利用Smack-4.2.1库来实现在Android上使用XMPP进行各种交互,如登录、注册、发送单聊消息、加入聊天室和发送群聊消息等基本功能。 首先,我们需要了解Smack-4.2.1。Smack是一个开源的Java库,专门...
标题中的“samck 电子文档 smack-1.5.0.jar smackx-1.5.0”提及了两个关键组件,即Smack和SmackX,它们是Java库,主要用于处理XMPP(Extensible Messaging and Presence Protocol)协议。XMPP是一种开放标准,用于...
【标题】"smack-extensions-4.1.0-alpha3.zip" 提供的是 Smack 开源库的一个扩展包,版本为4.1.0的Alpha3版本。Smack 是一个用于XMPP(Extensible Messaging and Presence Protocol)的Java库,它允许开发者在Java...
【标题】"smack-im-4.3.4-sources_www.im.43_im_" 指的是 Smack IM 的4.3.4版本的源代码,这个开源项目主要关注即时通讯(IM)功能的实现。Smack是一个用Java编写的库,允许开发者在他们的应用程序中集成XMPP...
- smack-xmpp-client-core.jar:Smack的核心组件,包含了基础的XMPP客户端功能。 正确地将这些jar包添加到项目的类路径中,你的Java应用就能利用Smack库的强大功能进行XMPP通信。在开发过程中,务必参考Smack的官方...
1. `smack-java7-4.1.6.jar`:这是Smack的主要库,针对Java 7进行了优化,包含了实现XMPP协议的核心功能。 2. `httpclient-cache-4.5.2.jar`:Apache HttpClient库的一个版本,用于处理HTTP请求,可能在Smack中用于...