smark和openfire即时通信代码

it2025-08-18  10

从:http://blog.csdn.net/casuallc/article/details/34794501

server:openfire

client计划:smark写

首先安装openfire,下载client直接安装就可以。数据库能够用openfire自身的,也能够用自己的数据库,仅仅要按提示设置好參数就可以

之后,就能够用smark写一个client測试与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。则不会去验证server证书是否有效,默觉得enabled      config.setSecurityMode(SecurityMode.disabled);      //设置能够调试。默觉得false,老版本号的写法为XMPPConnection.DEBUG_ENABLED = true;      config.setDebuggerEnabled(true);      //设置是否在登陆的时候告诉server,默觉得true      config.setSendPresence(false);      //XMPPConnection在后来的版本号中改成了抽象类      XMPPConnection conn = new XMPPTCPConnection(config);      //设置等待时间      conn.setPacketReplyTimeout(5000);      conn.connect();      //username,password,资源名(比如:假设是用潘迪安发送的消息。则资源名就是:  潘迪安,用于标识client)      conn.login("admin""0""资源名");   关于连接的參数,在新版本号中所有在config中设置

发送消息

[html] view plain copy private void testSendMessage(XMPPConnection conn) throws Exception {          //jid在数据表中ofroster能够查到。通常是   username@server名称          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 删除好友(即拒绝加入好友)。                               备注:对方发出加入好友的请求后。在server端会自己主动把对方加入到自己的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这样server就没办法推断是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""汇宝大厦");      //改动完要保存改动的内容,否则没办法更新到server      vCard.save(conn);      //改动自身的状态,包含隐身,上线(能够指定对特定的好友更改状态)      Presence p = new Presence(Type.available);      p.setTo("ly@192.168.1.100");      //改动心情      p.setStatus("我的心情");      //相同要发到server      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) {                  //该方法以及以下的方法都是在server改动好友信息时触发                  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);          //过滤器,用来过滤由server返回的信息(即得到注冊信息的内容)          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("server没有返回不论什么信息");          } 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;              }          }      }  

管理账号password

[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.cnblogs.com/bhlsheji/p/4592972.html

相关资源:java开源包10
最新回复(0)