Smack 中 PacketCollector的作用和用法举例



在 Connection 抽象类中,有一个属性  collectors ,类型是  Collection<PacketCollector> 。 collectors 是一个由 PacketCollector组成的集合。


一、简介


PacketCollector 是一个Packet数据搜集器,根据设置的filter来接收packet数据。

如果filter为空,则接收全部的packet数据。


二、工作原理


怎么接收呢?

PacketCollector中有一个  ArrayBlockingQueue 类型的结果队列 resultQueue,

所有的满足条件的packet都进入队列。


进队列的规则是:从队列尾部进,从队列头部出。队列满了,先进的 packet 就从队列头部溢出,让后来的 packet 进入队列。

这个规则就是有  processPacket(Packet packet) 来执行的,此方法接收新的 packet,然后执行上述进队列的规则。


三、用途


那么,这个 PacketCollector 有什么用呢?

他是为了专门满足某些条件的 packet,比如:在一个修改密码的操作之后,加上一个packetColletor 专门搜集能够响应这个操作的返回结果。

如果这个 packetCollector 里面的 packet 一个也没有,也就是队列为空,则没有收到服务器端的响应。

如果有packet ,就可以获得这个packet 读取返回的结果。


四、用法举例


1、创建一个filter

PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()),

                new PacketTypeFilter(IQ.class));

满足这个filter的所有 packet 都会进入 packetCollector 的队列中。


2、用这个filter 创建一个 packetCollector

PacketCollector collector = connection.createPacketCollector(filter);


3、发送数据到服务器端

connection.sendPacket(reg);


4、接收响应

 IQ result = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());


5、结束搜集

collector.cancel();



五、队列的创建和操作


1、根据filter 创建一个 PacketCollector 并加入集合中


    protected final Collection<PacketCollector> collectors = new ConcurrentLinkedQueue<PacketCollector>();

    public PacketCollector createPacketCollector(PacketFilter packetFilter) {

        PacketCollector collector = new PacketCollector(this, packetFilter);

        collectors.add(collector);

        return collector;

    }


所以,每个connect 可以增加任意多个 packetCollector 。

在什么时候加,在调用 connect.setPacket(packet)之前加,参见用法举例的步骤。


2、获取队列中的数据

collector.nextResult()获取结果,这个方法会等待队列,直到返回结果为止。得到的结果会弹出队列,下一个结果成为队列的顶端元素。

还有一个方法:

collector.pollResult()   也是获取结果,如果有就返回结果,没有就返回null,不会锁定队列。


3、结束搜集

collector.cancel()


六、搜集工作的入口


之前在 PacketReader里面,触发Listener 前面。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void processPacket(Packet packet) {  
  2.     if (packet == null) {  
  3.         return;  
  4.     }  
  5.   
  6.     // Loop through all collectors and notify the appropriate ones.  
  7.     for (PacketCollector collector : connection.getPacketCollectors()) {  
  8.         collector.processPacket(packet);  
  9.     }  
  10.   
  11.     // Deliver the incoming packet to listeners.  
  12.     listenerExecutor.submit(new ListenerNotification(packet));  
  13. }  


七、补充

PacketCollector中队列的大小在配置文件中设置。

配置文件  META-INF/smack-config.xml

对应的设置 <packetCollectorSize>10000</packetCollectorSize>

默认的是  10000





转:http://blog.csdn.net/teamlet/article/details/25834573


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值