`

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

阅读更多

本文转载http://blog.csdn.net/shimiso

 

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

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

(1)登录操作

  1. PPConnection.DEBUG_ENABLED=true;
  2. AccountManageraccountManager;
  3. finalConnectionConfigurationconnectionConfig=newConnectionConfiguration(
  4. "192.168.1.78",Integer.parseInt("5222"),"csdn.shimiso.com");
  5. //允许自动连接
  6. connectionConfig.setReconnectionAllowed(true);
  7. connectionConfig.setSendPresence(true);
  8. Connectionconnection=newXMPPConnection(connectionConfig);
  9. try{
  10. connection.connect();//开启连接
  11. accountManager=connection.getAccountManager();//获取账户管理类
  12. }catch(XMPPExceptione){
  13. thrownewIllegalStateException(e);
  14. }
  15. //登录
  16. connection.login("admin","admin","SmackTest");
  17. System.out.println(connection.getUser());
  18. connection.getChatManager().createChat("shimiso@csdn.shimiso.com",null).sendMessage("Helloword!");
		PPConnection.DEBUG_ENABLED = true;
		AccountManager accountManager;
		final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
				"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			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!");

运行结果:

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

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

  1. PPConnection.DEBUG_ENABLED=true;
  2. AccountManageraccountManager;
  3. finalConnectionConfigurationconnectionConfig=newConnectionConfiguration(
  4. "192.168.1.78",Integer.parseInt("5222"),"csdn.shimiso.com");
  5. //允许自动连接
  6. connectionConfig.setReconnectionAllowed(true);
  7. connectionConfig.setSendPresence(true);
  8. Connectionconnection=newXMPPConnection(connectionConfig);
  9. try{
  10. connection.connect();//开启连接
  11. accountManager=connection.getAccountManager();//获取账户管理类
  12. }catch(XMPPExceptione){
  13. thrownewIllegalStateException(e);
  14. }
  15. //登录
  16. connection.login("admin","admin","SmackTest3");
  17. ChatManagerchatmanager=connection.getChatManager();
  18. ChatnewChat=chatmanager.createChat("shimiso@csdn.shimiso.com",newMessageListener(){
  19. publicvoidprocessMessage(Chatchat,Messagemessage){
  20. if(message.getBody()!=null){
  21. System.out.println("Receivedfrom【"
  22. +message.getFrom()+"】message:"
  23. +message.getBody());
  24. }
  25. }
  26. });
  27. Scannerinput=newScanner(System.in);
  28. while(true){
  29. Stringmessage=input.nextLine();
  30. newChat.sendMessage(message);
  31. }
		PPConnection.DEBUG_ENABLED = true;
		AccountManager accountManager;
		final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
				"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			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);
		}

运行结果:

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

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

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

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

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			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点60分有会!");
		newmsg.setType(Message.Type.headline);// normal支持离线 
		connection.sendPacket(newmsg);
		connection.disconnect();

运行结果:

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

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

请看如下代码

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

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(false);//不要告诉服务器自己的状态
		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			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("离线消息数量: " + 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);
				}
			}

			// 在这里进行处理离线消息集合......
			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();//关闭连接

运行结果:

这里我们需要特别当心的是先不要告诉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)下面我们来看看如何来发送文件

 

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

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			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) {
				// 创建文件传输管理器
				FileTransferManager manager = new FileTransferManager(connection);
				// 创建输出的文件传输
				OutgoingFileTransfer transfer = manager
						.createOutgoingFileTransfer(pre.getFrom());
				// 发送文件
				transfer.sendFile(new File("E:\\Chrysanthemum.jpg"), "图片");
				while (!transfer.isDone()) {
					if (transfer.getStatus() == FileTransfer.Status.in_progress) {
						// 可以调用transfer.getProgress();获得传输的进度 
						System.out.println(transfer.getStatus());
						System.out.println(transfer.getProgress());
						System.out.println(transfer.isDone());
					}
				}
			}

运行结果:

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

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

  1. FileTransferManagertransfer=newFileTransferManager(connection);
  2. transfer.addFileTransferListener(newRecFileTransferListener());
  3. publicclassRecFileTransferListenerimplementsFileTransferListener{
  4. publicStringgetFileType(StringfileFullName){
  5. if(fileFullName.contains(".")){
  6. return"."+fileFullName.split("//.")[1];
  7. }else{
  8. returnfileFullName;
  9. }
  10. }
  11. @Override
  12. publicvoidfileTransferRequest(FileTransferRequestrequest){
  13. System.out.println("接收文件开始.....");
  14. finalIncomingFileTransferinTransfer=request.accept();
  15. finalStringfileName=request.getFileName();
  16. longlength=request.getFileSize();
  17. finalStringfromUser=request.getRequestor().split("/")[0];
  18. System.out.println("文件大小:"+length+""+request.getRequestor());
  19. System.out.println(""+request.getMimeType());
  20. try{
  21. JFileChooserchooser=newJFileChooser();
  22. chooser.setCurrentDirectory(newFile("."));
  23. intresult=chooser.showOpenDialog(null);
  24. if(result==JFileChooser.APPROVE_OPTION){
  25. finalFilefile=chooser.getSelectedFile();
  26. System.out.println(file.getAbsolutePath());
  27. newThread(){
  28. publicvoidrun(){
  29. try{
  30. System.out.println("接受文件:"+fileName);
  31. inTransfer
  32. .recieveFile(newFile(file
  33. .getAbsolutePath()
  34. +getFileType(fileName)));
  35. Messagemessage=newMessage();
  36. message.setFrom(fromUser);
  37. message.setProperty("REC_SIGN","SUCCESS");
  38. message.setBody("["+fromUser+"]发送文件:"
  39. +fileName+"/r/n"+"存储位置:"
  40. +file.getAbsolutePath()
  41. +getFileType(fileName));
  42. if(Client.isChatExist(fromUser)){
  43. Client.getChatRoom(fromUser)
  44. .messageReceiveHandler(message);
  45. }else{
  46. ChatFrameThreadcft=newChatFrameThread(
  47. fromUser,message);
  48. cft.start();
  49. }
  50. }catch(Exceptione2){
  51. e2.printStackTrace();
  52. }
  53. }
  54. }.start();
  55. }else{
  56. System.out.println("拒绝接受文件:"+fileName);
  57. request.reject();
  58. Messagemessage=newMessage();
  59. message.setFrom(fromUser);
  60. message.setBody("拒绝"+fromUser+"发送文件:"+fileName);
  61. message.setProperty("REC_SIGN","REJECT");
  62. if(Client.isChatExist(fromUser)){
  63. Client.getChatRoom(fromUser).messageReceiveHandler(message);
  64. }else{
  65. ChatFrameThreadcft=newChatFrameThread(fromUser,message);
  66. cft.start();
  67. }
  68. }
  69. /*
  70. *InputStreamin=inTransfer.recieveFile();
  71. *
  72. *StringfileName="r"+inTransfer.getFileName();
  73. *
  74. *OutputStreamout=newFileOutputStream(new
  75. *File("d:/receive/"+fileName));byte[]b=newbyte[512];
  76. *while(in.read(b)!=-1){out.write(b);out.flush();}
  77. *
  78. *in.close();out.close();
  79. */
  80. }catch(Exceptione){
  81. e.printStackTrace();
  82. }
  83. System.out.println("接收文件结束.....");
  84. }
  85. }
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("接收文件开始.....");
		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 + "]发送文件: "
									+ fileName + "/r/n" + "存储位置: "
									+ 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 + "发送文件: " + 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("接收文件结束.....");

	}

}

(6)用户列表

  1. **
  2. *返回所有组信息<RosterGroup>
  3. *
  4. *@returnList(RosterGroup)
  5. */
  6. publicstaticList<RosterGroup>getGroups(Rosterroster){
  7. List<RosterGroup>groupsList=newArrayList<RosterGroup>();
  8. Collection<RosterGroup>rosterGroup=roster.getGroups();
  9. Iterator<RosterGroup>i=rosterGroup.iterator();
  10. while(i.hasNext())
  11. groupsList.add(i.next());
  12. returngroupsList;
  13. }
  14. /**
  15. *返回相应(groupName)组里的所有用户<RosterEntry>
  16. *
  17. *@returnList(RosterEntry)
  18. */
  19. publicstaticList<RosterEntry>getEntriesByGroup(Rosterroster,
  20. StringgroupName){
  21. List<RosterEntry>EntriesList=newArrayList<RosterEntry>();
  22. RosterGrouprosterGroup=roster.getGroup(groupName);
  23. Collection<RosterEntry>rosterEntry=rosterGroup.getEntries();
  24. Iterator<RosterEntry>i=rosterEntry.iterator();
  25. while(i.hasNext())
  26. EntriesList.add(i.next());
  27. returnEntriesList;
  28. }
  29. /**
  30. *返回所有用户信息<RosterEntry>
  31. *
  32. *@returnList(RosterEntry)
  33. */
  34. publicstaticList<RosterEntry>getAllEntries(Rosterroster){
  35. List<RosterEntry>EntriesList=newArrayList<RosterEntry>();
  36. Collection<RosterEntry>rosterEntry=roster.getEntries();
  37. Iterator<RosterEntry>i=rosterEntry.iterator();
  38. while(i.hasNext())
  39. EntriesList.add(i.next());
  40. returnEntriesList;
  41. }
	**
	 * 返回所有组信息 <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;
	}

	/**
	 * 返回相应(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,很强大,具体自己看API吧,可以看看VCard传回来XML的组成,含有很多信息的

  1. **
  2. *获取用户的vcard信息
  3. *@paramconnection
  4. *@paramuser
  5. *@return
  6. *@throwsXMPPException
  7. */
  8. publicstaticVCardgetUserVCard(XMPPConnectionconnection,Stringuser)throwsXMPPException
  9. {
  10. VCardvcard=newVCard();
  11. vcard.load(connection,user);
  12. returnvcard;
  13. }
  14. /**
  15. *获取用户头像信息
  16. */
  17. publicstaticImageIcongetUserImage(XMPPConnectionconnection,Stringuser){
  18. ImageIconic=null;
  19. try{
  20. System.out.println("获取用户头像信息:"+user);
  21. VCardvcard=newVCard();
  22. vcard.load(connection,user);
  23. if(vcard==null||vcard.getAvatar()==null)
  24. {
  25. returnnull;
  26. }
  27. ByteArrayInputStreambais=newByteArrayInputStream(
  28. vcard.getAvatar());
  29. Imageimage=ImageIO.read(bais);
  30. ic=newImageIcon(image);
  31. System.out.println("图片大小:"+ic.getIconHeight()+""+ic.getIconWidth());
  32. }catch(Exceptione){
  33. e.printStackTrace();
  34. }
  35. returnic;
  36. }
	**
	 * 获取用户的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)组操作和用户分组操作

  1. **
  2. *添加一个组
  3. */
  4. publicstaticbooleanaddGroup(Rosterroster,StringgroupName)
  5. {
  6. try{
  7. roster.createGroup(groupName);
  8. returntrue;
  9. }catch(Exceptione){
  10. e.printStackTrace();
  11. returnfalse;
  12. }
  13. }
  14. /**
  15. *删除一个组
  16. */
  17. publicstaticbooleanremoveGroup(Rosterroster,StringgroupName)
  18. {
  19. returnfalse;
  20. }
  21. /**
  22. *添加一个好友无分组
  23. */
  24. publicstaticbooleanaddUser(Rosterroster,StringuserName,Stringname)
  25. {
  26. try{
  27. roster.createEntry(userName,name,null);
  28. returntrue;
  29. }catch(Exceptione){
  30. e.printStackTrace();
  31. returnfalse;
  32. }
  33. }
  34. /**
  35. *添加一个好友到分组
  36. *@paramroster
  37. *@paramuserName
  38. *@paramname
  39. *@return
  40. */
  41. publicstaticbooleanaddUser(Rosterroster,StringuserName,Stringname,StringgroupName)
  42. {
  43. try{
  44. roster.createEntry(userName,name,newString[]{groupName});
  45. returntrue;
  46. }catch(Exceptione){
  47. e.printStackTrace();
  48. returnfalse;
  49. }
  50. }
  51. /**
  52. *删除一个好友
  53. *@paramroster
  54. *@paramuserName
  55. *@return
  56. */
  57. publicstaticbooleanremoveUser(Rosterroster,StringuserName)
  58. {
  59. try{
  60. if(userName.contains("@"))
  61. {
  62. userName=userName.split("@")[0];
  63. }
  64. RosterEntryentry=roster.getEntry(userName);
  65. System.out.println("删除好友:"+userName);
  66. System.out.println("User:"+(roster.getEntry(userName)==null));
  67. roster.removeEntry(entry);
  68. returntrue;
  69. }catch(Exceptione){
  70. e.printStackTrace();
  71. returnfalse;
  72. }
  73. }
	**
	 * 添加一个组
	 */
	public static boolean addGroup(Roster roster,String groupName)
	{
		try {
			roster.createGroup(groupName);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 删除一个组
	 */
	public static boolean removeGroup(Roster roster,String groupName)
	{
		return false;
	}
	
	/**
	 * 添加一个好友  无分组
	 */
	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;
		}
	}
	/**
	 * 添加一个好友到分组
	 * @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;
		}
	}
	
	/**
	 * 删除一个好友
	 * @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)用户查询

  1. publicstaticList<UserBean>searchUsers(XMPPConnectionconnection,StringserverDomain,StringuserName)throwsXMPPException
  2. {
  3. List<UserBean>results=newArrayList<UserBean>();
  4. System.out.println("查询开始..............."+connection.getHost()+connection.getServiceName());
  5. UserSearchManagerusm=newUserSearchManager(connection);
  6. FormsearchForm=usm.getSearchForm(serverDomain);
  7. FormanswerForm=searchForm.createAnswerForm();
  8. answerForm.setAnswer("Username",true);
  9. answerForm.setAnswer("search",userName);
  10. ReportedDatadata=usm.getSearchResults(answerForm,serverDomain);
  11. Iterator<Row>it=data.getRows();
  12. Rowrow=null;
  13. UserBeanuser=null;
  14. while(it.hasNext())
  15. {
  16. user=newUserBean();
  17. row=it.next();
  18. user.setUserName(row.getValues("Username").next().toString());
  19. user.setName(row.getValues("Name").next().toString());
  20. user.setEmail(row.getValues("Email").next().toString());
  21. System.out.println(row.getValues("Username").next());
  22. System.out.println(row.getValues("Name").next());
  23. System.out.println(row.getValues("Email").next());
  24. results.add(user);
  25. //若存在,则有返回,UserName一定非空,其他两个若是有设,一定非空
  26. }
  27. returnresults;
  28. }
public static List<UserBean> searchUsers(XMPPConnection connection,String serverDomain,String userName) throws XMPPException
	{
		List<UserBean> results = new ArrayList<UserBean>();
		System.out.println("查询开始..............."+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一定非空,其他两个若是有设,一定非空
		 }
		 
		 return results;
	}

(10)修改自身状态

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

  1. ublicstaticvoidupdateStateToAvailable(XMPPConnectionconnection)
  2. {
  3. Presencepresence=newPresence(Presence.Type.available);
  4. nnection.sendPacket(presence);
  5. publicstaticvoidupdateStateToUnAvailable(XMPPConnectionconnection)
  6. {
  7. Presencepresence=newPresence(Presence.Type.unavailable);
  8. nnection.sendPacket(presence);
  9. }
  10. publicstaticvoidupdateStateToUnAvailableToSomeone(XMPPConnectionconnection,StringuserName)
  11. {
  12. Presencepresence=newPresence(Presence.Type.unavailable);
  13. presence.setTo(userName);
  14. nnection.sendPacket(presence);
  15. }
  16. publicstaticvoidupdateStateToAvailableToSomeone(XMPPConnectionconnection,StringuserName)
  17. {
  18. Presencepresence=newPresence(Presence.Type.available);
  19. presence.setTo(userName);
  20. nnection.sendPacket(presence);
  21. }
	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)心情修改

  1. **
  2. *修改心情
  3. *@paramconnection
  4. *@paramstatus
  5. */
  6. publicstaticvoidchangeStateMessage(XMPPConnectionconnection,Stringstatus)
  7. {
  8. Presencepresence=newPresence(Presence.Type.available);
  9. presence.setStatus(status);
  10. connection.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)修改用户头像

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

  1. publicstaticvoidchangeImage(XMPPConnectionconnection,Filef)throwsXMPPException,IOException{
  2. VCardvcard=newVCard();
  3. vcard.load(connection);
  4. byte[]bytes;
  5. bytes=getFileBytes(f);
  6. StringencodedImage=StringUtils.encodeBase64(bytes);
  7. vcard.setAvatar(bytes,encodedImage);
  8. vcard.setEncodedImage(encodedImage);
  9. vcard.setField("PHOTO","<TYPE>image/jpg</TYPE><BINVAL>"
  10. +encodedImage+"</BINVAL>",true);
  11. ByteArrayInputStreambais=newByteArrayInputStream(
  12. vcard.getAvatar());
  13. Imageimage=ImageIO.read(bais);
  14. ImageIconic=newImageIcon(image);
  15. vcard.save(connection);
  16. }
  17. privatestaticbyte[]getFileBytes(Filefile)throwsIOException{
  18. BufferedInputStreambis=null;
  19. try{
  20. bis=newBufferedInputStream(newFileInputStream(file));
  21. intbytes=(int)file.length();
  22. byte[]buffer=newbyte[bytes];
  23. intreadBytes=bis.read(buffer);
  24. if(readBytes!=buffer.length){
  25. thrownewIOException("Entirefilenotread");
  26. }
  27. returnbuffer;
  28. }finally{
  29. if(bis!=null){
  30. bis.close();
  31. }
  32. }
  33. }
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)用户状态的监听

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

  1. nalRosterroster=Client.getRoster();
  2. roster.addRosterListener(
  3. newRosterListener(){
  4. @Override
  5. publicvoidentriesAdded(Collection<String>arg0){
  6. //TODOAuto-generatedmethodstub
  7. System.out.println("--------EE:"+"entriesAdded");
  8. }
  9. @Override
  10. publicvoidentriesDeleted(Collection<String>arg0){
  11. //TODOAuto-generatedmethodstub
  12. System.out.println("--------EE:"+"entriesDeleted");
  13. }
  14. @Override
  15. publicvoidentriesUpdated(Collection<String>arg0){
  16. //TODOAuto-generatedmethodstub
  17. System.out.println("--------EE:"+"entriesUpdated");
  18. }
  19. @Override
  20. publicvoidpresenceChanged(Presencearg0){
  21. //TODOAuto-generatedmethodstub
  22. System.out.println("--------EE:"+"presenceChanged");
  23. }
  24. });
		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");
					}   
					
		});
 
 
分享到:
评论

相关推荐

    基于xmpp_openfire_smack开发之smack类库介绍和使用

    总之,Smack 类库为开发者提供了全面的工具集,用于构建基于 XMPP 协议的实时通信应用,无论是在桌面应用还是移动应用中,都能发挥其强大的功能。通过深入理解和熟练使用 Smack,开发者可以构建高效、稳定且功能丰富...

    高仿android qq客户端 基于xmpp openfire smack

    高仿android qq客户端,基于xmpp openfire smack。难得的即时通信学习源码。 介绍链接: http://blog.csdn.net/shimiso/article/details/11225873

    基于xmpp openfire smack开发之Android客户端开发

    2.离线消息 3.添加,删除好友 4.添加,移动好友分组 5.设置昵称 6.监控好友状态 7.网络断开系统自动重连接 8.收到添加好友请求消息处理 9.收到系统广播消息处理 10.查看历史聊天记录 11.消息弹出提醒,和小气泡 .......

    即时通信源码 高仿android qq客户端 基于xmpp openfire smack.

    基于xmpp openfire smack 的即时通信客户端,高仿qq,难得的学习资源。 资源介绍:http://blog.csdn.net/shimiso/article/details/11225873

    Android使用XMPP协议、OpenFire服务器和Smack类库实现即时通信

    本篇文章将深入探讨如何利用XMPP协议,结合OpenFire服务器以及Smack类库,在Android项目中构建一个即时通讯应用。 首先,我们需要了解OpenFire服务器。OpenFire是一款免费、开源的XMPP服务器,它支持多种操作系统,...

    android studio基于XMPP,Openfire,Smack聊天demo

    这个项目“android studio基于XMPP,Openfire,Smack聊天demo”提供了一个使用Android Studio、XMPP协议、Openfire服务器和Smack库实现的聊天应用示例。以下是关于这些关键技术的详细解释: **XMPP(Extensible ...

    Android 基于xmpp协议,smack包,openfire服务端的高仿QQ的即时通讯实现.zip

    综上所述,这个项目涉及到的技术栈包括XMPP协议、Smack库的使用、Openfire服务器的部署和配置,以及Android应用开发中的UI设计、安全性和性能优化。通过这些技术的结合,可以构建出一个功能完善的即时通讯应用,为...

    openfire+smack开发webim笔记

    总结:通过"openfire+smack"开发WebIM,我们可以理解到XMPP协议在Web即时通讯中的重要性,以及Openfire作为服务器软件的角色。同时,Smack库简化了Java应用与XMPP服务器的交互。WebIM的实现方式多样化,包括Ajax、...

    Android启动Service登陆Openfire实现基于XMPP Smack的消息推送功能

    本项目“Android启动Service登陆Openfire实现基于XMPP Smack的消息推送功能”就是一个很好的示例,展示了如何利用Service和XMPP协议在Android设备上实现实时消息传递。 首先,Openfire是一款开源的XMPP服务器,它...

    Android代码-基于openfire和smack的安卓xmpp客户端

    【Android代码-基于openfire和smack的安卓xmpp客户端】是一个项目,它实现了使用XMPP协议在Android设备上创建一个客户端应用。XMPP(Extensible Messaging and Presence Protocol)是一种实时通信协议,常用于实现...

    OpenFire+smack3.0.4 即时通讯Demo

    首先,OpenFire是一款用Java编写的开源XMPP服务器,它基于XMPP(Extensible Messaging and Presence Protocol)协议,这个协议被广泛用于即时通讯系统,提供实时通讯和在线状态等功能。OpenFire的特点包括高效、可...

    openfire+spark+smack开发流程.pdf

    在本文中,我们将详细介绍OpenFire、Spark和Smack三个组件在XMPP IM开发中的作用,以及如何使用它们来开发一个完整的XMPP IM系统。 首先,让我们了解一下XMPP是什么?Extensible Messaging and Presence Protocol,...

    基于smack连接openfire服务器的例子-JAVA

    Openfire是基于XMPP的服务器,提供了一个强大且可扩展的架构,使得开发者可以轻松创建聊天、协作和其他实时通信应用。 本文将深入探讨如何使用Smack库,一个Java实现的XMPP客户端库,来连接到Openfire服务器并进行...

    Smack API java的类库

    在实际开发中,Openfire是一款流行的开源XMPP服务器,它支持多种客户端连接,包括使用Smack API的Java应用。Openfire提供了用户管理、群组管理、权限控制等一系列服务器端功能,与Smack API相结合,可以构建出强大的...

    openfire+spark+smack

    Openfire、Spark和Smack是三个与XMPP(Extensible Messaging and Presence Protocol)相关的开源项目,它们在构建即时通讯(IM)系统中扮演着重要角色。XMPP是一种基于XML的网络协议,主要用于实时通讯,包括消息...

    openfire+smack即时通讯

    综上所述,建立一个"openfire+smack即时通讯"系统涉及的主要技术点有XMPP协议的使用、Openfire服务器的部署与配置、Smack库的集成开发以及客户端的UI设计和功能实现。开发者需要熟悉Java编程,理解XMPP的工作原理,...

    基于Smack3.0.4+ Openfire3.10.2开发之Android 客户端之三

    在本教程中,我们将深入探讨如何使用Smack 3.0.4库和Openfire 3.10.2服务器来开发一个Android客户端,重点在于实现用户登录、注册功能以及与XMPP服务器的交互。首先,让我们理解这两个关键组件。 **Smack 3.0.4** ...

    XMPP+Openfire4.5.1+Smack4.3.4+MySql

    XMPP+Openfire4.5.1+Smack4.3.4+MySql,支持手机对手机,手机对PC(Spark)的消息收发

    java android openfire smack项目源码

    【标题】"java android openfire smack项目源码"所涉及的知识点主要集中在Java、Android、OpenFire和Smack这四个核心领域。以下是对这些技术的详细介绍: 1. **Java**:Java是一种广泛使用的面向对象的编程语言,...

    Xmpp和OpenFire实例

    先说一下为什么要写这篇博客,是因为本人在周末在研究XMPP和OpenFire,从网上下载了个Demo,但跑不起来,花了很长时间,经改造后,跑起来了,写个篇博文也是希望后边学习XMPP和OpenFire的同学下载后直接运行,少走...

Global site tag (gtag.js) - Google Analytics