基于xmpp openfire smack开发之smack类库介绍和使用[2]
關(guān)于Smack編程庫(kù),前面我們提到,它是面向Java端的api,主要在PC上使用,利用它我們可以向openfire服務(wù)器注冊(cè)用戶,發(fā)送消息,并且可以通過(guò)監(jiān)聽(tīng)器獲得此用戶的應(yīng)答消息,以及構(gòu)建聊天室,分組,個(gè)人通訊錄等等。
下面我們寫(xiě)幾個(gè)程序小例子測(cè)試一下。
(1)登錄操作
?? ??? ??? ?PPConnection.DEBUG_ENABLED = true;
?? ??? ??? ?AccountManager accountManager;
?? ??? ??? ?final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
?? ??? ??? ??? ??? ?"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");
??? ?
?? ??? ??? ?// 允許自動(dòng)連接
?? ??? ??? ?connectionConfig.setReconnectionAllowed(true);
?? ??? ??? ?connectionConfig.setSendPresence(true);
??? ?
?? ??? ??? ?Connection connection = new XMPPConnection(connectionConfig);
?? ??? ??? ?try {
?? ??? ??? ??? ?connection.connect();// 開(kāi)啟連接
?? ??? ??? ??? ?accountManager = connection.getAccountManager();// 獲取賬戶管理類
?? ??? ??? ?} catch (XMPPException e) {
?? ??? ??? ??? ?throw new IllegalStateException(e);
?? ??? ??? ?}
??? ?
?? ??? ??? ?// 登錄
?? ??? ??? ?connection.login("admin", "admin","SmackTest");
?? ??? ??? ?System.out.println(connection.getUser());
?? ??? ??? ?connection.getChatManager().createChat("shimiso@csdn.shimiso.com",null).sendMessage("Hello word!");
運(yùn)行結(jié)果:
在login中一共有三個(gè)參數(shù),登錄名,密碼,資源名,可能有人不明白資源名到底是什么意思,其實(shí)就是客戶端的來(lái)源,客戶端的名稱,如果不寫(xiě)它默認(rèn)就叫smack,如果你用相同的賬戶不同的資源名和同一個(gè)人發(fā)三條消息,那將會(huì)彈出三個(gè)窗口,而不是一個(gè)窗口。
同時(shí)smack還為我們提供了非常好的調(diào)試工具Smack Debug,利用該工具我們可以準(zhǔn)確的捕獲詳細(xì)的往返報(bào)文信息。
(2)下面我們繼續(xù)寫(xiě)個(gè)聊天的例子:
?? ??? ??? ?PPConnection.DEBUG_ENABLED = true;
?? ??? ??? ?AccountManager accountManager;
?? ??? ??? ?final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
?? ??? ??? ??? ??? ?"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");
??? ?
?? ??? ??? ?// 允許自動(dòng)連接
?? ??? ??? ?connectionConfig.setReconnectionAllowed(true);
?? ??? ??? ?connectionConfig.setSendPresence(true);
??? ?
?? ??? ??? ?Connection connection = new XMPPConnection(connectionConfig);
?? ??? ??? ?try {
?? ??? ??? ??? ?connection.connect();// 開(kāi)啟連接
?? ??? ??? ??? ?accountManager = connection.getAccountManager();// 獲取賬戶管理類
?? ??? ??? ?} catch (XMPPException e) {
?? ??? ??? ??? ?throw new IllegalStateException(e);
?? ??? ??? ?}
??? ?
?? ??? ??? ?// 登錄
?? ??? ??? ?connection.login("admin", "admin","SmackTest3"); ?
?? ??? ??? ?ChatManager chatmanager = connection.getChatManager();
?? ??? ??? ?Chat newChat = chatmanager.createChat("shimiso@csdn.shimiso.com", new MessageListener() {
?? ??? ??? ??? ?public void processMessage(Chat chat, Message message) {
?? ??? ??? ??? ??? ?if (message.getBody() != null) {
?? ??? ??? ??? ??? ??? ?System.out.println("Received from 【"
?? ??? ??? ??? ??? ??? ??? ??? ?+ message.getFrom() + "】 message: "
?? ??? ??? ??? ??? ??? ??? ??? ?+ message.getBody());
?? ??? ??? ??? ??? ?}
??? ?
?? ??? ??? ??? ?}
?? ??? ??? ?});
?? ??? ??? ?Scanner input = new Scanner(System.in);
?? ??? ??? ?while (true) {
?? ??? ??? ??? ?String message = input.nextLine();
?? ??? ??? ??? ?newChat.sendMessage(message);
?? ??? ??? ?}
運(yùn)行結(jié)果:
這里我們用Scanner來(lái)捕捉用戶在控制臺(tái)的鍵盤(pán)操作,將信息發(fā)出,同時(shí)創(chuàng)建了一個(gè)MessageListener監(jiān)聽(tīng),在其中強(qiáng)制實(shí)現(xiàn)processMessage方法即可捕獲發(fā)回的信息,在初次使用上還是較為容易上手的,我們只要細(xì)心查看API即可逐步深入下去。
(3)除了聊天以外我們經(jīng)常還能想到就是廣播
需要給所有在線的用戶發(fā)送一個(gè)通知,或者給所有在線和離線的用戶全發(fā)送,我們先演示如何給在線用戶發(fā)送一個(gè)廣播:
?? ??? ??? ?PPConnection.DEBUG_ENABLED = false;
?? ??? ??? ?AccountManager accountManager;
?? ??? ??? ?final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
?? ??? ??? ??? ??? ?"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");
??? ?
?? ??? ??? ?// 允許自動(dòng)連接
?? ??? ??? ?connectionConfig.setReconnectionAllowed(true);
?? ??? ??? ?connectionConfig.setSendPresence(true);
??? ?
?? ??? ??? ?Connection connection = new XMPPConnection(connectionConfig);
?? ??? ??? ?try {
?? ??? ??? ??? ?connection.connect();// 開(kāi)啟連接
?? ??? ??? ??? ?accountManager = connection.getAccountManager();// 獲取賬戶管理類
?? ??? ??? ?} catch (XMPPException e) {
?? ??? ??? ??? ?throw new IllegalStateException(e);
?? ??? ??? ?}
?? ??? ??? ?connection.login("admin", "admin","SmackTest3");
?? ??? ??? ?Message newmsg = new Message();
?? ??? ??? ?newmsg.setTo("shimiso@csdn.shimiso.com");
?? ??? ??? ?newmsg.setSubject("重要通知");
?? ??? ??? ?newmsg.setBody("今天下午2點(diǎn)60分有會(huì)!");
?? ??? ??? ?newmsg.setType(Message.Type.headline);// normal支持離線
?? ??? ??? ?connection.sendPacket(newmsg);
?? ??? ??? ?connection.disconnect();
運(yùn)行結(jié)果:
將參數(shù)設(shè)置為Message.Type.normal即可支持離線廣播,openfire系統(tǒng)會(huì)自動(dòng)判斷該用戶是否在線,如果在線就直接發(fā)送出去,如果不在線則將信息存入ofoffline表,現(xiàn)在我將shimiso用戶退出登錄,再給它發(fā)消息,我們可以進(jìn)入openfire庫(kù)的ofoffline表中,非常清楚看到里面躺著一條離線消息記錄是發(fā)給shimiso這個(gè)用戶的
(4)那么我們?nèi)绾巫宻himiso這個(gè)用戶一登陸就取到離線消息呢?
請(qǐng)看如下代碼
?? ??? ??? ?PPConnection.DEBUG_ENABLED = false;
?? ??? ??? ?AccountManager accountManager;
?? ??? ??? ?final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
?? ??? ??? ??? ??? ?"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");
??? ?
?? ??? ??? ?// 允許自動(dòng)連接
?? ??? ??? ?connectionConfig.setReconnectionAllowed(true);
?? ??? ??? ?connectionConfig.setSendPresence(false);//不要告訴服務(wù)器自己的狀態(tài)
?? ??? ??? ?Connection connection = new XMPPConnection(connectionConfig);
?? ??? ??? ?try {
?? ??? ??? ??? ?connection.connect();// 開(kāi)啟連接
?? ??? ??? ??? ?accountManager = connection.getAccountManager();// 獲取賬戶管理類
?? ??? ??? ?} catch (XMPPException e) {
?? ??? ??? ??? ?throw new IllegalStateException(e);
?? ??? ??? ?}
?? ??? ??? ?connection.login("shimiso", "123","SmackTest");
?? ??? ??? ?OfflineMessageManager offlineManager = new OfflineMessageManager(
?? ??? ??? ??? ??? ?connection);
?? ??? ??? ?try {
?? ??? ??? ??? ?Iterator<org.jivesoftware.smack.packet.Message> it = offlineManager
?? ??? ??? ??? ??? ??? ?.getMessages();
??? ?
?? ??? ??? ??? ?System.out.println(offlineManager.supportsFlexibleRetrieval());
?? ??? ??? ??? ?System.out.println("離線消息數(shù)量: " + offlineManager.getMessageCount());
??? ?
?? ??? ??? ??? ?Map<String, ArrayList<Message>> offlineMsgs = new HashMap<String, ArrayList<Message>>();
??? ?
?? ??? ??? ??? ?while (it.hasNext()) {
?? ??? ??? ??? ??? ?org.jivesoftware.smack.packet.Message message = it.next();
?? ??? ??? ??? ??? ?System.out
?? ??? ??? ??? ??? ??? ??? ?.println("收到離線消息, Received from 【" + message.getFrom()
?? ??? ??? ??? ??? ??? ??? ??? ??? ?+ "】 message: " + message.getBody());
?? ??? ??? ??? ??? ?String fromUser = message.getFrom().split("/")[0];
??? ?
?? ??? ??? ??? ??? ?if (offlineMsgs.containsKey(fromUser)) {
?? ??? ??? ??? ??? ??? ?offlineMsgs.get(fromUser).add(message);
?? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ?ArrayList<Message> temp = new ArrayList<Message>();
?? ??? ??? ??? ??? ??? ?temp.add(message);
?? ??? ??? ??? ??? ??? ?offlineMsgs.put(fromUser, temp);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
??? ?
?? ??? ??? ??? ?// 在這里進(jìn)行處理離線消息集合......
?? ??? ??? ??? ?Set<String> keys = offlineMsgs.keySet();
?? ??? ??? ??? ?Iterator<String> offIt = keys.iterator();
?? ??? ??? ??? ?while (offIt.hasNext()) {
?? ??? ??? ??? ??? ?String key = offIt.next();
?? ??? ??? ??? ??? ?ArrayList<Message> ms = offlineMsgs.get(key);
??? ?
?? ??? ??? ??? ??? ?for (int i = 0; i < ms.size(); i++) {
?? ??? ??? ??? ??? ??? ?System.out.println("-->" + ms.get(i));
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
??? ?
?? ??? ??? ??? ?offlineManager.deleteMessages();
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ?}
?? ??? ??? ?offlineManager.deleteMessages();//刪除所有離線消息
?? ??? ??? ?Presence presence = new Presence(Presence.Type.available);
?????????? ??? ??? ?nnection.sendPacket(presence);//上線了
?????????? ??? ??? ?nnection.disconnect();//關(guān)閉連接
運(yùn)行結(jié)果:
這里我們需要特別當(dāng)心的是先不要告訴openfire服務(wù)器你上線了,否則永遠(yuǎn)也拿不到離線消息,用下面英文大概意思就是在你上線之前去獲取離線消息,這么設(shè)計(jì)是很有道理的。
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() 接著通知服務(wù)器上線了。
(5)下面我們來(lái)看看如何來(lái)發(fā)送文件
?? ??? ??? ?PPConnection.DEBUG_ENABLED = false;
?? ??? ??? ?AccountManager accountManager;
?? ??? ??? ?final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
?? ??? ??? ??? ??? ?"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");
??? ?
?? ??? ??? ?// 允許自動(dòng)連接
?? ??? ??? ?connectionConfig.setReconnectionAllowed(true);
?? ??? ??? ?connectionConfig.setSendPresence(true);
??? ?
?? ??? ??? ?Connection connection = new XMPPConnection(connectionConfig);
?? ??? ??? ?try {
?? ??? ??? ??? ?connection.connect();// 開(kāi)啟連接
?? ??? ??? ??? ?accountManager = connection.getAccountManager();// 獲取賬戶管理類
?? ??? ??? ?} catch (XMPPException e) {
?? ??? ??? ??? ?throw new IllegalStateException(e);
?? ??? ??? ?}
?? ??? ??? ?? connection.login("admin", "admin","Rooyee");
?? ??? ??? ?? Presence pre = connection.getRoster().getPresence("shimiso@csdn.shimiso.com");
?? ??? ??? ??? ?System.out.println(pre);
?? ??? ??? ??? ?if (pre.getType() != Presence.Type.unavailable) {
?? ??? ??? ??? ??? ?// 創(chuàng)建文件傳輸管理器
?? ??? ??? ??? ??? ?FileTransferManager manager = new FileTransferManager(connection);
?? ??? ??? ??? ??? ?// 創(chuàng)建輸出的文件傳輸
?? ??? ??? ??? ??? ?OutgoingFileTransfer transfer = manager
?? ??? ??? ??? ??? ??? ??? ?.createOutgoingFileTransfer(pre.getFrom());
?? ??? ??? ??? ??? ?// 發(fā)送文件
?? ??? ??? ??? ??? ?transfer.sendFile(new File("E:\\Chrysanthemum.jpg"), "圖片");
?? ??? ??? ??? ??? ?while (!transfer.isDone()) {
?? ??? ??? ??? ??? ??? ?if (transfer.getStatus() == FileTransfer.Status.in_progress) {
?? ??? ??? ??? ??? ??? ??? ?// 可以調(diào)用transfer.getProgress();獲得傳輸?shù)倪M(jìn)度
?? ??? ??? ??? ??? ??? ??? ?System.out.println(transfer.getStatus());
?? ??? ??? ??? ??? ??? ??? ?System.out.println(transfer.getProgress());
?? ??? ??? ??? ??? ??? ??? ?System.out.println(transfer.isDone());
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
運(yùn)行結(jié)果:
在這里我們需要特別注意的是,跨資源是無(wú)法發(fā)送文件的,看connection.login("admin", "admin","Rooyee");這個(gè)代碼就明白了,必須是“域名和資源名”完全相同的兩個(gè)用戶才可以互發(fā)文件,否則永遠(yuǎn)都沒(méi)反應(yīng),如果不清楚自己所用的客戶端的資源名,可以借助前面提到的SmackDebug工具查看往返信息完整報(bào)文,在to和from中一定可以看到。
如果我們自己要寫(xiě)文件接收例子的話,參考代碼如下:
??? FileTransferManager transfer = new FileTransferManager(connection);
??? transfer.addFileTransferListener(new RecFileTransferListener());
??? public class RecFileTransferListener implements FileTransferListener {
??? ?
?? ??? ?public String getFileType(String fileFullName) {
?? ??? ??? ?if (fileFullName.contains(".")) {
?? ??? ??? ??? ?return "." + fileFullName.split("//.")[1];
?? ??? ??? ?} else {
?? ??? ??? ??? ?return fileFullName;
?? ??? ??? ?}
??? ?
?? ??? ?}
??? ?
?? ??? ?@Override
?? ??? ?public void fileTransferRequest(FileTransferRequest request) {
?? ??? ??? ?System.out.println("接收文件開(kāi)始.....");
?? ??? ??? ?final IncomingFileTransfer inTransfer = request.accept();
?? ??? ??? ?final String fileName = request.getFileName();
?? ??? ??? ?long length = request.getFileSize();
?? ??? ??? ?final String fromUser = request.getRequestor().split("/")[0];
?? ??? ??? ?System.out.println("文件大小:" + length + "? " + request.getRequestor());
?? ??? ??? ?System.out.println("" + request.getMimeType());
?? ??? ??? ?try {
??? ?
?? ??? ??? ??? ?JFileChooser chooser = new JFileChooser();
?? ??? ??? ??? ?chooser.setCurrentDirectory(new File("."));
??? ?
?? ??? ??? ??? ?int result = chooser.showOpenDialog(null);
??? ?
?? ??? ??? ??? ?if (result == JFileChooser.APPROVE_OPTION) {
?? ??? ??? ??? ??? ?final File file = chooser.getSelectedFile();
?? ??? ??? ??? ??? ?System.out.println(file.getAbsolutePath());
?? ??? ??? ??? ??? ?new Thread() {
?? ??? ??? ??? ??? ??? ?public void run() {
?? ??? ??? ??? ??? ??? ??? ?try {
??? ?
?? ??? ??? ??? ??? ??? ??? ??? ?System.out.println("接受文件: " + fileName);
?? ??? ??? ??? ??? ??? ??? ??? ?inTransfer
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?.recieveFile(new File(file
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?.getAbsolutePath()
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?+ getFileType(fileName)));
??? ?
?? ??? ??? ??? ??? ??? ??? ??? ?Message message = new Message();
?? ??? ??? ??? ??? ??? ??? ??? ?message.setFrom(fromUser);
?? ??? ??? ??? ??? ??? ??? ??? ?message.setProperty("REC_SIGN", "SUCCESS");
?? ??? ??? ??? ??? ??? ??? ??? ?message.setBody("[" + fromUser + "]發(fā)送文件: "
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?+ fileName + "/r/n" + "存儲(chǔ)位置: "
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?+ file.getAbsolutePath()
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?+ getFileType(fileName));
?? ??? ??? ??? ??? ??? ??? ??? ?if (Client.isChatExist(fromUser)) {
?? ??? ??? ??? ??? ??? ??? ??? ??? ?Client.getChatRoom(fromUser)
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?.messageReceiveHandler(message);
?? ??? ??? ??? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ??? ??? ??? ?ChatFrameThread cft = new ChatFrameThread(
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?fromUser, message);
?? ??? ??? ??? ??? ??? ??? ??? ??? ?cft.start();
??? ?
?? ??? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ??? ?} catch (Exception e2) {
?? ??? ??? ??? ??? ??? ??? ??? ?e2.printStackTrace();
?? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}.start();
?? ??? ??? ??? ?} else {
??? ?
?? ??? ??? ??? ??? ?System.out.println("拒絕接受文件: " + fileName);
??? ?
?? ??? ??? ??? ??? ?request.reject();
?? ??? ??? ??? ??? ?Message message = new Message();
?? ??? ??? ??? ??? ?message.setFrom(fromUser);
?? ??? ??? ??? ??? ?message.setBody("拒絕" + fromUser + "發(fā)送文件: " + fileName);
?? ??? ??? ??? ??? ?message.setProperty("REC_SIGN", "REJECT");
?? ??? ??? ??? ??? ?if (Client.isChatExist(fromUser)) {
?? ??? ??? ??? ??? ??? ?Client.getChatRoom(fromUser).messageReceiveHandler(message);
?? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ?ChatFrameThread cft = new ChatFrameThread(fromUser, message);
?? ??? ??? ??? ??? ??? ?cft.start();
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
??? ?
?? ??? ??? ??? ?/*
?? ??? ??? ??? ? * InputStream in = inTransfer.recieveFile();
?? ??? ??? ??? ? *
?? ??? ??? ??? ? * String fileName = "r"+inTransfer.getFileName();
?? ??? ??? ??? ? *
?? ??? ??? ??? ? * OutputStream out = new FileOutputStream(new
?? ??? ??? ??? ? * File("d:/receive/"+fileName)); byte[] b = new byte[512];
?? ??? ??? ??? ? * while(in.read(b) != -1) { out.write(b); out.flush(); }
?? ??? ??? ??? ? *
?? ??? ??? ??? ? * in.close(); out.close();
?? ??? ??? ??? ? */
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ?}
??? ?
?? ??? ??? ?System.out.println("接收文件結(jié)束.....");
??? ?
?? ??? ?}
??? ?
??? }
(6)用戶列表
?? ??? ?**
?? ??? ? * 返回所有組信息 <RosterGroup>
?? ??? ? *
?? ??? ? * @return List(RosterGroup)
?? ??? ? */
?? ??? ?public static List<RosterGroup> getGroups(Roster roster) {
?? ??? ??? ?List<RosterGroup> groupsList = new ArrayList<RosterGroup>();
?? ??? ??? ?Collection<RosterGroup> rosterGroup = roster.getGroups();
?? ??? ??? ?Iterator<RosterGroup> i = rosterGroup.iterator();
?? ??? ??? ?while (i.hasNext())
?? ??? ??? ??? ?groupsList.add(i.next());
?? ??? ??? ?return groupsList;
?? ??? ?}
??? ?
?? ??? ?/**
?? ??? ? * 返回相應(yīng)(groupName)組里的所有用戶<RosterEntry>
?? ??? ? *
?? ??? ? * @return List(RosterEntry)
?? ??? ? */
?? ??? ?public static List<RosterEntry> getEntriesByGroup(Roster roster,
?? ??? ??? ??? ?String groupName) {
?? ??? ??? ?List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();
?? ??? ??? ?RosterGroup rosterGroup = roster.getGroup(groupName);
?? ??? ??? ?Collection<RosterEntry> rosterEntry = rosterGroup.getEntries();
?? ??? ??? ?Iterator<RosterEntry> i = rosterEntry.iterator();
?? ??? ??? ?while (i.hasNext())
?? ??? ??? ??? ?EntriesList.add(i.next());
?? ??? ??? ?return EntriesList;
?? ??? ?}
??? ?
?? ??? ?/**
?? ??? ? * 返回所有用戶信息 <RosterEntry>
?? ??? ? *
?? ??? ? * @return List(RosterEntry)
?? ??? ? */
?? ??? ?public static List<RosterEntry> getAllEntries(Roster roster) {
?? ??? ??? ?List<RosterEntry> EntriesList = new ArrayList<RosterEntry>();
?? ??? ??? ?Collection<RosterEntry> rosterEntry = roster.getEntries();
?? ??? ??? ?Iterator<RosterEntry> i = rosterEntry.iterator();
?? ??? ??? ?while (i.hasNext())
?? ??? ??? ??? ?EntriesList.add(i.next());
?? ??? ??? ?return EntriesList;
?? ??? ?}
(7)用戶頭像的獲取
使用VCard,很強(qiáng)大,具體自己看API吧,可以看看VCard傳回來(lái)XML的組成,含有很多信息的
?? ??? ?**
?? ??? ? * 獲取用戶的vcard信息
?? ??? ? * @param connection
?? ??? ? * @param user
?? ??? ? * @return
?? ??? ? * @throws XMPPException
?? ??? ? */
?? ??? ?public static VCard getUserVCard(XMPPConnection connection, String user) throws XMPPException
?? ??? ?{
?? ??? ??? ?VCard vcard = new VCard();
?? ??? ??? ?vcard.load(connection, user);
?? ??? ??? ?
?? ??? ??? ?return vcard;
?? ??? ?}
??? ?
?? ??? ?/**
?? ??? ? * 獲取用戶頭像信息
?? ??? ? */
?? ??? ?public static ImageIcon getUserImage(XMPPConnection connection, String user) {
?? ??? ??? ?ImageIcon ic = null;
?? ??? ??? ?try {
?? ??? ??? ??? ?System.out.println("獲取用戶頭像信息: "+user);
?? ??? ??? ??? ?VCard vcard = new VCard();
?? ??? ??? ??? ?vcard.load(connection, user);
?? ??? ??? ??? ?
?? ??? ??? ??? ?if(vcard == null || vcard.getAvatar() == null)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?return null;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?ByteArrayInputStream bais = new ByteArrayInputStream(
?? ??? ??? ??? ??? ??? ?vcard.getAvatar());
?? ??? ??? ??? ?Image image = ImageIO.read(bais);
?? ??? ?
?? ??? ??? ??? ?
?? ??? ??? ???? ic = new ImageIcon(image);
?? ??? ??? ??? ?System.out.println("圖片大小:"+ic.getIconHeight()+" "+ic.getIconWidth());
?? ??? ??? ?
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ?}
?? ??? ??? ?return ic;
?? ??? ?}
(8)組操作和用戶分組操作
?? ??? ?**
?? ??? ? * 添加一個(gè)組
?? ??? ? */
?? ??? ?public static boolean addGroup(Roster roster,String groupName)
?? ??? ?{
?? ??? ??? ?try {
?? ??? ??? ??? ?roster.createGroup(groupName);
?? ??? ??? ??? ?return true;
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ??? ?return false;
?? ??? ??? ?}
?? ??? ?}
?? ??? ?
?? ??? ?/**
?? ??? ? * 刪除一個(gè)組
?? ??? ? */
?? ??? ?public static boolean removeGroup(Roster roster,String groupName)
?? ??? ?{
?? ??? ??? ?return false;
?? ??? ?}
?? ??? ?
?? ??? ?/**
?? ??? ? * 添加一個(gè)好友? 無(wú)分組
?? ??? ? */
?? ??? ?public static boolean addUser(Roster roster,String userName,String name)
?? ??? ?{
?? ??? ??? ?try {
?? ??? ??? ??? ?roster.createEntry(userName, name, null);
?? ??? ??? ??? ?return true;
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ??? ?return false;
?? ??? ??? ?}
?? ??? ?}
?? ??? ?/**
?? ??? ? * 添加一個(gè)好友到分組
?? ??? ? * @param roster
?? ??? ? * @param userName
?? ??? ? * @param name
?? ??? ? * @return
?? ??? ? */
?? ??? ?public static boolean addUser(Roster roster,String userName,String name,String groupName)
?? ??? ?{
?? ??? ??? ?try {
?? ??? ??? ??? ?roster.createEntry(userName, name,new String[]{ groupName});
?? ??? ??? ??? ?return true;
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ??? ?return false;
?? ??? ??? ?}
?? ??? ?}
?? ??? ?
?? ??? ?/**
?? ??? ? * 刪除一個(gè)好友
?? ??? ? * @param roster
?? ??? ? * @param userName
?? ??? ? * @return
?? ??? ? */
?? ??? ?public static boolean removeUser(Roster roster,String userName)
?? ??? ?{
?? ??? ??? ?try {
?? ??? ??? ??? ?
?? ??? ??? ??? ?if(userName.contains("@"))
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?userName = userName.split("@")[0];
?? ??? ??? ??? ?}
?? ??? ??? ??? ?RosterEntry entry = roster.getEntry(userName);
?? ??? ??? ??? ?System.out.println("刪除好友:"+userName);
?? ??? ??? ??? ?System.out.println("User: "+(roster.getEntry(userName) == null));
?? ??? ??? ??? ?roster.removeEntry(entry);
?? ??? ??? ??? ?
?? ??? ??? ??? ?return true;
?? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ??? ?return false;
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ?}
(9)用戶查詢
??? public static List<UserBean> searchUsers(XMPPConnection connection,String serverDomain,String userName) throws XMPPException
?? ??? ?{
?? ??? ??? ?List<UserBean> results = new ArrayList<UserBean>();
?? ??? ??? ?System.out.println("查詢開(kāi)始..............."+connection.getHost()+connection.getServiceName());
?? ??? ??? ?
?? ??? ??? ?UserSearchManager usm = new UserSearchManager(connection);
?? ??? ??? ?
?? ??? ??? ?
??????????? Form searchForm = usm.getSearchForm(serverDomain);
??????????? Form answerForm = searchForm.createAnswerForm();
??????????? answerForm.setAnswer("Username", true);
??????????? answerForm.setAnswer("search", userName);
??????????? ReportedData data = usm.getSearchResults(answerForm, serverDomain);
?? ??? ??? ?
?? ??? ??? ? Iterator<Row> it = data.getRows();
?? ??? ??? ? Row row = null;
?? ??? ??? ? UserBean user = null;
?? ??? ??? ? while(it.hasNext())
?? ??? ??? ? {
?? ??? ??? ??? ? user = new UserBean();
?? ??? ??? ??? ? row = it.next();
?? ??? ??? ??? ? user.setUserName(row.getValues("Username").next().toString());
?? ??? ??? ??? ? user.setName(row.getValues("Name").next().toString());
?? ??? ??? ??? ? user.setEmail(row.getValues("Email").next().toString());
?? ??? ??? ??? ? System.out.println(row.getValues("Username").next());
?? ??? ??? ??? ? System.out.println(row.getValues("Name").next());
?? ??? ??? ??? ? System.out.println(row.getValues("Email").next());
?? ??? ??? ??? ? results.add(user);
?? ??? ??? ??? ? //若存在,則有返回,UserName一定非空,其他兩個(gè)若是有設(shè),一定非空
?? ??? ??? ? }
?? ??? ??? ?
?? ??? ??? ? return results;
?? ??? ?}
(10)修改自身狀態(tài)
包括上線,隱身,對(duì)某人隱身,對(duì)某人上線
?? ??? ?ublic static void updateStateToAvailable(XMPPConnection connection)
?? ??? ?{
?? ??? ??? ?Presence presence = new Presence(Presence.Type.available);
?????????? ??? ??? ?nnection.sendPacket(presence);
??????? ??? ?
?? ??? ?
?? ??? ?public static void updateStateToUnAvailable(XMPPConnection connection)
?? ??? ?{
?? ??? ??? ?Presence presence = new Presence(Presence.Type.unavailable);
?????????? ??? ??? ?nnection.sendPacket(presence);
?????? ??? ?}
?? ??? ?
?? ??? ?public static void updateStateToUnAvailableToSomeone(XMPPConnection connection,String userName)
?? ??? ?{
?? ??? ??? ?Presence presence = new Presence(Presence.Type.unavailable);
?? ??? ??? ?presence.setTo(userName);
?????????? ??? ??? ?nnection.sendPacket(presence);
?? ??? ?}
?? ??? ?public static void updateStateToAvailableToSomeone(XMPPConnection connection,String userName)
?? ??? ?{
?? ??? ??? ?Presence presence = new Presence(Presence.Type.available);
?? ??? ??? ?presence.setTo(userName);
?????????? ??? ??? ?nnection.sendPacket(presence);
??? ?
?? ??? ?}
(11)心情修改
?? ??? ?**
?? ??? ? * 修改心情
?? ??? ? * @param connection
?? ??? ? * @param status
?? ??? ? */
?? ??? ?public static void changeStateMessage(XMPPConnection connection,String status)
?? ??? ?{
?? ??? ??? ?Presence presence = new Presence(Presence.Type.available);
?? ??? ??? ?presence.setStatus(status);
?? ??? ??? ?connection.sendPacket(presence);
?? ??? ?
?? ??? ?}
(12)修改用戶頭像
有點(diǎn)麻煩,主要是讀入圖片文件,編碼,傳輸之
??? public static void changeImage(XMPPConnection connection,File f) throws XMPPException, IOException{
?? ??? ?
?? ??? ??? ?VCard vcard = new VCard();
?? ??? ??? ?vcard.load(connection);
?? ??? ??? ?
?? ??? ???????? byte[] bytes;
?? ??? ????? ?
?? ??? ???????????? bytes = getFileBytes(f);
?? ??? ???????????? String encodedImage = StringUtils.encodeBase64(bytes);
?? ??? ???????????? vcard.setAvatar(bytes, encodedImage);
?? ??? ???????????? vcard.setEncodedImage(encodedImage);
?? ??? ???????????? vcard.setField("PHOTO", "<TYPE>image/jpg</TYPE><BINVAL>"
?? ??? ???????????????????? + encodedImage + "</BINVAL>", true);
?? ??? ??????????? ?
?? ??? ??????????? ?
?? ??? ???????????? ByteArrayInputStream bais = new ByteArrayInputStream(
?? ??? ??? ??? ??? ??? ??? ?vcard.getAvatar());
?? ??? ??? ??? ??? ?Image image = ImageIO.read(bais);
?? ??? ??? ??? ??? ?ImageIcon ic = new ImageIcon(image);
?? ??? ??? ??? ??? ?
?? ??? ?????? ?
?? ??? ????? ?
?? ??? ???????? vcard.save(connection);
?? ??? ?????? ?
?? ??? ?}
?? ??? ?
????????? private static byte[] getFileBytes(File file) throws IOException {
?????????? ??? ??? ?BufferedInputStream bis = null;
?????????? ??? ?try {
??????????????? bis = new BufferedInputStream(new FileInputStream(file));
??????????????? int bytes = (int) file.length();
??????????????? byte[] buffer = new byte[bytes];
??????????????? int readBytes = bis.read(buffer);
??????????????? if (readBytes != buffer.length) {
??????????????????? throw new IOException("Entire file not read");
??????????????? }
??????????????? return buffer;
??????????? } finally {
??????????????? if (bis != null) {
??????????????????? bis.close();
??????????????? }
??????????? }
??? }
(13)用戶狀態(tài)的監(jiān)聽(tīng)
即對(duì)方改變頭像,狀態(tài),心情時(shí),更新自己用戶列表,其實(shí)這里已經(jīng)有smack實(shí)現(xiàn)的監(jiān)聽(tīng)器
?? ??? ??? ?nal Roster roster = Client.getRoster();
?? ??? ??? ?
?? ??? ??? ?roster.addRosterListener(
?? ??? ??? ??? ?new RosterListener() {
??? ?
?? ??? ??? ??? ??? ??? ?@Override
?? ??? ??? ??? ??? ??? ?public void entriesAdded(Collection<String> arg0) {
?? ??? ??? ??? ??? ??? ??? ?// TODO Auto-generated method stub
?? ??? ??? ??? ??? ??? ??? ?System.out.println("--------EE:"+"entriesAdded");
?? ??? ??? ??? ??? ??? ?}
??? ?
?? ??? ??? ??? ??? ??? ?@Override
?? ??? ??? ??? ??? ??? ?public void entriesDeleted(Collection<String> arg0) {
?? ??? ??? ??? ??? ??? ??? ?// TODO Auto-generated method stub
?? ??? ??? ??? ??? ??? ??? ?System.out.println("--------EE:"+"entriesDeleted");
?? ??? ??? ??? ??? ??? ?}
??? ?
?? ??? ??? ??? ??? ??? ?@Override
?? ??? ??? ??? ??? ??? ?public void entriesUpdated(Collection<String> arg0) {
?? ??? ??? ??? ??? ??? ??? ?// TODO Auto-generated method stub
?? ??? ??? ??? ??? ??? ??? ?System.out.println("--------EE:"+"entriesUpdated");
?? ??? ??? ??? ??? ??? ?}
??? ?
?? ??? ??? ??? ??? ??? ?@Override
?? ??? ??? ??? ??? ??? ?public void presenceChanged(Presence arg0) {
?? ??? ??? ??? ??? ??? ??? ?// TODO Auto-generated method stub
?? ??? ??? ??? ??? ??? ??? ?System.out.println("--------EE:"+"presenceChanged");
?? ??? ??? ??? ??? ??? ?}? ?
?? ??? ??? ??? ??? ??? ?
?? ??? ??? ?});
?
?
?
SmackTest例子下載
?
https://blog.csdn.net/shimiso/article/details/8816540
總結(jié)
以上是生活随笔為你收集整理的基于xmpp openfire smack开发之smack类库介绍和使用[2]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: camera理论基础和工作原理【转】
- 下一篇: R之ddlpy函数学习[转载]