天天看點

smack 源碼分析一(android上實作長連接配接)

前段時間應一個項目需求: 要求給終端短信, 聯系人資訊做一個雲存儲雲備份及雲端遠端控制終端并且雲端能夠推送消息到終端的需求. 這需要在終端與雲端建立一個長連接配接以便雲端消息能及時推送到終端. 是以項目中用到了smack架構.  smack功能強大, 遠不止本文所寫的這點内容. 現在我隻将對smack的了解以及項目中對smack的使用心得總結并記錄下來, 一則給大家分享 , 二則也算是一個技術經驗的累積. 但基于我混亂的表達能力和可能的了解上的偏差可能會有些錯誤. 歡迎各位大蝦大牛拍磚. 

項目中用到smack的長連接配接這塊關鍵有以下這幾個類: Connection , XMPPConnection , PakcetWriter , PacketReader. 如下圖: 

smack 源碼分析一(android上實作長連接配接)

檢視XMPPConnection源碼: 

protected void connectUsingConfiguration(ConnectionConfiguration config) throws XMPPException {
        String host = config.getHost();
        int port = config.getPort();
        try {

            if (this.socket == null || this.socket.isClosed()) {

                LogUtil.i(TAG, "this.socket == null || this.socket.isClosed()");
                if (config.getSocketFactory() == null) {
                    this.socket = new Socket(host, port);
                } else {
                    this.socket = config.getSocketFactory().createSocket(host, port);
                }
            }
           

可以看到, connectUsingConfiguration(ConnectionConfiguration config) 是長連接配接入口, 傳遞config制定伺服器ipAddress和port , 然後根據config建立一個socket對象. 緊接着調用initConnection()方法, 而在initConnection()中: 

private void initConnection() throws XMPPException {

            usingCompression = false;

        // Set the reader and writer instance variables
        initReaderAndWriter();

        try { 
//            if (isFirstInitialization) {
                packetWriter = new PacketWriter(this);
                packetReader = new PacketReader(this);

                // If debugging is enabled, we should start the thread that will
                // listen for
                // all packets and then log them.
                if (config.isDebuggerEnabled()) {
                    addPacketListener(debugger.getReaderListener(), null);
                    if (debugger.getWriterListener() != null) {
                        addPacketSendingListener(debugger.getWriterListener(), null);
                    }
                }
//            } else {
//                packetWriter.init();
//                packetReader.init();
//            }

            // Start the packet writer. This will open a XMPP stream to the
            // server
            packetWriter.startup();
            // Start the packet reader. The startup() method will block until we
            // get an opening stream packet back from server.
            packetReader.startup();

            // Make note of the fact that we're now connected.
            connected = true;
           

以上執行順序是

1. initReaderAndWriter()方法通過上面建立的socket執行個體化connection

的Writer和Reader.

2. 執行個體化PacketWriter和PacketReader對象.

PacketWriter就是向伺服器發送資料發送心跳包一直保持與伺服器的連接配接連.  PacketReader則是不斷的讀取并且解析伺服器推送的消息.

3. 分别調用packetWriter和packetReader的startup()方法.

至此整個連接配接過程就建立完成了.

   長連接配接大緻流程基本就這樣, 也許還是一頭霧水.  

1.終端如何發生心跳包與伺服器一直保持聯系的呢.

2.伺服器推送消息到終端, 終端是如何根據消息進行分發處理的呢. 

請看: smack 源碼分析- PacketReader (android上實作長連接配接) 和

smack 源碼分析- PacketWriter (android上實作長連接配接) 兩篇文章.