Xmpp客戶端庫Smack(4.1.4)文檔整理

一、Smack庫概述

????Smack是一個開源、易用的XMPP/Jabber客戶端庫,它使用Java語言開發(fā),由Jive Software開發(fā)。
????Smack的優(yōu)點是編程簡單。
????Smack的缺點是其API并非為大量并發(fā)用戶設計,每個客戶都要1個線程,占用資源相對較大,因此用Smack做模擬測試時,1臺機器只能模擬有限(數(shù)千個)客戶。
????截止2015年10月25日,Smack庫已經(jīng)發(fā)展到4.1.4版。最新的好消息是Smack在4.1.0版后將直接支持Android系統(tǒng),而無需再使用以前的Smack移植版aSmack庫了。Smack庫源碼托管于GitHub,主頁見: https://github.com/igniterealtime/Smack/

1.1 Smack 4的改變

Smack庫從3.4版發(fā)展到4.0.x版后,其API有較大的變化,主要有:
??1. 把Connection類重命名為XMPPConnection類,XMPPConnection類是XMPPTCPConnection類和XMPPBOSHConnection類的父類。
??2. 把各種Provider類進行了分包
??3. keep-alive(持久連接)機制從smack-core庫移到了smack-extensions庫,keep-alive機制現(xiàn)在由PingManager類提供。
??4. PrivacyList類的toString()方法重命名為getName()
??5. 當Chat實例的所有引用都撤掉后,應該調(diào)用Chat.close()方法
否則Chat對象會有內(nèi)存泄露的隱患,直到ChatManager對象被垃圾回收器回收后內(nèi)存泄露隱患才會消失。
??6. ServerTrustManager類被移除了,如果要使用帶SSL認證的XMPP,你只需提供自己的SSLContext對象給ConnectionConfiguration對象即可。
??7. Packet.setProperty()從smack-core庫移到了smack-extensions庫,其API現(xiàn)在可以在org.jivesoftware.smackx.jiveproperties包中找到。
??8. Connection.getAccountManager()方法現(xiàn)在改成了AccountManager.getInstance(XMPPConnection)方法
??9. 異常API做了改進
??10.ToContains過濾器被移除了

1.2 Smack庫的組成

Smack庫可以內(nèi)嵌到任意的Java應用程序中。Smack庫有數(shù)個JAR文件組成,非常具有靈活性。
??1. smack-core.jar提供了核心XMPP功能。都是XMPP RFC規(guī)范定義的XMPP特性。
??2. smack-extensions.jar支持許多由XMPP Standards Foundation定義的擴展(XEP)功能。包括群聊、文件傳輸、用戶搜索等等。以后可查看文檔《擴展手冊》:https://github.com/igniterealtime/Smack/blob/master/documentation/extensions/index.html(目前還是無效的)
??3. smack-experimental.jar支持許多由XMPP Standards Foundation定義的體驗性(XEP)功能。其API和功能特性都被認為是不穩(wěn)定的。
??4.smack-legacy.jar支持許多由XMPP Standards Foundation定義的遺留(XEP)功能。
??5. smack-bosh.jar支持BOSH通信(XEP-0124規(guī)范定義的)。此代碼被認為處于Beta階段。
??6. smack-jingle.jar支持Jingle。此代碼很老,目前處于無維護的狀態(tài)。
??7. smack-resolver-dnsjava.jar支持對DNS SRV記錄的解析,主要用于那些不支持javax.naming API的平臺。
??8. smack-debug.jar用于協(xié)議流量的增強型GUI調(diào)試器。當調(diào)試模式開啟后,如果它在類路徑下,它會自動被使用。以后可查看文檔《調(diào)試模式》:https://github.com/igniterealtime/Smack/blob/master/documentation/debugging.html(目前還是無效的)

二、Smack的配置

Smack的初始化過程涉及到2階段的調(diào)用。
??1.初始化系統(tǒng)屬性通過SmackConfiguration類初始化所有的系統(tǒng)可訪問屬性,這些屬性都是通過getXXX方法取回屬性值的。
??2. 初始化啟動類如果繼承了SmackInitializer接口后,都可以在調(diào)用initialize()方法后得到初始化,這意味著得到初始化的類在啟動后都是活動的。如果沒有繼承SmackInitializer接口,那么要實現(xiàn)初始化,必須要放置一個靜態(tài)代碼塊來實現(xiàn)——他在類裝載時會自動執(zhí)行。初始化是通過配置文件來完成的。默認情況下,Smack會載入Smack JAR文件中內(nèi)嵌的配置文件(它位于org.jivesoftware.smack/smack-config.xml)。這個指定的配置文件包含了一系列需載入初始化的類列表。所有的管理器類型的類都需要被初始化,這些管理器類就包含在上面所說的初始化列表中。

