• Android基于XMPP Smack Openfire下学习开发IM(一)实现用户注册、登录、修改密码和注销等


    http://blog.csdn.net/h7870181/article/details/8653865

    以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了。后来在网上看到用openfire做服务器,利用强大的Smack API库来实现IM聊天就简单多了。 

    网上也有很多关于这方面的资料,我就在这里把网上的资料和自己的理解总结一下和大家一起交流学习。

    需要用到以下几个工具:

    Openfire  最新版本(openfire 3.8.1) 

    下载地址:http://www.igniterealtime.org/downloads/index.jsp

    安装配置可参考:http://www.cnblogs.com/hoojo/archive/2012/05/17/2506769.html

    Spark  最新版本(Spark 2.6.3)

    下载地址:http://www.igniterealtime.org/downloads/index.jsp

    ASmack  最新版本 (asmack-jse-buddycloud-2010.12.11.jar)

    由于在Android平台下开发 所以我们用到的是 aSmack,与Smack没有很大的区别

    下载地址1:http://download.csdn.net/detail/h7870181/6372585 (现在用的就是这个,修改了一些BUG)

    下载地址2:http://code.google.com/p/asmack/downloads/list

    需要安装的安装好,需要下载的下载好(这里就不多作介绍)。创建项目工程,导入ASmack jar包,OK,下面就一起去学习怎么实现 用户注册、登录、修改密码和注销等一些功能!

    首先第一、与服务器建立好连接

    关键代码:127.0.0.1为服务器IP,5222为服务器端口号

    1. /** 
    2.  * 连接服务器 
    3.  *  
    4.  * @return 
    5.  */  
    6. public boolean conServer() {  
    7.     ConnectionConfiguration config = new ConnectionConfiguration(  
    8.             127.0.0.1, 5222);  
    9.     /** 是否启用安全验证 */  
    10.     config.setSASLAuthenticationEnabled(false);  
    11.     /** 是否启用调试 */  
    12.     // config.setDebuggerEnabled(true);   
    13.     /** 创建connection链接 */  
    14.     try {  
    15.         connection = new XMPPConnection(config);  
    16.         /** 建立连接 */  
    17.         connection.connect();  
    18.         return true;  
    19.     } catch (XMPPException e) {  
    20.         e.printStackTrace();  
    21.     }  
    22.     return false;  
    23. }  
    	/**
    	 * 连接服务器
    	 * 
    	 * @return
    	 */
    	public boolean conServer() {
    		ConnectionConfiguration config = new ConnectionConfiguration(
    				127.0.0.1, 5222);
    		/** 是否启用安全验证 */
    		config.setSASLAuthenticationEnabled(false);
    		/** 是否启用调试 */
    		// config.setDebuggerEnabled(true);
    		/** 创建connection链接 */
    		try {
    			connection = new XMPPConnection(config);
    			/** 建立连接 */
    			connection.connect();
    			return true;
    		} catch (XMPPException e) {
    			e.printStackTrace();
    		}
    		return false;
    	}

    第二、实现注册

    关键代码:

    以下代码注释都很清楚了,如有不懂的地方可以留言,这里就不多做解释了。

    1. /** 
    2.  * 注册 
    3.  *  
    4.  * @param account 注册帐号 
    5.  * @param password 注册密码 
    6.  * @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败 
    7.  */  
    8. public String regist(String account, String password) {  
    9.     if (connection == null)  
    10.         return "0";  
    11.     Registration reg = new Registration();  
    12.     reg.setType(IQ.Type.SET);  
    13.     reg.setTo(ClientConServer.connection.getServiceName());  
    14.     reg.setUsername(account);// 注意这里createAccount注册时,参数是username,不是jid,是“@”前面的部分。   
    15.     reg.setPassword(password);  
    16.     reg.addAttribute("android", "geolo_createUser_android");// 这边addAttribute不能为空,否则出错。所以做个标志是android手机创建的吧!!!!!   
    17.     PacketFilter filter = new AndFilter(new PacketIDFilter(  
    18.             reg.getPacketID()), new PacketTypeFilter(IQ.class));  
    19.     PacketCollector collector = ClientConServer.connection  
    20.             .createPacketCollector(filter);  
    21.     ClientConServer.connection.sendPacket(reg);  
    22.     IQ result = (IQ) collector.nextResult(SmackConfiguration  
    23.             .getPacketReplyTimeout());  
    24.     // Stop queuing results   
    25.     collector.cancel();// 停止请求results(是否成功的结果)   
    26.     if (result == null) {  
    27.         Log.e("RegistActivity", "No response from server.");  
    28.         return "0";  
    29.     } else if (result.getType() == IQ.Type.RESULT) {  
    30.         return "1";  
    31.     } else { // if (result.getType() == IQ.Type.ERROR)   
    32.         if (result.getError().toString().equalsIgnoreCase("conflict(409)")) {  
    33.             Log.e("RegistActivity", "IQ.Type.ERROR: "  
    34.                     + result.getError().toString());  
    35.             return "2";  
    36.         } else {  
    37.             Log.e("RegistActivity", "IQ.Type.ERROR: "  
    38.                     + result.getError().toString());  
    39.             return "3";  
    40.         }  
    41.     }  
    42. }  
    	/**
    	 * 注册
    	 * 
    	 * @param account 注册帐号
    	 * @param password 注册密码
    	 * @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败
    	 */
    	public String regist(String account, String password) {
    		if (connection == null)
    			return "0";
    		Registration reg = new Registration();
    		reg.setType(IQ.Type.SET);
    		reg.setTo(ClientConServer.connection.getServiceName());
    		reg.setUsername(account);// 注意这里createAccount注册时,参数是username,不是jid,是“@”前面的部分。
    		reg.setPassword(password);
    		reg.addAttribute("android", "geolo_createUser_android");// 这边addAttribute不能为空,否则出错。所以做个标志是android手机创建的吧!!!!!
    		PacketFilter filter = new AndFilter(new PacketIDFilter(
    				reg.getPacketID()), new PacketTypeFilter(IQ.class));
    		PacketCollector collector = ClientConServer.connection
    				.createPacketCollector(filter);
    		ClientConServer.connection.sendPacket(reg);
    		IQ result = (IQ) collector.nextResult(SmackConfiguration
    				.getPacketReplyTimeout());
    		// Stop queuing results
    		collector.cancel();// 停止请求results(是否成功的结果)
    		if (result == null) {
    			Log.e("RegistActivity", "No response from server.");
    			return "0";
    		} else if (result.getType() == IQ.Type.RESULT) {
    			return "1";
    		} else { // if (result.getType() == IQ.Type.ERROR)
    			if (result.getError().toString().equalsIgnoreCase("conflict(409)")) {
    				Log.e("RegistActivity", "IQ.Type.ERROR: "
    						+ result.getError().toString());
    				return "2";
    			} else {
    				Log.e("RegistActivity", "IQ.Type.ERROR: "
    						+ result.getError().toString());
    				return "3";
    			}
    		}
    	}
    

    第三、实现登录

    关键代码: 代码很简单不做太多解释

    1.      /** 
    2.  * 登录 
    3.  *  
    4.  * @param a 登录帐号 
    5.  * @param p 登录密码 
    6.  * @return 
    7.  */  
    8. public boolean login(String a, String p) {  
    9.     try {  
    10.         if (connection == null)  
    11.             return false;  
    12.         /** 登录 */             
    13.         connection.login(a, p);  
    14.         return true;  
    15.     } catch (Exception e) {  
    16.         e.printStackTrace();  
    17.     }  
    18.     return false;  
    19. }  
     	 /**
    	 * 登录
    	 * 
    	 * @param a 登录帐号
    	 * @param p 登录密码
    	 * @return
    	 */
    	public boolean login(String a, String p) {
    		try {
    			if (connection == null)
    				return false;
    			/** 登录 */			
    			connection.login(a, p);
    			return true;
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return false;
    	}

    第四、修改密码

    关键代码:同样很简单

    1. /**  
    2.  * 修改密码  
    3.  * @param connection  
    4.  * @return  
    5.  */    
    6. public static boolean changePassword(XMPPConnection connection,String pwd)    
    7. {    
    8.     try {    
    9.         connection.getAccountManager().changePassword(pwd);    
    10.         return true;    
    11.     } catch (Exception e) {    
    12.         return false;    
    13.     }    
    14. }   
        /** 
         * 修改密码 
         * @param connection 
         * @return 
         */  
        public static boolean changePassword(XMPPConnection connection,String pwd)  
        {  
            try {  
                connection.getAccountManager().changePassword(pwd);  
                return true;  
            } catch (Exception e) {  
                return false;  
            }  
        } 

    第五、更改用户状态

    关键代码:好吧,代码有点多,不过很清晰

    1. /** 
    2.  * 更改用户状态 
    3.  */  
    4. public void setPresence(int code) {  
    5.     if (connection == null)  
    6.         return;  
    7.     Presence presence;  
    8.     switch (code) {  
    9.         case 0:  
    10.             presence = new Presence(Presence.Type.available);  
    11.             connection.sendPacket(presence);  
    12.             Log.v("state", "设置在线");  
    13.             break;  
    14.         case 1:  
    15.             presence = new Presence(Presence.Type.available);  
    16.             presence.setMode(Presence.Mode.chat);  
    17.             connection.sendPacket(presence);  
    18.             Log.v("state", "设置Q我吧");  
    19.             System.out.println(presence.toXML());  
    20.             break;  
    21.         case 2:  
    22.             presence = new Presence(Presence.Type.available);  
    23.             presence.setMode(Presence.Mode.dnd);  
    24.             connection.sendPacket(presence);  
    25.             Log.v("state", "设置忙碌");  
    26.             System.out.println(presence.toXML());  
    27.             break;  
    28.         case 3:  
    29.             presence = new Presence(Presence.Type.available);  
    30.             presence.setMode(Presence.Mode.away);  
    31.             connection.sendPacket(presence);  
    32.             Log.v("state", "设置离开");  
    33.             System.out.println(presence.toXML());  
    34.             break;  
    35.         case 4:  
    36.             Roster roster = connection.getRoster();  
    37.             Collection<RosterEntry> entries = roster.getEntries();  
    38.             for (RosterEntry entry : entries) {  
    39.                 presence = new Presence(Presence.Type.unavailable);  
    40.                 presence.setPacketID(Packet.ID_NOT_AVAILABLE);  
    41.                 presence.setFrom(connection.getUser());  
    42.                 presence.setTo(entry.getUser());  
    43.                 connection.sendPacket(presence);  
    44.                 System.out.println(presence.toXML());  
    45.             }  
    46.             // 向同一用户的其他客户端发送隐身状态   
    47.             presence = new Presence(Presence.Type.unavailable);  
    48.             presence.setPacketID(Packet.ID_NOT_AVAILABLE);  
    49.             presence.setFrom(connection.getUser());  
    50.             presence.setTo(StringUtils.parseBareAddress(connection.getUser()));  
    51.             connection.sendPacket(presence);  
    52.             Log.v("state", "设置隐身");  
    53.             break;  
    54.         case 5:  
    55.             presence = new Presence(Presence.Type.unavailable);  
    56.             connection.sendPacket(presence);  
    57.             Log.v("state", "设置离线");  
    58.             break;  
    59.         default:  
    60.             break;  
    61.         }  
    62.     }  
    	/**
    	 * 更改用户状态
    	 */
    	public void setPresence(int code) {
    		if (connection == null)
    			return;
    		Presence presence;
    		switch (code) {
    			case 0:
    				presence = new Presence(Presence.Type.available);
    				connection.sendPacket(presence);
    				Log.v("state", "设置在线");
    				break;
    			case 1:
    				presence = new Presence(Presence.Type.available);
    				presence.setMode(Presence.Mode.chat);
    				connection.sendPacket(presence);
    				Log.v("state", "设置Q我吧");
    				System.out.println(presence.toXML());
    				break;
    			case 2:
    				presence = new Presence(Presence.Type.available);
    				presence.setMode(Presence.Mode.dnd);
    				connection.sendPacket(presence);
    				Log.v("state", "设置忙碌");
    				System.out.println(presence.toXML());
    				break;
    			case 3:
    				presence = new Presence(Presence.Type.available);
    				presence.setMode(Presence.Mode.away);
    				connection.sendPacket(presence);
    				Log.v("state", "设置离开");
    				System.out.println(presence.toXML());
    				break;
    			case 4:
    				Roster roster = connection.getRoster();
    				Collection<RosterEntry> entries = roster.getEntries();
    				for (RosterEntry entry : entries) {
    					presence = new Presence(Presence.Type.unavailable);
    					presence.setPacketID(Packet.ID_NOT_AVAILABLE);
    					presence.setFrom(connection.getUser());
    					presence.setTo(entry.getUser());
    					connection.sendPacket(presence);
    					System.out.println(presence.toXML());
    				}
    				// 向同一用户的其他客户端发送隐身状态
    				presence = new Presence(Presence.Type.unavailable);
    				presence.setPacketID(Packet.ID_NOT_AVAILABLE);
    				presence.setFrom(connection.getUser());
    				presence.setTo(StringUtils.parseBareAddress(connection.getUser()));
    				connection.sendPacket(presence);
    				Log.v("state", "设置隐身");
    				break;
    			case 5:
    				presence = new Presence(Presence.Type.unavailable);
    				connection.sendPacket(presence);
    				Log.v("state", "设置离线");
    				break;
    			default:
    				break;
    			}
    		}

     

    第六:注销

    关键代码:很简单吧!

    1. /**  
    2.  * 删除当前用户  
    3.  * @param connection  
    4.  * @return  
    5.  */    
    6. public static boolean deleteAccount(XMPPConnection connection)    
    7. {    
    8.     try {    
    9.         connection.getAccountManager().deleteAccount();    
    10.         return true;    
    11.     } catch (Exception e) {    
    12.         return false;    
    13.     }    
    14. }    
        /** 
         * 删除当前用户 
         * @param connection 
         * @return 
         */  
        public static boolean deleteAccount(XMPPConnection connection)  
        {  
            try {  
                connection.getAccountManager().deleteAccount();  
                return true;  
            } catch (Exception e) {  
                return false;  
            }  
        }  


    好吧,这篇就先介绍到这!

  • 相关阅读:
    安装linux下文件搜索工具ANGRYsearch,与windows下Everything类似
    windows常用软件、Linux软件对比
    在linux下双击用wine软件的打开
    好用的Linux下PDF编辑批注软件PDF Studio Pro 11
    python multiprocessing.pool.apply_async 占用内存多 解决方法
    linux 版 Fiddler 抓包软件的安装
    安装linux下强大的文件搜索工具fsearch,与windows下Everything类似
    python3 删除空文件夹
    【廖雪峰老师python教程】——错误和调试
    【廖雪峰老师python教程】——OOP
  • 原文地址:https://www.cnblogs.com/wangluochong/p/4037110.html
Copyright © 2020-2023  润新知