XMPP 通信之Asmack(一) 建立連接


  先聲明:我這里不分析源碼,只介紹開發包的使用,歡迎大家交流

  openfire+spark+smack是java領域的一種即時通信解決方案;

  Openfire是基於Jabber協議(XMPP)實現的即時通信服務器端版本,網上很容易找到開發包,建議使用能找到的最新開發包;

  Spark支持聊天、語音、視頻、截屏、會議、文件收發、連接MSN等功能,我未找到android方面的支持,各位博友若有謝謝分享;

  Smack是即時通信客戶端編程庫,是基於XMPP的java實現,提供了一套可擴展的API,而Asmack是該編程庫的android版本,這是本文介紹的重點;

  1.什么是XMPP?

  百度百科上解釋的是“XMPP是一種基於標准通用標記語言的子集XML的協議”,簡單的說就是一個收發消息的協議,而這個協議就是基於XML;XMPP的前身是jabber,由一個開源組織產生的即時通信協議,后來由IETF完成標准化工作;

  2.IM

  即”即時通信軟件“,想現在國內使用人比較多的QQ、微信等等,但他們采用的是這些公司自己的通信協議,並不對外開放,一般的公司沒有過於硬性的需求,XMPP協議已經可以滿足我們的需求;

 接下來就是正文,即Asmack的使用:

 1.關於開發包,就盡量使用能找到的最新的開發包,如果需要請在評論區留下郵箱

 2.下面就逐步講解相關使用:

 一、連接,這部分重點是一個類,一個監聽接口

  1.ConnectionConfiguration類,這個類是用來配置連接參數的類

  

     try {
            //初始化時傳入服務器地址和端口號
            connConfig = new ConnectionConfiguration(ChatRoomInfo.openfireAddress, ChatRoomInfo.openfirePort);
            // 設置登錄狀態為離線
            connConfig.setSendPresence(false);
            connConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
            //允許重新連接
            connConfig.setReconnectionAllowed(true);
            //服務器名稱,這個需要跟后台約定好
            connConfig.setServiceName(ChatRoomInfo.serverName);
            con = new XMPPConnection(connConfig);
//紅色標記的部分請留意,后面會詳細講解 con.addPacketListener(
new ChatPacketListener(null), new ChatPacketFilter(context));
            connectionListener = new ViConnectionListener(context,mHandler, successful); con.addConnectionListener(connectionListener);

//開始連接 con.connect();
if (con.isConnected()) { LogUtil.w("conn is conn");//con.addPacketListener(new ChatPacketListener(null),new PacketTypeFilter(Message.class)); } LogUtil.i("XmppTool......連后接22222222222"); } catch (Exception e) { }

  2.ConnectionListener 這個接口監聽連接狀態,上面ViConnectionListener類則是我的實現該接口,這個接口的作用在於監聽XMPP的連接狀況,如果連接失敗的情況出現,自動進行重連,及其他情況的處理,自己的代碼如下;

package com.bankeys.general.chatroom.Utils;

import android.content.Context;

import com.bankeys.general.chatroom.Handler.GeneralChatRoomHandler;
import com.bankeys.general.chatroom.Interface.CharRoomCore;
import com.bankeys.general.chatroom.Log.LogUtil;

import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.packet.Presence;

/**
 * 同賬號登錄等情況監聽
 */
public class ViConnectionListener implements ConnectionListener {
    private GeneralChatRoomHandler mHandler;
    private CharRoomCore connectSuccessful;
    private Context context;

    /**
     *
     * @param context
     * @param mHandler  GeneralChatRoomHandler這個是handler的子類,用來處理這里的各種情況,可以視情況而定
     * @param connectSuccessful  這個接口現在看顯得有些多余,畢竟有handler來處理了 就不需要了,不過暫時先放在這里不影響
     */
    public ViConnectionListener(Context context,GeneralChatRoomHandler mHandler, CharRoomCore connectSuccessful) {
        this.mHandler = mHandler;
        this.connectSuccessful = connectSuccessful;
        this.context = context;
    }

    @Override
    public void connectionClosed() {
        //連接關閉
        LogUtil.i("---------connectionClosed---------");
    }

    @Override
    public void connectionClosedOnError(Exception e) {
        //連接錯誤關閉,錯誤連接的情況,參考下就行,這部分目前還沒測試
        LogUtil.i("ViConnectionListener-->connectionClosedOnError");
        if (e.getMessage().contains("conflict")) { //
            LogUtil.i("ViConnectionListener-->同一賬號登陸");
            if (mHandler != null)
                mHandler.obtainMessage(4).sendToTarget();
            //關閉連接,由於是被人擠下線,可能是用戶自己,所以關閉連接,讓用戶重新登錄是一個比較好的選擇
            XmppTool.getInstance().closeConnection();
            // 接下來你可以通過發送一個廣播,提示用戶被擠下線,提示用戶重新登錄
        } else if (e.getMessage().contains("Connection timed out")) {// 連接超時
            LogUtil.i("ViConnectionListener 正在重連......ʱ");

        } else if (e.getMessage().contains("system-shutdown")) {     // 服務器關閉
            LogUtil.w("服務器關閉");
            if (mHandler != null)
                mHandler.obtainMessage(5).sendToTarget();
        }
        LogUtil.i(e.getMessage());
    }

    @Override
    public void reconnectingIn(int arg0) {
        LogUtil.i("ViConnectionListener-->reconnectingIn 正在重新連接......");
    }

    @Override
    public void reconnectionFailed(Exception arg0) {
        LogUtil.i("ViConnectionListener-->reconnectionFailed  重新連接失敗......");
    }

    @Override
    public void reconnectionSuccessful() {
        LogUtil.i("連接成功/登陸成功......");
        // 設置登錄狀態:在線
        Presence presence = new Presence(Presence.Type.available);
        XmppTool.getInstance().getConnection(context,mHandler, connectSuccessful).sendPacket(presence);
        if (connectSuccessful != null) {
            connectSuccessful.onConnectSuccessful();
        }
    }


}

  這里要添加一點說明,在我們建立連接或者建立連接之前記得加上下面的代碼:

    // 靜態加載ReconnectionManager ,重連后正常工作
    static {
        try {
            Class.forName("org.jivesoftware.smack.ReconnectionManager");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM