基于xmpp openfire smack开发之smack类库介绍和使用[2]

简介:

关于Smack编程库,前面我们提到,它是面向Java端的api,主要在PC上使用,利用它我们可以向openfire服务器注册用户,发送消息,并且可以通过监听器获得此用户的应答消息,以及构建聊天室,分组,个人通讯录等等。

下面我们写几个程序小例子测试一下。

(1)登录操作

[java]  view plain copy
  1. PPConnection.DEBUG_ENABLED = true;  
  2. AccountManager accountManager;  
  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  
  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  
  5.   
  6. // 允许自动连接  
  7. connectionConfig.setReconnectionAllowed(true);  
  8. connectionConfig.setSendPresence(true);  
  9.   
  10. Connection connection = new XMPPConnection(connectionConfig);  
  11. try {  
  12.     connection.connect();// 开启连接  
  13.     accountManager = connection.getAccountManager();// 获取账户管理类  
  14. catch (XMPPException e) {  
  15.     throw new IllegalStateException(e);  
  16. }  
  17.   
  18. // 登录  
  19. connection.login("admin""admin","SmackTest");  
  20. System.out.println(connection.getUser());   
  21. connection.getChatManager().createChat("shimiso@csdn.shimiso.com",null).sendMessage("Hello word!");  

运行结果:

在login中一共有三个参数,登录名,密码,资源名,可能有人不明白资源名到底是什么意思,其实就是客户端的来源,客户端的名称,如果不写它默认就叫smack,如果你用相同的账户不同的资源名和同一个人发三条消息,那将会弹出三个窗口,而不是一个窗口。
同时smack还为我们提供了非常好的调试工具Smack Debug,利用该工具我们可以准确的捕获详细的往返报文信息。

(2)下面我们继续写个聊天的例子:

[java]  view plain copy
  1. PPConnection.DEBUG_ENABLED = true;  
  2. AccountManager accountManager;  
  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  
  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  
  5.   
  6. // 允许自动连接  
  7. connectionConfig.setReconnectionAllowed(true);  
  8. connectionConfig.setSendPresence(true);  
  9.   
  10. Connection connection = new XMPPConnection(connectionConfig);  
  11. try {  
  12.     connection.connect();// 开启连接  
  13.     accountManager = connection.getAccountManager();// 获取账户管理类  
  14. catch (XMPPException e) {  
  15.     throw new IllegalStateException(e);  
  16. }  
  17.   
  18. // 登录  
  19. connection.login("admin""admin","SmackTest3");    
  20. ChatManager chatmanager = connection.getChatManager();  
  21. Chat newChat = chatmanager.createChat("shimiso@csdn.shimiso.com"new MessageListener() {  
  22.     public void processMessage(Chat chat, Message message) {  
  23.         if (message.getBody() != null) {  
  24.             System.out.println("Received from 【"  
  25.                     + message.getFrom() + "】 message: "  
  26.                     + message.getBody());  
  27.         }  
  28.   
  29.     }  
  30. });  
  31. Scanner input = new Scanner(System.in);  
  32. while (true) {  
  33.     String message = input.nextLine();   
  34.     newChat.sendMessage(message);  
  35. }  

运行结果:

这里我们用Scanner来捕捉用户在控制台的键盘操作,将信息发出,同时创建了一个MessageListener监听,在其中强制实现processMessage方法即可捕获发回的信息,在初次使用上还是较为容易上手的,我们只要细心查看API即可逐步深入下去。

(3)除了聊天以外我们经常还能想到就是广播

需要给所有在线的用户发送一个通知,或者给所有在线和离线的用户全发送,我们先演示如何给在线用户发送一个广播:

[java]  view plain copy
  1. PPConnection.DEBUG_ENABLED = false;  
  2. AccountManager accountManager;  
  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  
  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  
  5.   
  6. // 允许自动连接  
  7. connectionConfig.setReconnectionAllowed(true);  
  8. connectionConfig.setSendPresence(true);  
  9.   
  10. Connection connection = new XMPPConnection(connectionConfig);  
  11. try {  
  12.     connection.connect();// 开启连接  
  13.     accountManager = connection.getAccountManager();// 获取账户管理类  
  14. catch (XMPPException e) {  
  15.     throw new IllegalStateException(e);  
  16. }  
  17. connection.login("admin""admin","SmackTest3");   
  18. Message newmsg = new Message();   
  19. newmsg.setTo("shimiso@csdn.shimiso.com");  
  20. newmsg.setSubject("重要通知");  
  21. newmsg.setBody("今天下午2点60分有会!");  
  22. newmsg.setType(Message.Type.headline);// normal支持离线   
  23. connection.sendPacket(newmsg);  
  24. connection.disconnect();  

运行结果:

将参数设置为Message.Type.normal即可支持离线广播,openfire系统会自动判断该用户是否在线,如果在线就直接发送出去,如果不在线则将信息存入ofoffline表,现在我将shimiso用户退出登录,再给它发消息,我们可以进入openfire库的ofoffline表中,非常清楚看到里面躺着一条离线消息记录是发给shimiso这个用户的

(4)那么我们如何让shimiso这个用户一登陆就取到离线消息呢?

请看如下代码

[java]  view plain copy
  1. PPConnection.DEBUG_ENABLED = false;  
  2. AccountManager accountManager;  
  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  
  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  
  5.   
  6. // 允许自动连接  
  7. connectionConfig.setReconnectionAllowed(true);  
  8. connectionConfig.setSendPresence(false);//不要告诉服务器自己的状态  
  9. Connection connection = new XMPPConnection(connectionConfig);  
  10. try {  
  11.     connection.connect();// 开启连接  
  12.     accountManager = connection.getAccountManager();// 获取账户管理类  
  13. catch (XMPPException e) {  
  14.     throw new IllegalStateException(e);  
  15. }   
  16. connection.login("shimiso""123","SmackTest");   
  17. OfflineMessageManager offlineManager = new OfflineMessageManager(  
  18.         connection);  
  19. try {  
  20.     Iterator<org.jivesoftware.smack.packet.Message> it = offlineManager  
  21.             .getMessages();  
  22.   
  23.     System.out.println(offlineManager.supportsFlexibleRetrieval());  
  24.     System.out.println("离线消息数量: " + offlineManager.getMessageCount());  
  25.   
  26.     Map<String, ArrayList<Message>> offlineMsgs = new HashMap<String, ArrayList<Message>>();  
  27.   
  28.     while (it.hasNext()) {  
  29.         org.jivesoftware.smack.packet.Message message = it.next();  
  30.         System.out  
  31.                 .println("收到离线消息, Received from 【" + message.getFrom()  
  32.                         + "】 message: " + message.getBody());  
  33.         String fromUser = message.getFrom().split("/")[0];  
  34.   
  35.         if (offlineMsgs.containsKey(fromUser)) {  
  36.             offlineMsgs.get(fromUser).add(message);  
  37.         } else {  
  38.             ArrayList<Message> temp = new ArrayList<Message>();  
  39.             temp.add(message);  
  40.             offlineMsgs.put(fromUser, temp);  
  41.         }  
  42.     }  
  43.   
  44.     // 在这里进行处理离线消息集合......  
  45.     Set<String> keys = offlineMsgs.keySet();  
  46.     Iterator<String> offIt = keys.iterator();  
  47.     while (offIt.hasNext()) {  
  48.         String key = offIt.next();  
  49.         ArrayList<Message> ms = offlineMsgs.get(key);  
  50.   
  51.         for (int i = 0; i < ms.size(); i++) {  
  52.             System.out.println("-->" + ms.get(i));  
  53.         }  
  54.     }  
  55.   
  56.     offlineManager.deleteMessages();  
  57. catch (Exception e) {  
  58.     e.printStackTrace();  
  59. }  
  60. offlineManager.deleteMessages();//删除所有离线消息  
  61. Presence presence = new Presence(Presence.Type.available);  
  62.             nnection.sendPacket(presence);//上线了  
  63.             nnection.disconnect();//关闭连接  

运行结果:

这里我们需要特别当心的是先不要告诉openfire服务器你上线了,否则永远也拿不到离线消息,用下面英文大概意思就是在你上线之前去获取离线消息,这么设计是很有道理的。

The OfflineMessageManager helps manage offline messages even before the user has sent an available presence. When a user asks for his offline messages before sending an available presence then the server will not send a flood with all the offline messages when the user becomes online. The server will not send a flood with all the offline messages to the session that made the offline messages request or to any other session used by the user that becomes online.

拿到离线消息处理完毕之后删除离线消息offlineManager.deleteMessages() 接着通知服务器上线了。

(5)下面我们来看看如何来发送文件

[java]  view plain copy
  1. PPConnection.DEBUG_ENABLED = false;  
  2. AccountManager accountManager;  
  3. final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(  
  4.         "192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");  
  5.   
  6. // 允许自动连接  
  7. connectionConfig.setReconnectionAllowed(true);  
  8. connectionConfig.setSendPresence(true);  
  9.   
  10. Connection connection = new XMPPConnection(connectionConfig);  
  11. try {  
  12.     connection.connect();// 开启连接  
  13.     accountManager = connection.getAccountManager();// 获取账户管理类  
  14. catch (XMPPException e) {  
  15.     throw new IllegalStateException(e);  
  16. }  
  17.   connection.login("admin""admin","Rooyee");   
  18.   Presence pre = connection.getRoster().getPresence("shimiso@csdn.shimiso.com");  
  19.     System.out.println(pre);  
  20.     if (pre.getType() != Presence.Type.unavailable) {  
  21.         // 创建文件传输管理器  
  22.         FileTransferManager manager = new FileTransferManager(connection);  
  23.         // 创建输出的文件传输  
  24.         OutgoingFileTransfer transfer = manager  
  25.                 .createOutgoingFileTransfer(pre.getFrom());  
  26.         // 发送文件  
  27.         transfer.sendFile(new File("E:\\Chrysanthemum.jpg"), "图片");  
  28.         while (!transfer.isDone()) {  
  29.             if (transfer.getStatus() == FileTransfer.Status.in_progress) {  
  30.                 // 可以调用transfer.getProgress();获得传输的进度   
  31.                 System.out.println(transfer.getStatus());  
  32.                 System.out.println(transfer.getProgress());  
  33.                 System.out.println(transfer.isDone());  
  34.             }  
  35.         }  
  36.     }  

运行结果:

在这里我们需要特别注意的是,跨资源是无法发送文件的,看connection.login("admin", "admin","Rooyee");这个代码就明白了,必须是“域名和资源名”完全相同的两个用户才可以互发文件,否则永远都没反应,如果不清楚自己所用的客户端的资源名,可以借助前面提到的SmackDebug工具查看往返信息完整报文,在to和from中一定可以看到。

如果我们自己要写文件接收例子的话,参考代码如下:

[java]  view plain copy
  1. FileTransferManager transfer = new FileTransferManager(connection);  
  2. transfer.addFileTransferListener(new RecFileTransferListener());  
  3. public class RecFileTransferListener implements FileTransferListener {  
  4.   
  5.     public String getFileType(String fileFullName) {  
  6.         if (fileFullName.contains(".")) {  
  7.             return "." + fileFullName.split("//.")[1];  
  8.         } else {  
  9.             return fileFullName;  
  10.         }  
  11.   
  12.     }  
  13.   
  14.     @Override  
  15.     public void fileTransferRequest(FileTransferRequest request) {  
  16.         System.out.println("接收文件开始.....");  
  17.         final IncomingFileTransfer inTransfer = request.accept();  
  18.         final String fileName = request.getFileName();  
  19.         long length = request.getFileSize();  
  20.         final String fromUser = request.getRequestor().split("/")[0];  
  21.         System.out.println("文件大小:" + length + "  " + request.getRequestor());  
  22.         System.out.println("" + request.getMimeType());  
  23.         try {  
  24.   
  25.             JFileChooser chooser = new JFileChooser();  
  26.             chooser.setCurrentDirectory(new File("."));  
  27.   
  28.             int result = chooser.showOpenDialog(null);  
  29.   
  30.             if (result == JFileChooser.APPROVE_OPTION) {  
  31.                 final File file = chooser.getSelectedFile();  
  32.                 System.out.println(file.getAbsolutePath());  
  33.                 new Thread() {  
  34.                     public void run() {  
  35.                         try {  
  36.   
  37.                             System.out.println("接受文件: " + fileName);  
  38.                             inTransfer  
  39.                                     .recieveFile(new File(file  
  40.                                             .getAbsolutePath()  
  41.                                             + getFileType(fileName)));  
  42.   
  43.                             Message message = new Message();  
  44.                             message.setFrom(fromUser);  
  45.                             message.setProperty("REC_SIGN""SUCCESS");  
  46.                             message.setBody("[" + fromUser + "]发送文件: "  
  47.                                     + fileName + "/r/n" + "存储位置: "  
  48.                                     + file.getAbsolutePath()  
  49.                                     + getFileType(fileName));  
  50.                             if (Client.isChatExist(fromUser)) {  
  51.                                 Client.getChatRoom(fromUser)  
  52.                                         .messageReceiveHandler(message);  
  53.                             } else {  
  54.                                 ChatFrameThread cft = new ChatFrameThread(  
  55.                                         fromUser, message);  
  56.                                 cft.start();  
  57.   
  58.                             }  
  59.                         } catch (Exception e2) {  
  60.                             e2.printStackTrace();  
  61.                         }  
  62.                     }  
  63.                 }.start();  
  64.             } else {  
  65.   
  66.                 System.out.println("拒绝接受文件: " + fileName);  
  67.   
  68.                 request.reject();  
  69.                 Message message = new Message();  
  70.                 message.setFrom(fromUser);  
  71.                 message.setBody("拒绝" + fromUser + "发送文件: " + fileName);  
  72.                 message.setProperty("REC_SIGN""REJECT");  
  73.                 if (Client.isChatExist(fromUser)) {  
  74.                     Client.getChatRoom(fromUser).messageReceiveHandler(message);  
  75.                 } else {  
  76.                     ChatFrameThread cft = new ChatFrameThread(fromUser, message);  
  77.                     cft.start();  
  78.                 }  
  79.             }  
  80.   
  81.             /* 
  82.              * InputStream in = inTransfer.recieveFile(); 
  83.              *  
  84.              * String fileName = "r"+inTransfer.getFileName(); 
  85.              *  
  86.              * OutputStream out = new FileOutputStream(new 
  87.              * File("d:/receive/"+fileName)); byte[] b = new byte[512]; 
  88.              * while(in.read(b) != -1) { out.write(b); out.flush(); } 
  89.              *  
  90.              * in.close(); out.close(); 
  91.              */  
  92.         } catch (Exception e) {  
  93.             e.printStackTrace();  
  94.         }  
  95.   
  96.         System.out.println("接收文件结束.....");  
  97.   
  98.     }  
  99.   
  100. }  

(6)用户列表

[java]  view plain copy
  1. **  
  2.  * 返回所有组信息 <RosterGroup>  
  3.  *   
  4.  * @return List(RosterGroup)  
  5.  */  
  6. public static List<RosterGroup> getGroups(Roster roster) {  
  7.     List<RosterGroup> groupsList = new ArrayList<RosterGroup>();  
  8.     Collection<RosterGroup> rosterGroup = roster.getGroups();  
  9.     Iterator<RosterGroup> i = rosterGroup.iterator();  
  10.     while (i.hasNext())  
  11.         groupsList.add(i.next());  
  12.     return groupsList;  
  13. }  
  14.   
  15. /** 
  16.  * 返回相应(groupName)组里的所有用户<RosterEntry> 
  17.  *  
  18.  * @return List(RosterEntry) 
  19.  */  
  20. public static List<RosterEntry> getEntriesByGroup(Roster roster,  
  21.         String groupName) {  
  22.     List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();  
  23.     RosterGroup rosterGroup = roster.getGroup(groupName);  
  24.     Collection<RosterEntry> rosterEntry = rosterGroup.getEntries();  
  25.     Iterator<RosterEntry> i = rosterEntry.iterator();  
  26.     while (i.hasNext())  
  27.         EntriesList.add(i.next());  
  28.     return EntriesList;  
  29. }  
  30.   
  31. /** 
  32.  * 返回所有用户信息 <RosterEntry> 
  33.  *  
  34.  * @return List(RosterEntry) 
  35.  */  
  36. public static List<RosterEntry> getAllEntries(Roster roster) {  
  37.     List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();  
  38.     Collection<RosterEntry> rosterEntry = roster.getEntries();  
  39.     Iterator<RosterEntry> i = rosterEntry.iterator();  
  40.     while (i.hasNext())  
  41.         EntriesList.add(i.next());  
  42.     return EntriesList;  
  43. }  

(7)用户头像的获取

使用VCard,很强大,具体自己看API吧,可以看看VCard传回来XML的组成,含有很多信息的

[java]  view plain copy
  1. **  
  2.  * 获取用户的vcard信息  
  3.  * @param connection  
  4.  * @param user  
  5.  * @return  
  6.  * @throws XMPPException  
  7.  */  
  8. public static VCard getUserVCard(XMPPConnection connection, String user) throws XMPPException  
  9. {  
  10.     VCard vcard = new VCard();  
  11.     vcard.load(connection, user);  
  12.       
  13.     return vcard;  
  14. }  
  15.   
  16. /** 
  17.  * 获取用户头像信息 
  18.  */  
  19. public static ImageIcon getUserImage(XMPPConnection connection, String user) {  
  20.     ImageIcon ic = null;  
  21.     try {  
  22.         System.out.println("获取用户头像信息: "+user);  
  23.         VCard vcard = new VCard();  
  24.         vcard.load(connection, user);  
  25.           
  26.         if(vcard == null || vcard.getAvatar() == null)  
  27.         {  
  28.             return null;  
  29.         }  
  30.         ByteArrayInputStream bais = new ByteArrayInputStream(  
  31.                 vcard.getAvatar());  
  32.         Image image = ImageIO.read(bais);  
  33.   
  34.           
  35.         ic = new ImageIcon(image);  
  36.         System.out.println("图片大小:"+ic.getIconHeight()+" "+ic.getIconWidth());  
  37.       
  38.     } catch (Exception e) {  
  39.         e.printStackTrace();  
  40.     }  
  41.     return ic;  
  42. }  

(8)组操作和用户分组操作

[java]  view plain copy
  1. **  
  2.  * 添加一个组  
  3.  */  
  4. public static boolean addGroup(Roster roster,String groupName)  
  5. {  
  6.     try {  
  7.         roster.createGroup(groupName);  
  8.         return true;  
  9.     } catch (Exception e) {  
  10.         e.printStackTrace();  
  11.         return false;  
  12.     }  
  13. }  
  14.   
  15. /** 
  16.  * 删除一个组 
  17.  */  
  18. public static boolean removeGroup(Roster roster,String groupName)  
  19. {  
  20.     return false;  
  21. }  
  22.   
  23. /** 
  24.  * 添加一个好友  无分组 
  25.  */  
  26. public static boolean addUser(Roster roster,String userName,String name)  
  27. {  
  28.     try {  
  29.         roster.createEntry(userName, name, null);  
  30.         return true;  
  31.     } catch (Exception e) {  
  32.         e.printStackTrace();  
  33.         return false;  
  34.     }  
  35. }  
  36. /** 
  37.  * 添加一个好友到分组 
  38.  * @param roster 
  39.  * @param userName 
  40.  * @param name 
  41.  * @return 
  42.  */  
  43. public static boolean addUser(Roster roster,String userName,String name,String groupName)  
  44. {  
  45.     try {  
  46.         roster.createEntry(userName, name,new String[]{ groupName});  
  47.         return true;  
  48.     } catch (Exception e) {  
  49.         e.printStackTrace();  
  50.         return false;  
  51.     }  
  52. }  
  53.   
  54. /** 
  55.  * 删除一个好友 
  56.  * @param roster 
  57.  * @param userName 
  58.  * @return 
  59.  */  
  60. public static boolean removeUser(Roster roster,String userName)  
  61. {  
  62.     try {  
  63.           
  64.         if(userName.contains("@"))  
  65.         {  
  66.             userName = userName.split("@")[0];  
  67.         }  
  68.         RosterEntry entry = roster.getEntry(userName);  
  69.         System.out.println("删除好友:"+userName);  
  70.         System.out.println("User: "+(roster.getEntry(userName) == null));  
  71.         roster.removeEntry(entry);  
  72.           
  73.         return true;  
  74.     } catch (Exception e) {  
  75.         e.printStackTrace();  
  76.         return false;  
  77.     }  
  78.       
  79. }  

(9)用户查询

[java]  view plain copy
  1. public static List<UserBean> searchUsers(XMPPConnection connection,String serverDomain,String userName) throws XMPPException  
  2.     {  
  3.         List<UserBean> results = new ArrayList<UserBean>();  
  4.         System.out.println("查询开始..............."+connection.getHost()+connection.getServiceName());  
  5.           
  6.         UserSearchManager usm = new UserSearchManager(connection);  
  7.           
  8.           
  9.         Form searchForm = usm.getSearchForm(serverDomain);  
  10.         Form answerForm = searchForm.createAnswerForm();  
  11.         answerForm.setAnswer("Username"true);  
  12.         answerForm.setAnswer("search", userName);  
  13.         ReportedData data = usm.getSearchResults(answerForm, serverDomain);  
  14.            
  15.          Iterator<Row> it = data.getRows();  
  16.          Row row = null;  
  17.          UserBean user = null;  
  18.          while(it.hasNext())  
  19.          {  
  20.              user = new UserBean();  
  21.              row = it.next();  
  22.              user.setUserName(row.getValues("Username").next().toString());  
  23.              user.setName(row.getValues("Name").next().toString());  
  24.              user.setEmail(row.getValues("Email").next().toString());  
  25.              System.out.println(row.getValues("Username").next());  
  26.              System.out.println(row.getValues("Name").next());  
  27.              System.out.println(row.getValues("Email").next());  
  28.              results.add(user);  
  29.              //若存在,则有返回,UserName一定非空,其他两个若是有设,一定非空  
  30.          }  
  31.            
  32.          return results;  
  33.     }  

(10)修改自身状态

包括上线,隐身,对某人隐身,对某人上线

[java]  view plain copy
  1. ublic static void updateStateToAvailable(XMPPConnection connection)  
  2. {  
  3.     Presence presence = new Presence(Presence.Type.available);  
  4.             nnection.sendPacket(presence);  
  5.           
  6.   
  7. public static void updateStateToUnAvailable(XMPPConnection connection)  
  8. {  
  9.     Presence presence = new Presence(Presence.Type.unavailable);  
  10.             nnection.sendPacket(presence);  
  11.     }  
  12.   
  13. public static void updateStateToUnAvailableToSomeone(XMPPConnection connection,String userName)  
  14. {  
  15.     Presence presence = new Presence(Presence.Type.unavailable);  
  16.     presence.setTo(userName);  
  17.             nnection.sendPacket(presence);  
  18. }  
  19. public static void updateStateToAvailableToSomeone(XMPPConnection connection,String userName)  
  20. {  
  21.     Presence presence = new Presence(Presence.Type.available);  
  22.     presence.setTo(userName);  
  23.             nnection.sendPacket(presence);  
  24.   
  25. }  

(11)心情修改

[java]  view plain copy
  1. **  
  2.  * 修改心情  
  3.  * @param connection  
  4.  * @param status  
  5.  */  
  6. public static void changeStateMessage(XMPPConnection connection,String status)  
  7. {  
  8.     Presence presence = new Presence(Presence.Type.available);  
  9.     presence.setStatus(status);  
  10.     connection.sendPacket(presence);  
  11.   
  12. }  

(12)修改用户头像

有点麻烦,主要是读入图片文件,编码,传输之

[java]  view plain copy
  1. public static void changeImage(XMPPConnection connection,File f) throws XMPPException, IOException{  
  2.       
  3.         VCard vcard = new VCard();  
  4.         vcard.load(connection);  
  5.           
  6.             byte[] bytes;  
  7.             
  8.                 bytes = getFileBytes(f);  
  9.                 String encodedImage = StringUtils.encodeBase64(bytes);  
  10.                 vcard.setAvatar(bytes, encodedImage);  
  11.                 vcard.setEncodedImage(encodedImage);  
  12.                 vcard.setField("PHOTO""<TYPE>image/jpg</TYPE><BINVAL>"  
  13.                         + encodedImage + "</BINVAL>"true);  
  14.                   
  15.                   
  16.                 ByteArrayInputStream bais = new ByteArrayInputStream(  
  17.                         vcard.getAvatar());  
  18.                 Image image = ImageIO.read(bais);  
  19.                 ImageIcon ic = new ImageIcon(image);  
  20.                    
  21.              
  22.             
  23.             vcard.save(connection);  
  24.              
  25.     }  
  26.       
  27.       private static byte[] getFileBytes(File file) throws IOException {  
  28.                 BufferedInputStream bis = null;  
  29.             try {  
  30.             bis = new BufferedInputStream(new FileInputStream(file));  
  31.             int bytes = (int) file.length();  
  32.             byte[] buffer = new byte[bytes];  
  33.             int readBytes = bis.read(buffer);  
  34.             if (readBytes != buffer.length) {  
  35.                 throw new IOException("Entire file not read");  
  36.             }  
  37.             return buffer;  
  38.         } finally {  
  39.             if (bis != null) {  
  40.                 bis.close();  
  41.             }  
  42.         }  
  43. }  

(13)用户状态的监听

即对方改变头像,状态,心情时,更新自己用户列表,其实这里已经有smack实现的监听器

[java]  view plain copy
  1. nal Roster roster = Client.getRoster();  
  2.   
  3. roster.addRosterListener(  
  4.     new RosterListener() {  
  5.   
  6.             @Override  
  7.             public void entriesAdded(Collection<String> arg0) {  
  8.                 // TODO Auto-generated method stub  
  9.                 System.out.println("--------EE:"+"entriesAdded");  
  10.             }  
  11.   
  12.             @Override  
  13.             public void entriesDeleted(Collection<String> arg0) {  
  14.                 // TODO Auto-generated method stub  
  15.                 System.out.println("--------EE:"+"entriesDeleted");  
  16.             }  
  17.   
  18.             @Override  
  19.             public void entriesUpdated(Collection<String> arg0) {  
  20.                 // TODO Auto-generated method stub  
  21.                 System.out.println("--------EE:"+"entriesUpdated");  
  22.             }  
  23.   
  24.             @Override  
  25.             public void presenceChanged(Presence arg0) {  
  26.                 // TODO Auto-generated method stub  
  27.                 System.out.println("--------EE:"+"presenceChanged");  
  28.             }     
  29.               
  30. });  

 

 

 

SmackTest例子下载

相关文章
|
XML Java 数据格式
openfire 插件开发
插件分类 消息等内部插件 这类插件主要用于对 openfire 内消息,状态等扩展 webUI 插件 这类插件主要用于对 openfire 控制台扩展 web接口插件 这类插件主要用于对 openfire 后台接口扩展 插件开发基本流程 实现 Plugin 类 添加 plugin.
1507 0
|
Java 测试技术 网络架构
神器:REST测试工具[wiztools.org restclient]客户端Jar依赖Java安装环境
背景 使用Spring Boot开发集群应用,架构风格启用RestFul之后表单Post请求无法Url测试,必须使用专用工具测试 主题 经过亲身感受,测试发现最靠谱的工具非[wiztools.org restclient]莫属 特色 支持本地测试,不依赖任何第三发 支持所有报头,任意切换 Java编写,跨平台运行 内容 1、输入完整的服务地址,例如“http://172.16.90.64:8080/bindCard” 2、Method选择Post 3、Body选择Sting Body,选择json格式,高亮区域输入测试的Json串。
1268 0
|
关系型数据库 MySQL Java
iOS - XMPP Openfire 服务器的搭建
前言 提前下载好相关软件,且安装目录最好安装在全英文路径下。如果路径有中文名,那么可能会出现一些莫名其妙的问题。 提前准备好的软件: jdk-8u91-macosx-x64.dmg mysql-5.7.17-macos10.12-x86_64.dmg mysql-workbench-community-6.3.9-osx-x86_64.dmg openfire_4_1_1.dmg Openfire 官网 MySQL 官网 JDK 官网 在安装配置 Openfire 或其他 xmpp 服务器前,需要先安装 MySQL 数据库。
2397 0
XMPP客户端库Smack
原文博客地址:http://blog.csdn.net/chszs/article/details/41576877
832 0
|
网络协议 API
Smack 4.1.x升级指南
版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/48576553 Smack 4.1.x升级指南 作者:chszs,版权所有,未经同意,不得转载。
1021 0
|
数据安全/隐私保护 iOS开发 分布式计算
|
关系型数据库 MySQL 数据库
XMPP(一)-openfire服务端的安装和搭建
XMPP全称:可扩展通讯和表示协议 简介:可扩展通讯和表示协议 (XMPP) 可用于服务类实时通讯、表示和需求响应服务中的XML数据元流式传输。XMPP以Jabber协议为基础,而Jabber是即时通讯中常用的开放式协议。XMPP is the IETF's formalization of the base XML streaming protocols for inst
1584 0