XMPP+Openfire4.5.1+Smack4.3.4+MySql

关于XMPP,14年的时候就已经写过几篇博客了,服务器使用Openfire,安卓客户端使用asmack.jar,不过asmack现在已经停止维护,而Openfire和配套的smack.jar则一直在更新,所以这篇博客主要来写如何用最新的openfire4.5.1+smack4.3.4完成XMPP的初步实现!

效果如下图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面为安卓客户端和PC端的Spark实现即时聊天,当然可以手机和手机聊。相关资源下载地址:https://igniterealtime.org/downloads/index.jsp

至于Openfire的安装方法,基本跟之前没什么变化,可以参考之前的文章有介绍,在使用Openfire前,请务必安装好数据库,本例中使用的是MySql,安卓完成后,启动Openfire:
客户端:
在这里插入图片描述
数据库(数据库名自定义):
在这里插入图片描述
表示安装成功!

可以开始写安卓端APP了!

Smack.jar中的方法跟之前的asmack有相似也有区别,首先说Smack最新的登录方式如下:

                    InetAddress addr = InetAddress.getByName(Const.XMPP_HOST);
                    HostnameVerifier verifier = new HostnameVerifier() {
                        @Override
                        public boolean verify(String hostname, SSLSession session) {
                            return false;
                        }
                    };
                    DomainBareJid serviceName = JidCreate.domainBareFrom(Const.XMPP_DOMAIN);//Domain 服务器名称
                    XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
                            .setHost(Const.XMPP_HOST)
                            .setPort(5222)
                            .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
                            .setXmppDomain(serviceName)
                            .setHostnameVerifier(verifier)
                            .setHostAddress(addr)
                            .setConnectTimeout(30000)
                            .build();
                    xmpptcpConnection = new XMPPTCPConnection(config);
                    //开启重联机制
//                    ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(xmpptcpConnection);
//                    reconnectionManager.setFixedDelay(5);
//                    reconnectionManager.enableAutomaticReconnection();
                    //连接
                    xmpptcpConnection.connect();
                    //登录
                    xmpptcpConnection.login(PreferencesUtils.getSharePreStr(context, Const.ACCOUNT), PreferencesUtils.getSharePreStr(context, Const.PWD));
                    if (xmpptcpConnection.isAuthenticated()) {//登录成功
                       
                    } else {//登录失败
                      
                    }

端口5222固定的,其它重要的两个参数:host域名和Domain服务器名称:这是在安装openfire已经设置好的:
在这里插入图片描述
这里我将两个名称设置一样了!

注册方法,只要在connect成功后,调用以下方法即可:

AccountManager accountManager = AccountManager.getInstance(xmpptcpConnection);
accountManager.sensitiveOperationOverInsecureConnection(true);
accountManager.createAccount(Localpart.from(username), pwd);

注意XMPP连接等方法需要线程中进行,切记!

监听连接状态addConnectionListener:

    ConnectionListener connectionListener = new ConnectionListener() {
        @Override
        public void connected(XMPPConnection connection) {
          
        }

        @Override
        public void authenticated(XMPPConnection connection, boolean resumed) {

        }

        @Override
        public void connectionClosed() {

        }

        @Override
        public void connectionClosedOnError(Exception e) {

        }
    };

监听消息接收:

ChatManager.getInstanceFor(xmpptcpConnection).addIncomingListener(new IncomingChatMessageListener() {
        @Override
        public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {

        }
    })

监听消息发送:

ChatManager.getInstanceFor(xmpptcpConnection).addOutgoingListener(new OutgoingChatMessageListener() {
        @Override
        public void newOutgoingMessage(EntityBareJid from, Message message, Chat chat) {

        }
    })

发送消息:

 EntityBareJid jid = JidCreate.entityBareFrom(to + "@" + Const.XMPP_DOMAIN);
 Chat chat = XMPPConnectionUtil.getChatManager().chatWith(jid);
  if (chat != null) {
      Message message = new Message();
      message.setBody(msg);
      chat.send(message);
  }

接收离线消息:
首先看上面登录的方法中有设置:

.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)

此方法表示以离线状态登录,这样才能去接收离线消息,在登录成功后:

 OfflineMessageManager offlineMessageManager = new OfflineMessageManager(XMPPConnectionUtil.getInstance());
                List<Message> messageList = offlineMessageManager.getMessages();
                for (Message message : messageList) {
                    LogUtil.e("离线消息>>" + message.getBody());
                }
                offlineMessageManager.deleteMessages();
                XMPPConnectionUtil.getInstance().sendStanza(new Presence(Presence.Type.available));

离线消息获取完毕后,将登录状态设置为上线available。

由于smack自带的重连机制并不好用,所以需要我们自己写靠谱的重连机制,我们需要在ConnectionListener做监听,一旦发现连接错误等,变启动重连机制,本项目中做法:

    @SuppressLint("HandlerLeak")
    public Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull android.os.Message msg) {
            super.handleMessage(msg);
            LogUtil.e("重新连接>>");
            XMPPConnectionUtil.login(mContext, new XMPPConnectionUtil.OnLoginListener() {
                @Override
                public void onLogin(boolean isLogin, String error) {
                    if (!TextUtils.isEmpty(error) && error.contains("already logged")) {
                        handler.removeMessages(0);
                        return;
                    }
                    if (isLogin) {//连接成功
                        LogUtil.e("连接成功>>");
                        XMPPConnectionUtil.getInstance().addConnectionListener(connectionListener);
                        XMPPConnectionUtil.getChatManager().addIncomingListener(incomingChatMessageListener);
                        XMPPConnectionUtil.getChatManager().addOutgoingListener(outgoingChatMessageListener);
                        handler.removeMessages(0);
                    } else {
                        LogUtil.e("连接失败>>");
                        handler.sendEmptyMessageDelayed(0, 5000);
                    }
                }
            });
        }
    };

    /**
     * 连接状态监听
     */
    ConnectionListener connectionListener = new ConnectionListener() {
        @Override
        public void connected(XMPPConnection connection) {
            handler.removeMessages(0);
            LogUtil.e("connected>>");
        }

        @Override
        public void authenticated(XMPPConnection connection, boolean resumed) {
            handler.removeMessages(0);
            LogUtil.e("authenticated>>" + resumed);
        }

        @Override
        public void connectionClosed() {
            removeListener();
            handler.sendEmptyMessage(0);
            LogUtil.e("connectionClosed>>");
        }

        @Override
        public void connectionClosedOnError(Exception e) {
            removeListener();
            handler.sendEmptyMessage(0);
            LogUtil.e("connectionClosedOnError>>" + e.getMessage());
        }
    };

项目中也包含了查询用户和好友的方法,简单的基础封装,保持XmppConnect对象单例模式,另外,我将接收消息以及监听连接状态方法写在了MainActivity,而不是像之前一样写在Service,是因为Service管理越来越严格,很容易被杀掉即便应用是打开状态,所以写在ManActivity尽量保证万无一失!

项目地址:
CSDN下载:https://download.csdn.net/download/baiyuliang2013/12375843

GitHub:https://github.com/baiyuliang/xmpp

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白玉梁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值