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();
        }
    }
原文地址:https://www.cnblogs.com/ZhangXiangQian/p/5254840.html