三、XMPPConnection管理

3.1 創(chuàng)建連接

org.jivesoftware.smack.XMPPConnection類可管理到XMPP服務器的連接,它默認的連接實現(xiàn)類是org.jivesoftware.smack.XMPPTCPConnection。它主要使用兩個構(gòu)造方法,
??一個是XMPPTCPConnection(StringserverName)方法,參數(shù)為服務器名。連接會使用所有默認的設置,有:
????1)執(zhí)行DNSSRV查詢,找到服務器確切的地址和端口(通常是5222)。
????2)與服務器協(xié)商最大數(shù)安全,包括TLS加密。但如果有必要,連接會回落到較低的安全設置。
????3)XMPP資源名“Smack”會被用于連接。
??第二個是XMPPTCPConnection(ConnectionConfigurationcc)構(gòu)造器,它會指定高級的連接設置。其中包括:
????1)手動指定服務器地址和端口,而不是通過DNSSRV查詢。
????2)能開啟連接壓縮。
????3)指定自定義的連接資源名(如Work或Home)。用戶到服務器的每一個連接都必須有唯一的資源名。比如對于用戶"jsmith@example.com",完整的帶資源的地址應該是"jsmith@example.com/Smack"。通過攜帶唯一的資源名,用戶可以同時從不同的位置登錄到同一個服務器,這適用于多設備的情況。每一個資源使用的在線優(yōu)先級值:用于決定由哪一個帶資源的指定連接來接收到地址"jsmith@example.com"的消息。

第一種連接方式:

    boolean target = false;  
    AbstractXMPPConnection conn = new XMPPTCPConnection(username, password, serverName);  
    try {  
        conn.connect();  
        target = conn.isConnected();  
        if(target){  
            System.out.println("XMPP 服務器連接成功");  
        }else{  
            System.out.println("XMPP 服務器連接不成功");  
        }  
    } catch (SmackException | IOException | XMPPException e) {  
        e.printStackTrace();  
    }  

第二種連接方式:

   boolean target=false;  
   XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()  
                  .setUsernameAndPassword(username, password)  
                  .setServiceName(serverName)  
                  .setHost(serverName)  
                  .setPort(5222)  
                  .build();  
   AbstractXMPPConnection conn = new XMPPTCPConnection(config);  
        try {  
            conn.connect();  
            target = conn.isConnected();  
            if(target){  
                System.out.println("XMPP 服務器連接成功");  
            }else{  
                System.out.println("XMPP 服務器連接不成功");  
            }  
        } catch (SmackException | IOException | XMPPException e) {  
            e.printStackTrace();  
        }  

3.2 連接和關閉連接

//為新連接創(chuàng)建配置
ConnectionConfigurationconfig = new ConnectionConfiguration(“jabber.org”, 5222);
AbstractXMPPConnectionconn = new XMPPTCPConnection(config);
//連接到服務器
conn.connect();
//登錄到服務器
conn.login(“username”,“password”,“SomeResource”);
 
…
//關閉連接
conn.disconnect();

????默認情況下,一旦連接斷開,Smack會嘗試重建連接。使用ConnectionConfiguration類的setReconnectionAllowed(Boolean)方法可以開啟或關閉重連的功能。重連管理器會立即嘗試重連到服務器,并且會增加延時設置,以便提高重連的成功率。在重連管理器正在等待下一次重連的期間,如果你想強制重連,可以使用AbstractXMPPConnection類的connect()方法,它會嘗試建立一個新連接。如果手動嘗試也失敗了,那么重連管理器會繼續(xù)重連的工作。

四、使用Chat消息通信

????來回收發(fā)消息是即時通信的核心功能。盡管單條消息是以包的形式發(fā)送和接收的,通常還是把他視為聊天的消息字符串,使用org.jivesoftware.smack.Chat類。

4.1 Chat類

