Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2206151
  • 博文数量: 866
  • 博客积分: 14125
  • 博客等级: 上将
  • 技术积分: 10638
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 16:53
个人简介

https://github.com/landuochong

文章分类

全部博文(866)

文章存档

2019年(3)

2018年(1)

2017年(10)

2015年(3)

2014年(8)

2013年(3)

2012年(70)

2011年(103)

2010年(360)

2009年(283)

2008年(22)

分类: 嵌入式

2011-07-25 13:29:28

需求:

基于XMPP的IM工具,需实现和gtalk实现通信,需实现同spark的通信,需架设服务器,实现同自身客户端的通信,传文件,视频聊天

 

写完未实现需要改进的地方:离线消息,离线文件

一、XMPP

XMPP : The Extensible Messaging and Presence Protocol

中文全称:可扩展通讯和表示协议

简介:

可扩展通讯和表示协议 (XMPP) 可用于服务类实时通讯、表示和需求 - 响应服务中的 XML 数据元流式传输。XMPP 以Jabber 协议为基础,而 Jabber 是即时通讯中常用的开放式协议。

 

二、Smack

    Smack是一个开源,易于使用的XMPP(jabber)客户端类库。

   Smack API, 是一个 Java 的XMPP Client Library,也是由Jive Software开发。 优点:编程简单。 缺点:API并非为大量并发用户设计,每个客户要1个线程,占用资源大,1台机器只能模拟有限(数千个)客户.

smack是一个用 java 写的XMPP客户端代码库, 是 spark 的核心.

 

二、连接及断开

基本方法

 XMPPConnection connection = new XMPPConnection("gmail.com");

        connection.connect();

实现的方法

  1. public static XMPPConnection getConnection(String domain) throws XMPPException {    
  2.         
  3.      XMPPConnection connection = new XMPPConnection(domain);    
  4.      connection.connect();    
  5.      return connection;    
  6. }    
  7.     
  8.     
  9. public static XMPPConnection getConnection(String domain,int port) throws XMPPException {    
  10.      ConnectionConfiguration config = new ConnectionConfiguration(domain,port);    
  11.      XMPPConnection connection = new XMPPConnection(config);    
  12.      connection.connect();    
  13.      return connection;    
  14. }   

断开  

     connection.disconnect();

     

四、登陆

connection.login("javatest2011@gmail.com", "*****");

 

五、账户操作

 

   可以对账户进行基本操作,包括注册,注销,修改密码

  1. /**  
  2.      * 注册用户  
  3.      * @param connection  
  4.      * @param regUserName  
  5.      * @param regUserPwd  
  6.      * @return  
  7.      */    
  8.     public static boolean createAccount(XMPPConnection connection,String regUserName,String regUserPwd)    
  9.     {    
  10.         try {    
  11.             connection.getAccountManager().createAccount(regUserName, regUserPwd);    
  12.             return true;    
  13.         } catch (Exception e) {    
  14.             return false;    
  15.         }    
  16.     }    
  17.         
  18.     /**  
  19.      * 删除当前用户  
  20.      * @param connection  
  21.      * @return  
  22.      */    
  23.     public static boolean deleteAccount(XMPPConnection connection)    
  24.     {    
  25.         try {    
  26.             connection.getAccountManager().deleteAccount();    
  27.             
  28.             return true;    
  29.         } catch (Exception e) {    
  30.             return false;    
  31.         }    
  32.     }    
  33.         
  34.     /**  
  35.      * 删除修改密码  
  36.      * @param connection  
  37.      * @return  
  38.      */    
  39.     public static boolean changePassword(XMPPConnection connection,String pwd)    
  40.     {    
  41.         try {    
  42.             connection.getAccountManager().changePassword(pwd);    
  43.             
  44.             return true;    
  45.         } catch (Exception e) {    
  46.             return false;    
  47.         }    
  48.     }   

连接之后,拿到了connection,通过它可以搞定会话

 1.       建立一个会话

  1. MessageListener msgListener    
  2.  = new MessageListener()    
  3.         {    
  4.             public void processMessage(Chat chat, Message message)    
  5.             {    
  6.     
  7.                 if (message != null && message.getBody() != null)    
  8.                 {    
  9.                     System.out.println("收到消息:" + message.getBody());    
  10.                     // 可以在这进行针对这个用户消息的处理,但是这里我没做操作,看后边聊天窗口的控制    
  11.                 }    
  12.     
  13.             }    
  14.         };    
  15. Chat chat = Client.getConnection().getChatManager()    
  16.                 .createChat(userName, msgListener);  

