利用openfire和smark的即时通信

xiaoxiao2021-02-28  143

利用openfire和smark的即时通信

  3240人阅读  评论(5)  收藏  举报   分类: Android(3) 

服务器:openfire

客户端程序:smark编写

首先安装openfire,下载客户端后直接安装即可,数据库可以用openfire自身的,也可以用自己的数据库,只要按提示设置好参数即可

之后,就可以用smark写一个客户端测试与openfire的通信了(需要引进的jar包除了smark自身的,还要引入xmlpull-1.1.3.1.jar、kxml2-2.3.0.jar两个包

    ,作用是解析xml文件)

备注:我用的smark版本是4.0,要引入的基本包有smack-core-4.0.0.jar、smack-debug-4.0.0.jar、smack-extensions-4.0.0.jar、smack-tcp-4.0.0.jar

debug包使用来调试的,tcp是用来初始化连接的、extension包里面含有发送离线消息、文件等类

下面是创建一个连接

[java]  view plain  copy ConnectionConfiguration config = new ConnectionConfiguration("ip"5222);       //设置成disabled,则不会去验证服务器证书是否有效,默认为enabled       config.setSecurityMode(SecurityMode.disabled);       //设置可以调试,默认为false,老版本的写法为XMPPConnection.DEBUG_ENABLED = true;       config.setDebuggerEnabled(true);       //设置是否在登陆的时候告诉服务器,默认为true       config.setSendPresence(false);       //XMPPConnection在后来的版本中改成了抽象类       XMPPConnection conn = new XMPPTCPConnection(config);       //设置等待时间       conn.setPacketReplyTimeout(5000);       conn.connect();       //用户名,密码,资源名(例如:如果是用潘迪安发送的消息,则资源名就是:  潘迪安,用于标识客户端)       conn.login("admin""0""资源名");   关于连接的参数,在新版本中全部在config中设置

发送消息

[html]  view plain  copy private void testSendMessage(XMPPConnection conn) throws Exception {           //jid在数据表中ofroster可以查到,一般是   用户名@服务器名称           Chat chat = ChatManager.getInstanceFor(conn).createChat("ly@192.168.1.100", new MessageListener() {               @Override               public void processMessage(Chat chat, Message message) {                   System.out.println("Received message: " + message);               }           });           Message msg = new Message();           msg.setBody("hello world");           //定义成normal,在对象不在线时发送离线消息,消息存放在数据表ofoffline中           msg.setType(Message.Type.normal);           //发送消息,参数可以是字符串,也可以是message对象           chat.sendMessage(msg);           //发送广播           conn.sendPacket(msg);       }   发送离线消息

[java]  view plain  copy private void testOffLine(XMPPConnection conn) throws Exception {       //离线文件       OfflineMessageManager offMM = new OfflineMessageManager(conn);       System.out.println("离线文件数量 :" + offMM.getMessageCount());       System.out.println("离线文件内容 :");       //经测试,当调用getMessages时,会触发chat设置的监听器,从而输出离线消息内容,但是getMessages方法返回的离线消息为空       //猜测回调函数的触发条件是一个变量,方变量改变时(while(flag)),执行回调函数       List<Message> listMessage = offMM.getMessages();       //listMessage的大小为0       System.out.println(listMessage.size());       for(Message m : offMM.getMessages()) {           System.out.println(" 离线  : " + m.getBody() + m.getBodies());       }   }   得到好友列表

[java]  view plain  copy private void testGetRoster(XMPPConnection conn) throws Exception {       //得到该user的roster(相当于好友列表),不区分是否在线       Roster r = conn.getRoster();       Collection<RosterEntry> c = r.getEntries();       for(RosterEntry re : c) {           StringBuilder sb = new StringBuilder();           sb.append("name : ").append(re.getName());           sb.append("\nuser : ").append(re.getUser());           sb.append("\ntype : ").append(re.getType());           sb.append("\nstatus : ").append(re.getStatus());           System.out.println(sb.toString());           System.out.println("-----------------------------");       }       System.out.println(r.getEntries());       //输出内容       /*  name : null          user : ly@192.168.1.100          type : from          status : null          -----------------------------          name : null          user : yy@192.168.1.100          type : to          status : null          -----------------------------          [ly@192.168.1.100, yy@192.168.1.100]       */   }   管理好友,监听好友请求

[java]  view plain  copy <pre name="code" class="java">   [java]  view plain  copy </pre><pre name="code" class="java">private void testAddAndDelFriends(final XMPPConnection conn) throws Exception {           Roster r = conn.getRoster();           // 用户的jid,昵称,用户的分组。如果该用户不存在也可以添加       //  r.createEntry("yy@192.168.1.100", "yy", null);           // rosterEntry的构造方法是包访问权限,不能直接new       //  RosterEntry entry = r.getEntry("ly@192.168.1.100");           // r.removeEntry(entry);                      //监听所有的请求,之后可以过滤掉不想要的请求           PacketListener packetListener = new PacketListener() {                              @Override               public void processPacket(Packet packet) throws NotConnectedException {                   /*                  available                    unavailable                   subscribe  发出添加好友的请求                  subscribed 同意添加好友                  unsubscribe 发出删除好友请求                  unsubscribed 删除好友(即拒绝添加好友),                                备注:对方发出添加好友的请求后,在服务器端会自动把对方加入到自己的roster,所以在执行处理好友请求或添加删除好友的时候,要重新获取roster,更新好友列表                  */                   Presence presence = (Presence) packet;                   Type type = presence.getType();                   //请求添加好友                   if(Type.subscribe.equals(type)) {                       //注意点:要设置to(即指明要发送的对象,否则不能成功拒绝),至于from不用设置,因为在sendPacket方法中已经设置了,formMode初始化的时候为OMITTED,可以自己设置                       /*                          switch (fromMode) {                          case OMITTED:                              packet.setFrom(null);                              break;                          case USER:                              packet.setFrom(getUser());//getUser是抽象方法                              break;                       */                       //直接用传来的presence,不能自己新建一个presence(可能要验证presence是否是原来的对象,来判断是谁拒绝了谁的好友请求),否则不能成功拒绝对方添加好友                       //例:A--presence1-->B   A---presence2---C, C---presence3---A这样服务器就没办法判断是B、C中的哪一个拒绝了A的请求                       presence.setType(Type.unsubscribed);//拒绝,发送了一条presence                       //presence.setType(Type.unavailable);//发送了两条presence,一条是subscribed,一条是unavailabled,能接受对方消息,自己的状态显示隐身,再一次登录的时候显示在线                       presence.setTo(presence.getFrom());                       presence.setPacketID(presence.getPacketID());                       Roster r = conn.getRoster();                       try {                           RosterEntry entry = r.getEntry(presence.getFrom());                           if(entry != null)                               r.removeEntry(entry);                       } catch (NotLoggedInException | NoResponseException | XMPPErrorException e) {                           // TODO Auto-generated catch block                           e.printStackTrace();                       }                       conn.sendPacket(presence);                       //多方删除自己                   } else if(Type.unsubscribe.equals(type)) {                       presence.setTo(presence.getFrom());                       presence.setType(Type.unsubscribe);                       Roster r = conn.getRoster();                       try {                           r.removeEntry(r.getEntry(presence.getFrom()));                       } catch (NotLoggedInException | NoResponseException | XMPPErrorException e) {                           // TODO Auto-generated catch block                           e.printStackTrace();                       }                       conn.sendPacket(presence);                   }                }           };              //      PacketFilter packetFilter = new PacketFilter() {   //             //          //如果返回false,则不把事件交给listener处理,否则会调用packetListener中的processPacket方法   //          //方法解释true if and only if packet passes the filter.   //          @Override   //          public boolean accept(Packet packet) {   //              System.out.println("2" + packet);   //              return true;   //          }   //      };                       //过滤掉所有的不是好友请求、删除的所有packet           PacketFilter packetFilter = new AndFilter(new PacketTypeFilter(Presence.class));                      conn.addPacketListener(packetListener, packetFilter);                                 //未知           RosterExchangeManager rem = new RosterExchangeManager(conn);           rem.addRosterListener(new RosterExchangeListener() {                  @Override               public void entriesReceived(String from, Iterator<RemoteRosterEntry> remoteRosterEntries) {                   System.out.println(from);                   while(remoteRosterEntries.hasNext()) {                       RemoteRosterEntry entry = remoteRosterEntries.next();                       System.out.println(entry.getUser() + " : " + entry.getName());                   }               }                          });       }   得到好友的信息,主要是VCard类的使用

[java]  view plain  copy private void testGetFriendInfo(XMPPConnection conn) throws Exception {           VCard vCard = new VCard();           VCardManager vcManager = new VCardManager();           //此处返回false           boolean b = vcManager.isSupported("ly@192.168.1.100", conn);           System.out.println(b);           vCard.load(conn, "ly@192.168.1.100");            // Load Avatar from VCard            byte[] avatarBytes = vCard.getAvatar();            //得不到头像等的信息            if(avatarBytes == null) {                return;            }                        // To create an ImageIcon for Swing applications            ImageIcon icon = new ImageIcon(avatarBytes);            System.out.println(icon.getIconWidth() + " : " + icon.getIconHeight());                        // To create just an image object from the bytes            ByteArrayInputStream bais = new ByteArrayInputStream(avatarBytes);            try {              Image image = ImageIO.read(bais);              FileOutputStream fos = new FileOutputStream("D://icon.jpg");              fos.write(avatarBytes);              fos.close();             }             catch (IOException e) {               e.printStackTrace();            }       }   设置自己的状态信息

[java]  view plain  copy private void testSetInfo(XMPPConnection conn) throws Exception {       VCard vCard = new VCard();       vCard.load(conn);       vCard.setEmailHome("admin@126.com");       vCard.setAddressFieldWork("POSTAL""汇宝大厦");       //修改完要保存修改的内容,否则没办法更新到服务器       vCard.save(conn);       //修改自身的状态,包括隐身,上线(可以指定对特定的好友更改状态)       Presence p = new Presence(Type.available);       p.setTo("ly@192.168.1.100");       //修改心情       p.setStatus("我的心情");       //同样要发到服务器       conn.sendPacket(p);   }   监听好友的状态

[java]  view plain  copy private void testSetRosterListener(XMPPConnection conn) throws Exception {           Roster r = conn.getRoster();           r.createEntry("ly@192.168.1.100""昵称"null);           r.addRosterListener(new RosterListener() {                              @Override               public void presenceChanged(Presence presence) {                   //更改状态信息时调用该方法(更改在线状态,修改心情,修改头像等)                   System.out.println("presenceChanged");               }                              @Override               public void entriesUpdated(Collection<String> addresses) {                   //该方法以及下面的方法都是在服务器修改好友信息时触发                   System.out.println("entriesUpdated");               }                              @Override               public void entriesDeleted(Collection<String> addresses) {                   // TODO Auto-generated method stub                   System.out.println("entriesDeleted");               }                              @Override               public void entriesAdded(Collection<String> addresses) {                   // TODO Auto-generated method stub                   System.out.println("entriesAdded");               }           });       }   监听好友的输入状态

[java]  view plain  copy private void testGetExtention(XMPPConnection conn) throws Exception {           Chat chat = ChatManager.getInstanceFor(conn).createChat("ly@192.168.1.100"new MessageListener() {                              @Override               public void processMessage(Chat chat, Message message) {                   //得到输入状态,分为五种:正在输入(composing),暂停输入(paused),发送(active),关闭对话框(gone)                   PacketExtension pe = message.getExtension("http://jabber.org/protocol/chatstates");                   switch (pe.getElementName()) {                   case "composing":                       System.out.println("正在输入......");                       break;                   case "paused":                       System.out.println("正在冥想......");                       break;                   case "active":                       System.out.println("对方已发送。");                       break;                   case "gone":                       System.out.println("对话框已被关闭。");                       break;                   default:                       break;                   }               }           });           Message msg = new Message();           msg.addExtension(new ChatStateExtension(ChatState.gone));           msg.setBody("hello world");           chat.sendMessage(msg);       }   加入聊天室进行多人聊天

[java]  view plain  copy private MultiUserChat multiUserChat;       private void testMutiUserChat(XMPPConnection conn) throws Exception {           MultiUserChat.addInvitationListener(conn, new InvitationListener() {                              @Override               public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password, Message message) {                   StringBuilder sb = new StringBuilder();                   sb.append("房间号  : ").append(room);                   sb.append("\n邀请者  : ").append(inviter);                   sb.append("\n理由  : ").append(reason);                   sb.append("\n密码  : ").append(password);                   sb.append("\n消息  : ").append(message);                   System.out.println(sb);                   multiUserChat = new MultiUserChat(conn, room);                   try {                       multiUserChat.join("admin", password);                   } catch (XMPPErrorException e) {                       // TODO Auto-generated catch block                       e.printStackTrace();                   } catch (SmackException e) {                       // TODO Auto-generated catch block                       e.printStackTrace();                   }                   multiUserChat.addMessageListener(new PacketListener() {                                              @Override                       public void processPacket(Packet packet) throws NotConnectedException {                           Message msg = (Message) packet;                           System.out.println(msg.getBody());                       }                   });               }           });           while(true) {               try {                   Thread.sleep(500);                   if(multiUserChat == null)                       continue;                   //关于发送消息的问题,可以直接发字符串                   //也可以发送message,但是要设定message的一些参数,否则不能发送(参数设置如下)                   //用Chat发送消息时,不用设置,原因是在Chat的sendMessage方法中已经添加了这些参数                   /*                   *  message.setTo(participant);                      message.setType(Message.Type.chat);                      message.setThread(threadID);                   */                   //但是,用MultiUserChat类中的sendMessage方法,直接调用了XMPPConnection中的sendPacket方法,没有设置Message的参数                   Message msg = new Message();                   //房间名称                   msg.setTo("a@conference.192.168.1.100");                   msg.setType(Message.Type.groupchat);                   msg.setThread(Thread.currentThread().getId() + "");                   msg.setBody("hello");                   multiUserChat.sendMessage(msg);                   break;               } catch (InterruptedException e) {                   e.printStackTrace();               } catch (NotConnectedException e) {                   e.printStackTrace();               } catch (XMPPException e) {                   e.printStackTrace();               }           }       }         

发送和接收文件

[java]  view plain  copy private void testSendFile(XMPPConnection conn) throws Exception {           // 发送文件的管理器           FileTransferManager ftm = new FileTransferManager(conn);           ftm.addFileTransferListener(new FileTransferListener() {                  @Override               public void fileTransferRequest(FileTransferRequest request) {                   System.out.println(request.getFileName());                   IncomingFileTransfer inComingFileTransfer = request.accept();                   try {                       //可以直接写到file文件中                       File file = new File("D://" + request.getFileName());                       inComingFileTransfer.recieveFile(file);                   } catch (Exception e) {                       e.printStackTrace();                   }               }           });           // 注意jid格式,下面为标准格式,如果不对则会抛出jid格式错误的异常           // (if (parseName(jid).length() <= 0 || parseServer(jid).length() <= 0|| parseResource(jid).length() <= 0) {           // return false;           OutgoingFileTransfer oft = ftm.createOutgoingFileTransfer("admin@192.168.1.100/潘迪安");           File file = new File("D://time.jpg");           oft.sendFile(file, "图片");           System.out.println(oft.isDone());       }   创建多人聊天室

[java]  view plain  copy     private void testCreateRoom(XMPPConnection conn) throws Exception {           while(true) {               if(conn != null)                   break;           }           //@之前的是会议房间名称,之后的是conference+ip(固定格式,不能改变)           MultiUserChat muc = new MultiUserChat(conn, "ly@conference.192.168.1.100");           //昵称,如果该房间已经存在,则会抛出Creation failed - Missing acknowledge of room creation.(先加入房间,然后离开房间)           muc.create("real_admin");           Form form = muc.getConfigurationForm();           Form submitForm = form.createAnswerForm();           //下面的初始化有什么用,在创建submitForm的时候已经设置参数了   //      List<FormField> list = submitForm.getFields();   //      for(FormField f : list) {   //          if(!(FormField.TYPE_HIDDEN.equals(f.getType())) && f.getVariable() != null) {   //              submitForm.setDefaultAnswer(f.getVariable());   //          }   //      }           //参数到底是什么意思,为什么有的可以设置,有的不可以设置           /*           *  variable:FORM_TYPE  type:hidden  value:[http://jabber.org/protocol/muc#roomconfig]              variable:muc#roomconfig_roomname  type:text-single  value:[]              variable:muc#roomconfig_roomdesc  type:text-single  value:[]              variable:muc#roomconfig_changesubject  type:boolean  value:[]              variable:muc#roomconfig_maxusers  type:list-single  value:[]              variable:muc#roomconfig_presencebroadcast  type:list-multi  value:[]              variable:muc#roomconfig_publicroom  type:boolean  value:[]              variable:muc#roomconfig_persistentroom  type:boolean  value:[]              variable:muc#roomconfig_moderatedroom  type:boolean  value:[]              variable:muc#roomconfig_membersonly  type:boolean  value:[]              variable:muc#roomconfig_allowinvites  type:boolean  value:[]              variable:muc#roomconfig_passwordprotectedroom  type:boolean  value:[]              variable:muc#roomconfig_roomsecret  type:text-private  value:[]              variable:muc#roomconfig_whois  type:list-single  value:[]              variable:muc#roomconfig_enablelogging  type:boolean  value:[]              variable:x-muc#roomconfig_reservednick  type:boolean  value:[]              variable:x-muc#roomconfig_canchangenick  type:boolean  value:[]              variable:x-muc#roomconfig_registration  type:boolean  value:[]              variable:muc#roomconfig_roomadmins  type:jid-multi  value:[]              variable:muc#roomconfig_roomowners  type:jid-multi  value:[]           */           //submitForm.setAnswer(FormField.TYPE_TEXT_PRIVATE, "0");           muc.sendConfigurationForm(submitForm);           //被拒绝时执行           muc.addInvitationRejectionListener(new InvitationRejectionListener() {                              @Override               public void invitationDeclined(String invitee, String reason) {                   System.out.println(invitee + " : " + reason);               }           });           muc.invite("yy@192.168.1.100""ly_room");       }   管理房间

[java]  view plain  copy <pre name="code" class="java">private void testManageRoom(XMPPConnection conn) throws Exception {           testCreateRoom(conn);           MultiUserChat muc = new MultiUserChat(conn, "ly@conference.192.168.1.100");           //Thread.sleep(5000);           //赋予管理员权限           //muc.grantAdmin("yy@192.168.1.100");                                 //Thread.sleep(5000);           //如果是管理员,则不能踢除           //muc.banUser("yy@192.168.1.100", "太水");                      //收回说话的权限           muc.revokeVoice("yy");           //muc.grantVoice("yy");       }  

注册

[java]  view plain  copy private void testRegister(XMPPConnection conn) throws Exception {           //可以直接改登陆用户的信息(如果是username的值必须和该用户的用户名相同)           Registration r = new Registration();           Map<String, String> attributes = new HashMap<String, String>();           attributes.put("username""newuser");           attributes.put("password""0");           attributes.put("email""new00@126.com");           attributes.put("name""name@192.168.1.100");           //添加用户,要设置type类型为set,原因不明           r.setType(IQ.Type.SET);           r.setAttributes(attributes);           //过滤器,用来过滤由服务器返回的信息(即得到注册信息的内容)           PacketFilter packetFilter = new AndFilter(new PacketIDFilter(r.getPacketID()), new PacketTypeFilter(IQ.class));           PacketCollector collector = conn.createPacketCollector(packetFilter);            System.out.println(r);           conn.sendPacket(r);           IQ result = (IQ) collector.nextResult();           if(result == null) {               System.out.println("服务器没有返回任何信息");           } else {           switch (result.getType().toString()) {               case "result":                   System.out.println("注册成功");                   break;               case "error":                   if(result.getError().toString().equalsIgnoreCase("conflict"))                       System.out.println("用户名称已存在");                   else                        System.out.println("注册失败");                   break;               default:                   break;               }           }       }  

管理账号密码

[java]  view plain  copy private void testModifyPwd(XMPPConnection conn) throws Exception {           //创建一个用户信息管理,可以创建新用户,或者修改用户密码           AccountManager am = AccountManager.getInstance(conn);           Collection<String> c = am.getAccountAttributes();           for(String s : c) {               System.out.println(s);           }           /*           * 通过accountManager可以得到的属性           *  username              email              registered              name              password           */           am.getAccountAttribute("username");           am.createAccount("newUser""0");           am.changePassword("00");       }  

至于细节和中间遇到的问题,在程序代码中都有叙述

参考博客:

http://blog.csdn.NET/shimiso/article/details/11225873

转载请注明原文地址: https://www.6miu.com/read-31311.html

最新回复(0)