美文网首页即时通信
android移动端xmpp开发入门

android移动端xmpp开发入门

作者: Lilee丶 | 来源:发表于2018-09-23 11:50 被阅读0次

引入###

即时通信技术现在已经广泛应用到各种app中了,那么他到底是怎么实现的呢。前段时间因为项目开发的需要,了解学习过一些这方面。这篇文章记录的是我个人了解的一些这方面的知识,如果有错误的地方还请斧正指出,非常感谢。
另外 慕课网中 郭大神的关于xmpp的这个课程也对我学习起到了很大的帮助:http://www.imooc.com/learn/223

xmpp###

  • XMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。XMPP目前被IETF国际标准组织完成了标准化工作。标准化的核心结果分为两部分; 核心的XML流传输协议 基于XML流传输的即时通讯扩展应用 XMPP的核心XML流传输协议的定义使得XMPP能够在一个比以往网络通信协议更规范的平台上。借助于XML易于解析和阅读的特性,使得XMPP的协议能够非常漂亮。 XMPP的即时通讯扩展应用部分是根据IETF在这之前对即时通讯的一个抽象定义的,与其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。
  • 上面是xmpp的官方解释,其实我每次看完官方解释,总是懵懵的。好像什么都知道了,也好像什么都不知道。不过在我了解过之后简单总结看来,xmpp就像上面说的,是一套协议。里面定义了很多xml格式的文本。比如当我们要登录到服务器时,怎么告诉服务器呢。按照xmpp协议中的规范封装一段xml的字符串以流的方式传给服务器就好了。以最简单的发送一个消息举例:
   <message
       to='romeo@example.net'
       from='juliet@example.com/balcony'
       type='chat'
       xml:lang='en'>
     <body>Wherefore art thou, Romeo?</body>
   </message>
  1. suke 发送给 beta 一条消息,消息的类型是chat(聊天),消息的内容是 who are you ?。
  • 总结以上,在我理解看来,xmpp 就像是我们平时说话使用的语言,服务器和客户端都遵循这样的规范,比我message 代表一个消息。这样到客户端想给服务器发送一条消息时,就拼装一个以message开头的xml字符串流到服务器。服务器按照xmpp的协议,就知道这是一条消息。听起来感觉傻乎乎的。可是xmpp就是这样的。
  • 如果想深入了解xmpp协议,请搜索《xmpp权威指南》,英文版本和中文版本的都有。

IM即时通信软件该怎么做###

  • 目前网上比较主流的是采用开源的 openfire服务器+smack sdk 进行开发。smack是一个封装了tcp连接和xmpp协议解析的sdk。
    smack的资料可以移步github:https://github.com/igniterealtime/Smack/wiki/Smack-4.2-Readme-and-Upgrade-Guide
    里面提供了详尽的API
  • 我们都知道即时通信是需要做长连接的,而openfire和smack之间的连接采用的是tcp长连接。大家一定都知道心跳包和保持在线,断线重连之类的,我刚开始入手的时候也不知道怎么弄。看了文章开头郭大神的那个基于xmpp的推送后,对于其中的原理不能说豁然开朗吧,也算窥探到了一二。我在这里就不赘述了,那个视频已经讲的很明白了。