????一個聊天Chat會在兩個用戶之間創(chuàng)建一個消息線程(通過線程ID)。下面的代碼片段演示了怎樣創(chuàng)建一個新聊天,然后向用戶發(fā)送一條文本消息:

  //假設已經(jīng)創(chuàng)建了一個名為"connection"的XMPPConnection
  ChatManager chatmanager = connection.getChatManager();
  Chat newChat = chatmanager.createChat("jsmith@jivesoftware.com", newMessageListener(){

    public void processMessage(Chat chat,Message message){
          System.out.println(“Receivedmessage: “+ message);
    }
  });
  try{
      newChat.sendMessage(“Howdy!”);
  }catch(XMPPExceptione){
      System.out.println(“Error Deliveringblock”);
  }

Chat.sendMessage(String)方法可以方便地創(chuàng)建一個消息Message對象,用字符串參數(shù)設置消息正文Body,然后發(fā)送消息。在某些情況下你可能希望在發(fā)送消息前設置額外的值,使用Chat.createMessage()方法和Chat.sendMessage(Message)方法,如下面的代碼片段所示:

   Message newMessage = new Message();
   newMessage.setBody(“Howdy!”);
   message.setProperty(“favoriteColor”,“red”);
   newChat.sendMessage(newMessage);

前面的例子中,我們可以注意到,在創(chuàng)建聊天Chat時指定了一個消息監(jiān)聽器MessageListener,在任意時刻,當來自其它用戶的聊天消息到達后,消息監(jiān)聽器會得到通知。下面的代碼片段使用了監(jiān)聽器做鸚鵡學舌,它會回顯來自其他用戶傳遞的消息。
//假設在聊天Chat中已經(jīng)設置了消息監(jiān)聽器MessageListener

   publicvoid processMessage(Chat chat, Message message){
       // 把用戶發(fā)送的消息內(nèi)容發(fā)送給用戶
       chat.sendMessage(message.getBody());
   }

4.2 來電聊天

????當提示有另一個用戶的聊天消息到了后,設置有輕微的不同,因為你是首次接收到聊天消息。取代明確地創(chuàng)建一個Chat來發(fā)送消息,當ChatManager創(chuàng)建了Chat實例后,你需要注冊處理新創(chuàng)建的Chat實例。ChatManager會通過線程ID找到匹配的Chat,如果Chat不存在,那么它會創(chuàng)建一個新Chat對象來匹配。要得到這個新Chat,你必須注冊來得到通知。可以注冊一個消息監(jiān)聽器來接收所有要到來的消息。

  //假定已經(jīng)創(chuàng)建了名為”connection”的XMPPConnection
  ChatManager  cm = connection.getChatManager().addChatListener(
   new ChatManagerListener(){
      @Override
      public void chatCreated(Chat chat, BooleancreatedLocally){
          if(!createdLocally)
              chat.addMessageListener(newMyNewMessageListener());
    }
});

????除了基于線程的Chat消息,也有一些客戶端不發(fā)送線程ID作為Chat的一部分。要處理這種情況,Smack會基于JID嘗試匹配接收的消息到最匹配現(xiàn)有的Chat。它會嘗試用完整的JID來查找Chat,如果搜不到,再嘗試用基本的JID來查找Chat。如果找不到現(xiàn)有的Chat來匹配,那么會創(chuàng)建一個新Chat。

五、名單Roster和在線狀態(tài)Presence

名單可以讓你跟蹤其他用戶是否在線,而且名單可以讓你把用戶組織到群組,比如朋友群或工作群。而其它的即時通信IM系統(tǒng)則把名單Roster視為好友列表、聯(lián)系人列表等等。

5.1 名單條目

????Roster用于跟蹤其他用戶是否在線。用戶的聯(lián)系人可以以分組的方式進行組織,比如“好友”、“同事”。然后就可以查看組中的每個用戶是否在線了。要檢索Roster,使用XMPPConnection.getRoster()方法。Roster類允許你查找所有的Roster實體,以及他們屬于哪個組,每個實體當前的在線狀態(tài)。名單中的每一個用戶都由RosterEntry來表示,它包括:
????1)一個XMPP地址(比如”jsmith@example.com”)
????2)你為用戶編寫的備注姓名(比如”Joe”)
????3)名單中的群列表。如果名單的條目不屬于任何群組,那么它被稱為"unfiledentry"。
下面的代碼片段會打印名單中所有的條目:

   //假定已經(jīng)創(chuàng)建了名為”connection”的XMPPConnection
   Rosterroster = connection.getRoster();
   Collection<RosterEntry>entries = roster.getEntries();
   for(RosterEntryentry : entries){
             System.out.println(entry);
   }

