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 plaincopy在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


發佈了76 篇原創文章 · 獲贊 3 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章