zoukankan      html  css  js  c++  java
  • 技术笔记:XMPP之openfire+spark+smack

    在即时通信这个领域目前只找到一个XMPP协议,在其协议基础上还是有许多成熟的产品,而且是开源的。所以还是想在这个领域多多了解一下。

    XMPP协议:具体的概念我就不写了,毕竟这东西网上到处是。简单的说就是基于XML的一种协议。其解决了什么问题呢?就是给即时通讯制定了标准,大家只要遵守标准就可以完成即时通信的功能。有了标准的好处就是可以有各种不同的实现,大家在这个标准上发展自己的特长。而且还给即时通信提供了互联互通的基础。XMPP协议据网上说还是比较优秀的,表现就是google等大公司都在自己的即时通讯产品上。

    openfire:是我在这个万花丛中找到的一点红。选它的主要原因是:

    1、它支持XMPP咯

    2、它是java实现的,开源的

    3、它比较有名,性能不错

    4、部署挺简单的,还有许多现成的插件

    至于openfire的安装部署网上文章比较多,这里也不打算写。可以到这个网站上找到比较多的资源:http://www.igniterealtime.org/

    为什么说openfire部署简单,我当时只是下载了一个exe的安装包,然后在windows下按照向导安装部署配置后,再整个客户端就可以聊天了。而且在igniterealtime上有配套的客户端产品,还有类库提供。对于开发者来说很方便,而且很实用。

    然而我花了较多时间研究的并不是服务端,毕竟这部分还没到实际的产品开发,只要能跑即可。所以时间都花在哪了呢?就是客户端,毕竟spark这个客户端的界面有点老久,而且聊天功能完成的也比较原始。所以就得花比较多的时间在这上面。

    另外,实际的需求对客户的要求是可以适用多平台:windows,macos,android,ios,甚至还要能在浏览器中。毕竟之前没有做过即时通讯的产品,这一下子还真有点拿不到点。于是只好一个个去接触了解。经过了解真正能拿来商用的东西不多,只能自己去定制开发。这里有个XMPP的官方网站可以看看:http://xmpp.org/software,这里列举了一些现有的产品和开发包。包括Clients,Servers,Libraries,Projects。openfire就在Servers中可以找到,spark在Clients可以找到,Smack在Libraries中找到。其中的Projects列举了一些使用XMPP协议的比较大的项目,比如Google、whatapp、apple,够大了吧。

    我的想法是围绕igniterealtime来展开吧,毕竟是个持续维护的产品系列。

    1、spark可以使用在多平台上,这样PC端的算是解决了

    2、smack包可以支持android平台,可以在这个包基础上定制开发android的产品

    spark的功能还是比较完整的,文本、图片、文件消息都支持,单聊、群聊也支持。只要在界面上做些定制便可以用于使用了。而且spark的通讯核心还是smack,这也充分说明了smack的重要性。smack新版本已经支持android,为此我就直接写了一个smack的android版本的demo,这样一方面了解一下smack,同时也了解一下android的开发。

    源代码已经放在github上:https://github.com/mini188/SmackDemo

    完成的非常搓,也就是个登录、简单聊天。

    简单的写了一个单例的类:XmppConnectionService,主要是负责与Xmpp服务器的通讯管理,这里面最主要的就是建一个连接,由于smack(4.1.x)的版本更新后和之前老的api不一样了。所以在我在网上看到很多资料都是比较老的写法,试了一段时间都是失败。后来找到方法:

        public void Connect (String userName, String pwd){
            if (_xmppConnection != null && _xmppConnection.isConnected()) {
                return;
            }
    
            XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
            configBuilder.setHost("192.168.45.41");
            configBuilder.setPort(5222);
            configBuilder.setUsernameAndPassword(userName, pwd);
            configBuilder.setServiceName("zrtc");
            configBuilder.setCustomSSLContext(getSslContent());
            //configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
    
            _xmppConnection = new XMPPTCPConnection(configBuilder.build());
            new Thread() {
                @Override
                public void run() {
                    try {
                        _xmppConnection.connect();
                        _xmppConnection.login();
                    } catch (IOException e) {
                        Log.e("XMPP_CONNLOGIN", e.getMessage());
                    } catch (XMPPException e) {
                        Log.e("XMPP_CONNLOGIN", e.getMessage());
                    } catch (SmackException e) {
                        Log.e("XMPP_CONNLOGIN", e.getMessage());
                    }
                }
            }.start();
        }

    这段代码里主要是两点注意:

    1、服务器通讯要用自定义证书的话要用自定义的SSLConent,说白点就是不验证证书是否可信。这玩意不知道使用有CA签名的证书会不会有这问题。

    2、connect要使用线程来执行,这是由于android中不允许在主线程中跑这种耗时的代码,影响界面响应

    获取登录用户的好友列表:

     Roster roster = Roster.getInstanceFor(_conn);
     Set<RosterEntry> entries = roster.getEntries();

    创建聊天会话:

        private void createChat(Intent intent) {
            _jid = intent.getStringExtra(JID);
            _chat = _chatMgr.createChat(_jid);
    
    
            _chat.addMessageListener(new ChatMessageListener() {
                @Override
                public void processMessage(Chat chat, Message message) {
                    addMessage(message);
                }
            });
        }

    会话还可以监听消息,这样对方发来消息就可以进行处理。比如显示在聊天记录里。

    发送聊天信息:

            _sendButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    EditText sendText = (EditText) findViewById(R.id.textinput);
                    String msg = sendText.getText().toString();
                    if (!msg.equals("")) {
                        Message message = new Message();
                        message.setTo(_jid);
                        message.setBody(msg);
                        message.setType(Message.Type.chat);
                        addMessage(message);
                        try {
                            _chat.sendMessage(message);
                        } catch (SmackException.NotConnectedException e) {
                            e.printStackTrace();
                        }
                        sendText.setText("");
                    }
                }
            });

    还是通过会话_chat,它有一个方法sendMessage就可以将消息发送出去,挺简单的吧。

    最后贴一下聊天的效果吧,真的好搓:

    最后备注一下,这个android的客户端demo代码参考了一个开源项目:https://github.com/siacs/Conversations

  • 相关阅读:
    1094. Car Pooling
    121. Best Time to Buy and Sell Stock
    58. Length of Last Word
    510. Inorder Successor in BST II
    198. House Robber
    57. Insert Interval
    15. 3Sum java solutions
    79. Word Search java solutions
    80. Remove Duplicates from Sorted Array II java solutions
    34. Search for a Range java solutions
  • 原文地址:https://www.cnblogs.com/5207/p/5377510.html
Copyright © 2011-2022 走看看