還有獲取單個條目的方法、獲取"unfiledentry"的方法,獲取一個群或所有群的方法。

5.2 在線狀態(tài)

????名單中的每個條目都有一個與之相關的在線狀態(tài)。Roster.getPresence(Stringuser)方法會返回一個表示用戶是否在線的Presence對象。如果為空是你還沒有訂閱用戶是否在線的返回。注意:通常情況下,在線狀態(tài)的訂閱總是綁定到名單中的用戶,但這并不適應所有的情況。
????一個用戶的在線狀態(tài)要么是在線,要么是離線。當用戶在線時,他們的在線狀態(tài)還可以包含擴展的信息,比如用戶當前正在做什么,用戶是否愿意被打擾等等。具體參考Presence類。

5.3 監(jiān)聽名單Roster和在線狀態(tài)Presence的改變

????Roster類的典型應用場景是以樹狀結(jié)構(gòu)顯示用戶群和列表,并且用戶列表中包含用戶是否在線的狀態(tài)。比如,參考下圖所示的一個ExodusXMPP客戶端的Roster。



????在線狀態(tài)的信息可能會經(jīng)常變化,Roster條目也可能經(jīng)常修改或刪除。要監(jiān)聽Roster和Presence數(shù)據(jù)的變化,你應該使用RosterListener。要得到Roster改變的所有提醒,那么必須在登錄XMPP服務器之前注冊RosterListener。下面的代碼片段注冊了一個Roster的RosterListener,它能夠在標準輸出中打印任何Presence的改變。一個標準的客戶端可以使用類似的代碼用變化的信息來更新Roster界面。

   //假定已經(jīng)創(chuàng)建了名為”connection”的XMPPConnection
   Roster roster = connection.getRoster();
   roster.addRosterListener(new RosterListener(){
       // 忽略事件
       public void entriesAdded(Collection<String> addresses){}

       public void entriesDeleted(Collection<String>addresses){}

       public void entriesUpdated(Collection<String> addresses){}

       public void presenceChanged(Presencepresence){
           System.out.println(“Presencechanged: “+ presence.getFrom() + “ “ + presence);
    }
});

5.4 添加Entries到Roster

????Roster和Presence使用一種基于權限的模型,用戶必須得到其他人的許可才能把這些人添加到Roster。這樣可以保護用戶的隱私,確保了只有獲得同意的用戶才能查看到他們的Presence信息。因此,當你想添加某個用戶到你的Roster中,必須得到該用戶接受你的請求才可以。
如果有用戶請求訂閱你的在線狀態(tài)Presence,這個用戶必須先把你添加到他的Roster,因此他會發(fā)起請求,你必須選擇接受或拒絕該請求。Smack通過以下三種方式來處理Presence的預訂請求:
????1)自動接受所有Presence的預訂請求
????2)自動拒絕所有Presence的預訂請求
????3)手動處理每一個Presence預訂請求
????這三種方式可以通過Roster.setSubscriptionMode(intsubscriptionMode)方法來設置請求的處理方式。簡單的客戶端通常使用第一種自動方式處理預訂請求,而功能比較全的客戶端應該選擇第三種手動處理請求的方式,讓終端用戶自行決定是接受請求或是拒絕請求。如果使用手動方式,應該注冊一個PacketListener來監(jiān)聽Presence.Type.SUBSCRIBE類型的Presence包。

六、讀寫Packet(數(shù)據(jù)包)

????從客戶端發(fā)送到XMPP服務器的每一條消息都稱為一個Packet(數(shù)據(jù)包)。org.jivesoftware.smack.packet庫中包含了XMPP支持的消息Message、在線狀態(tài)Presence、IQ)三種不同的基本數(shù)據(jù)包類型的封裝類。而像Chat或GroupChat這樣的類則提供了更高層的結(jié)構(gòu)來管理數(shù)據(jù)包的自動創(chuàng)建和發(fā)送。但是,開發(fā)者還是可以直接創(chuàng)建和發(fā)送數(shù)據(jù)包的。下面的代碼就是修改自己的在線狀態(tài),讓其他人知道你不在線。

   //假設已經(jīng)創(chuàng)建了一個名為"connection"的XMPPConnection
   Presence presence = new Presence(Presence.Type.unavailable);  
   presence.setStatus("Gone fishing");  

   connection.sendStanza(presence);  