Smack怎么用###

  • 连接到服务器。

    • Constant.HOST_SERVER 为服务器IP地址,运行demo时需要修改。
                        InetAddress addr = InetAddress.getByName(Constant.HOST_SERVER);
                      HostnameVerifier verifier = new HostnameVerifier() {
                          @Override
                          public boolean verify(String hostname, SSLSession session) {
                              return false;
                          }
                      };
                      DomainBareJid serviceName = JidCreate.domainBareFrom(Constant.HOST_SERVER);
                      XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
                              .setHost(Constant.HOST_SERVER) // it will be resolved by setHostAddress method
                              .setUsernameAndPassword(username, pwd)
                              .setPort(Constant.HOST_PORT)
                              .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
                              .setXmppDomain(serviceName)
                              .setHostnameVerifier(verifier)
                              .setHostAddress(addr)
                              .setDebuggerEnabled(true)
                              .build();
    
                      connection = new XMPPTCPConnection(config);
                      connection.connect();
    
  • 连接之后,就是登录和获取好友列表(花名册)了。具体的实现

    • roster.addRosterLoadedListener(new RosterLoadedListener() {});这个是添加一个监听,因为再刚登录的时候,直接去获取花名册,服务器返回的经常为空集合。网上有人建议在登录成功之后让线程睡100毫秒,不过还是添加listener优雅一点。

           if (connection.isConnected()) {
                        try {
                            connection.login();
                        } catch (Exception e) {
                            android.os.Message msg = android.os.Message.obtain();
                            msg.what = LOGIN_FAILED;
                            handler.sendMessage(msg);
                        }
                        // Thread.sleep(100);
                        Roster roster = Roster.getInstanceFor(connection);
                        roster.addRosterLoadedListener(new RosterLoadedListener() {
                            @Override
                            public void onRosterLoaded(Roster roster) {
                                Logger.e(TAG,"Get roster success ... " );
                                android.os.Message msg = android.os.Message.obtain();
                                msg.what = LOGIN_SUCCESS;
                                msg.obj = roster;
                                handler.sendMessage(msg);
                            }
      
                            @Override
                            public void onRosterLoadingFailed(Exception exception) {
                                Logger.e(TAG,"Get roster failed : " + exception.getMessage());
                            }
                        });
                        android.os.Message msg = android.os.Message.obtain();
                        msg.what = LOGIN_SUCCESS;
                        msg.obj = roster;
                        handler.sendMessage(msg);
                    } else {
                        android.os.Message msg = android.os.Message.obtain();
                        msg.what = CONNECTION_FAILED;
                        handler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
      
  • 创建聊天室

        private void createChatRoom() {
            // 设置聊天监听器,监听聊天消息
            chatManager = ChatManager.getInstanceFor(connection);
            chatManager.addIncomingListener(mIncomingChatMessageListener);
        }
        
    IncomingChatMessageListener mIncomingChatMessageListener = new IncomingChatMessageListener() {
    //接收消息
        @Override
        public void newIncomingMessage(EntityBareJid from, Message message, org.jivesoftware.smack.chat2.Chat chat) {
            String str = chatMap.get(from.toString());
            String name = from.getLocalpart().toString();
            String msg = message.getBody();
            String type = message.getType().toString();
            if (str == null) {
                str = name + " : " + type + " : " + msg + "\n";
            } else {
                str += name + " : " + type + " : " + msg + "\n";
            }
            chatMap.put(from.toString(), str);
            mainBinding.tvChatCon.setText(str);
        }
    };
    
    //发送消息
    private void sendmsg(String msg, RosterEntry rosterEntry, Message.Type type) {
        Chat currentChat;
        try {
            String jidStr = rosterEntry.getJid().toString();
            EntityBareJid jid = JidCreate.entityBareFrom(jidStr);
            currentChat = chatManager.chatWith(jid);
            Message newMessage = new Message();
            newMessage.setBody(msg);
            newMessage.setType(type);
            currentChat.send(newMessage);
    
            String str = chatMap.get(jidStr);
            if (str == null) {
                str = username + " : " + msg + "\n";
            } else {
                str += username + " : " + msg + "\n";
            }
            chatMap.put(jidStr, str);
            mainBinding.tvChatCon.setText(str);
            mainBinding.etWillSendMsg.setText("");
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (XmppStringprepException e) {
            e.printStackTrace();
        }
    }
    

    总结###

    其实对于xmpp,我现在也只是略微了解一些,上面这些,希望对有这方面需求的同学有所帮助。郭大神的那个视频和xmpp权威指南真的很值得阅读。视频有助于理解客户端与服务器的连接实现,而xmpp权威指南中会告诉你xmpp协议都定义了那些功能(节的概念,发送消息,出席状态,状态订阅,多设备登录哪个优先,发送文件是怎么实现的,为什么只能发送小文件等等很多很多),了解了这些功能也有助于使用smack这个sdk,同时给扩展做好准备。
    好了,希望以上这些,可以对大家有些许帮助,谢谢。

相关文章

  • android移动端xmpp开发入门

    引入### 即时通信技术现在已经广泛应用到各种app中了,那么他到底是怎么实现的呢。前段时间因为项目开发的需要,了...

  • 那些年收藏的技术文章(二)-云笔记篇

    IM、推送、保活相关 Android进程保活招式大全 新手入门一篇就够:从零开发移动端IM Android端外推送...

  • 那些年收藏的技术文章(二)-云笔记篇

    Android IM、推送、保活相关 Android进程保活招式大全新手入门一篇就够:从零开发移动端IMAndro...

  • 4. 移动端适配相关概念

    1. 什么是移动端适配? 移动端开发目前主要包括三类: 原生App开发(iOS、Android、RN、uniapp...

  • iOS IM即时通讯小结:WebSocket

    参考网站 即时通讯网 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》 大牛博客IM 即时通讯技术...

  • Vue仿微信app页面跳转动画

    独立开发者在开发移动端产品时,为了更高效,通常会使用Web技术来开发移动端项目,可以同时适配Android、iOS...

  • IM

    一、开始-------新手读 新手入门一篇就够:从零开发移动端IM 移动端IM开发需要面对的技术问题 扫盲贴:浅谈...

  • 2018年计划

    移动端:Android:学会kotlinweb端: 前端学会Vue及其几个框架服务端:Laravel提高一个入门级别吧

  • Flutter 探索(一)入门前言

    移动端现状 移动应用已经十年有余,如今,原生开发 Android 可以使用 Java、Kotlin 开发,iOS ...

  • android websokect 连接

    websokect 其实就是sokect用http+xmpp二次开发出来的 这里贴一下Android客户端怎样...

网友评论

    本文标题:android移动端xmpp开发入门

    本文链接:https://www.haomeiwen.com/subject/ktgfoftx.html