通过会话发送消息

两个方法,一个直接发送一条文本,一个发送一个Message对象,可包含一些信息,一般使用后者,因为需要包装字体等信息

  1. public static void sendMessage(Chat chat,String message) throws XMPPException {    
  2.         chat.sendMessage(message);    
  3.     }    
  4.         
  5.     public static void sendMessage(Chat chat,Message message) throws XMPPException {    
  6.         chat.sendMessage(message);    
  7.     }   

2.       消息监听

每个connectionchatManager可以设置一个消息监听器,因为IM必须实现他人对你发起会话也会弹出窗口,即自己可以主动发起会话,也可以接收他人发起的会话

  1. ChatManager manager = Client.getConnection().getChatManager();    
  2.         manager.addChatListener(new ChatManagerListener() {    
  3.             public void chatCreated(Chat chat, boolean arg1) {    
  4.                 chat.addMessageListener(new MessageListener() {    
  5.                     public void processMessage(Chat arg0, Message message) {    
  6.                      //若是聊天窗口已存在,将消息转往目前窗口    
  7.                      //若是窗口不存在,开新的窗口并注册    
  8.     
  9.                     }       
  10.                 });    
  11.             }    
  12.         });    

其实窗口的管理是使用线程的,来一个新的会话,起线程

3.  字体表情

在这里实现字体和表情是使用自身开发IM之间的实现。

 

字体实现思想:

在发送消息的同时,将字体内容作为附加信息发送,接收方接收到根据字体信息进行处理后显示

  

   实现:使用Message对消息进行封装

  1. Message msg = new Message();    
  2.         msg.setProperty("size", size);    
  3.         msg.setProperty("kind", kind);    
  4.         msg.setProperty("bold", bold);    
  5.         msg.setProperty("italic", italic);    
  6.         msg.setProperty("underline", underline);    
  7.         msg.setProperty("color", color);    
  8.         msg.setBody(getSendInfo());//真正的消息    
  9.         chat.sendMessage(msg);    

接收方先获取设置信息后展示

       展示的控件: JTextPane receiveText = new JTextPane();

  1. Style style = receiveText.addStyle("font"null);    
  2.         StyleConstants.setFontSize(style, size);    
  3.         StyleConstants.setFontFamily(style, kind);    
  4.         StyleConstants.setBold(style, bold);    
  5.         StyleConstants.setItalic(style, italic);    
  6.         StyleConstants.setUnderline(style, underline);    
  7.         StyleConstants.setForeground(style, color);    

表情:

       实现机制是客户端本身存有一套表情图片,在选中时,将表情编号加入到消息中,实际发送出去的只是文本,拿到后解析字符串,将编号转为具体表情展示

      具体就不写了

 

 

1.  聊天窗口控制

所谓控制,主要是控制唯一性

无论是你发起一个会话开启一个窗口,还是对方给你发送会话开启,你与对方之间有且仅有一个窗口,之后任何消息都在这个窗口中处理

 

思想:单例类,持有一个

//现有的聊天窗口

    public static TreeMap currentChat = new TreeMap();

 

其实应该用concurrentHashMap可能会更好,不顾我这边分派的主线程只有一个,不涉及多个线程并发的问题,所以用了Treemap,汗一个,貌似应该hashmap,当时考虑不同

 

然后,在接收消息的时候根据发消息的用户,判定窗口是否存在,存在,转发消息到该窗口,不存在,建立新的窗口

若是关闭窗口,注销之

  1. //注册聊天室    
  2.     public static void registerChat(String userName,TelFrame chatroom)    
  3.     {    
  4.         //System.out.println("注册:"+userName);    
  5.         currentChat.put(userName, chatroom);    
  6.     }    
  7.     //注销注册    
  8.     public static void removeChat(String userName)    
  9.     {    
  10.         System.out.println("用户注销聊天室:"+userName);    
  11.         currentChat.remove(userName);    
  12.     }    
  13.     //查看是否已有    
  14.     public static boolean isChatExist(String userName)    
  15.     {    
  16.             
  17.         return currentChat.containsKey(userName);    
  18.     }    
  19.     //获取对象    
  20.     public static TelFrame getChatRoom(String userName)    
  21.     {    
  22.         return currentChat.get(userName);    
  23.     }    
  24.         
阅读(1494) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册