6.1 PacketListener與PacketCollector

Smack提供了兩種讀取到來的數(shù)據(jù)包的方式:
????org.jivesoftware.smack.PacketCollector(包收集器):該類提供synchronously(同步)方法,等待接受數(shù)據(jù)包(Packets).
????org.jivesoftware.smack.PacketListener(包監(jiān)聽器): 該接口提供asynchronously(異步)方法,等待結(jié)束數(shù)據(jù)(Packets)。
????兩者都使用PacketFilter實例來判斷應該處理哪一個數(shù)據(jù)包。PacketListener(包監(jiān)聽器)用于事件風格的編程,而PacketCollector(包收集器)有一個數(shù)據(jù)包的結(jié)果隊列,你可以做輪詢或阻塞等操作。也就是說,如果你想在數(shù)據(jù)包到來時執(zhí)行一些動作,那么包監(jiān)聽器很適合。如果你想等待指定的數(shù)據(jù)包的到來,那么包收集器很適合。包收集器和包監(jiān)聽器都使用Connection連接實例創(chuàng)建。
????數(shù)據(jù)包集合(PacketCollector)和數(shù)據(jù)包接口(PacketListener)是通過XMPPConnection實例對象創(chuàng)建。

6.2 攔截器

????org.jivesoftware.smack.filter.StanzaFilter接口可以決定,那些特定的數(shù)據(jù)包會被傳遞到PacketCollector 或者PacketListener。
許多預先定義的攔截器都實現(xiàn)了org.jivesoftware.smack.filter接口。

下面的代碼片段,演示了注冊的數(shù)據(jù)包監(jiān)聽器和數(shù)據(jù)包集合

// Create a packet filter to listen for new messages from a particular  
// user. We use an AndFilter to combine two other filters._  
StanzaFilter filter = new AndFilter(new StanzaTypeFilter(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);  

標準段落(字符)攔截器
????smack 類庫中已經(jīng)包含很多包攔截器,你也可以創(chuàng)建屬于自己的攔截器,只需要代碼實現(xiàn)StanzaFilter接口,默認的攔截器包含如下:

  • StanzaTypeFilter --特定類型的數(shù)據(jù)包過濾器
  • StanzaIdFilter -- 特定數(shù)據(jù)包標識篩選器
  • ThreadFilter -- 特定線程標識數(shù)據(jù)包過濾器
  • ToContainsFilter -- 特定發(fā)送地址數(shù)據(jù)包過濾器
  • FromContainsFilter -- 特定接受地址數(shù)據(jù)包過濾器.
  • StanzaExtensionFilter -- 特定包擴展數(shù)據(jù)包過濾器
  • AndFilter -- implements the logical AND operation over two filters.
  • OrFilter -- implements the logical OR operation over two filters.
  • NotFilter -- implements the logical NOT operation on a filter.

七、信息包插件提供者

????Smack提供的體系是堵塞自定義的XML信息包擴展和IQ包分析器的系統(tǒng)(The Smack provider architecture is a system for plugging in custom XML parsing of packet extensions and IQ packets)。標準的Smack擴展(Smack Extensions)是使用提供者的體系結(jié)構(gòu)搭建的。存在以下兩種類型的提供者:

  • IQProvider –將IQ請求( IQ requests)解析成Java對象(Java objects)
  • PacketExtension – 將附屬在信息包上的XML子文檔解析成信息包擴展實例(PacketExtension instances)

7.1 IQProvider

???? IQProvider 默認情況下,Smack只知道如何處理類似以下幾個名字空間的子信息包的IQ信息包(IQ packets):
???? jabber:iq:auth
???? jabber:iq:roster
???? jabber:iq:register
因為許多IQ類型是XMPP及其擴展部分的一部分,所以提供一個可插入的IQ分析機制。IQ Providers被程序自動的注冊或通過創(chuàng)建在你的JAR 文件的META-INF目錄下創(chuàng)建一個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)相聯(lián)系。在上面的例子中,元素名是query,名字空間是abber:iq:time。如果有多重提供者條目(multiple provider entries)嘗試注冊并控制相同的名字空間,那么從類路徑(classpath)載入的第一個條目將有優(yōu)先權。
????IQ provider類可以實現(xiàn)IQProvide接口,或者繼承IQ類。在前面的例子中,每一個IQProvider負責解析原始的XML流從而創(chuàng)建一個IQ實例。在下面的例子中,bean introspection將被用于嘗試自動使用在IQ packet XML中發(fā)現(xiàn)的值設置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)的服務將試著自動的將字符串值轉(zhuǎn)化成a boolean, int, long, float, double,或 Class 類型。轉(zhuǎn)化成何種類型由IQ實例的需要來決定。

7.2 PacketExtensionProvider

????PacketExtensionProvider 信息包插件提供者(Packet extension providers)為信息包提供一個可插入的系統(tǒng),這些信息包是一個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)載入的第一個條目將有優(yōu)先權。 一旦在一個信息包中發(fā)現(xiàn)信息包插件,解析器將傳遞到正確的提供者。每一個提供者可以實現(xiàn)PacketExtensionProvider接口或者是一個標準的Java Bean。在前面的例子中,每一個插件提供者(extension provider)負責解析原始的XML流去構(gòu)造一個實例。在下面的例子中,bean introspection將被用于嘗試自動使用在信息包插件子元素(packet extension sub-element)中的值設置類的屬性。 當一個插件提供者(extension provider)沒有用元素名(element name)和名字空間(namespace)對注冊是,Smack將存儲所有在缺省信息包插件(DefaultPacketExtension)對象中的最高級別元素(top-level elements),并匹配到信息包上。

七、smack debug模式講解

????smakc 內(nèi)置兩套debuging 控制臺,讓你追蹤XMPP服務端和客戶端之間所有XML 流動,在smack-debug.jar包含Lite調(diào)試器和增強調(diào)試器,在smack-core.jar包含debug輸出控制臺。
調(diào)試模式可以用不同的方式來啟用:
1、在創(chuàng)建新連接之前,先添加以下代碼行:

SmackConfiguration.DEBUG = true;  

1、設置Java系統(tǒng)屬性smack.debugenabled真實。可以在命令行上設置系統(tǒng)屬性,例如:

java -Dsmack.debugEnabled=true SomeApp  

如果你希望在你的應用程序中顯式禁用調(diào)試模式,可以通過使用命令行參數(shù) 或者是在在打開新連接之前,請在應用程序中添加以下行:

SmackConfiguration.DEBUG = false;  

smack 使用以下邏輯決定調(diào)試控制臺使用;
1、它首先會嘗試使用在Java系統(tǒng)屬性指定類smack.debuggerclass調(diào)試器。如果你需要開發(fā)屬于自己的Debug,需要smackdebugger接口,然后設置系統(tǒng)屬性的命令行如:

java -Dsmack.debuggerClass=my.company.com.MyDebugger SomeApp  

2、如果第一步失敗,Smack會嘗試使用增強型Debug,smackx-debug.jar文件中包含了增強型Debug,因此,你需要將jar文件的路徑添加到ClassPath路徑中。smack-core.jar Lite調(diào)試器和增強調(diào)試器不可用的情況下,只有控制臺調(diào)試器。

增強調(diào)試器



????當smack Debug模式是啟動時,Debug窗口會顯示每一個創(chuàng)建連接信息,同時也包含以下信息:

  • XMPPConnection tabs -- 每個選項卡顯示有關連接的調(diào)試信息.
  • Smack info tab -- shows information about Smack (e.g. Smack version, installed components, etc.). The connection tab will contain the following information:
  • All Stanzas --通過smack 分析發(fā)送和接收的數(shù)據(jù)包的信息分析.
  • Raw Sent Stanzas -- 通過Smack產(chǎn)生的原始XML流量發(fā)送到服務器.
  • Raw Received Stanzas -- 服務器向客戶端發(fā)送的原始XML.
  • Ad-hoc message -- 允許發(fā)送特定類型的數(shù)據(jù)包.
  • Information -- 顯示連接狀態(tài)和統(tǒng)計數(shù).

Lite Debugger



????當smack Debug模式是啟動時,Debug窗口會顯示每一個創(chuàng)建連接信息,同時也包含以下信息:

  • Client Traffic (red text) -- 通過Smack產(chǎn)生的原始XML流量發(fā)送到服務器.
  • Server Traffic (blue text) --服務器向客戶端發(fā)送的原始XML.
  • Interpreted Stanzas (green text) -- shows XML packets from the server as parsed by Smack. Right click on any of the panes to bring up a menu with the choices to copy of the contents to the system clipboard or to clear the contents of the pane.
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內(nèi)容