一、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();
实现的方法
断开
connection.disconnect();
四、登陆
connection.login("javatest2011@gmail.com", "*****");
五、账户操作
可以对账户进行基本操作,包括注册,注销,修改密码
XMPP——Smack[2]会话、消息监听、字体表情和聊天窗口控制
拿到了connection,通过它可以搞定会话
1. 建立一个会话
通过会话发送消息
两个方法,一个直接发送一条文本,一个发送一个Message对象,可包含一些信息,一般使用后者,因为需要包装字体等信息
2. 消息监听
每个connection的chatManager可以设置一个消息监听器,因为IM必须实现他人对你发起会话也会弹出窗口,即自己可以主动发起会话,也可以接收他人发起的会话
其实窗口的管理是使用线程的,来一个新的会话,起线程
3. 字体表情
在这里实现字体和表情是使用自身开发IM之间的实现。
字体实现思想:
在发送消息的同时,将字体内容作为附加信息发送,接收方接收到根据字体信息进行处理后显示
实现:使用Message对消息进行封装
接收方先获取设置信息后展示
展示的控件: JTextPane receiveText = new JTextPane();
表情:
实现机制是客户端本身存有一套表情图片,在选中时,将表情编号加入到消息中,实际发送出去的只是文本,拿到后解析字符串,将编号转为具体表情展示
具体就不写了
1. 聊天窗口控制
所谓控制,主要是控制唯一性
无论是你发起一个会话开启一个窗口,还是对方给你发送会话开启,你与对方之间有且仅有一个窗口,之后任何消息都在这个窗口中处理
思想:单例类,持有一个
//现有的聊天窗口
public static TreeMap<String,TelFrame> currentChat = new TreeMap<String,TelFrame>();
其实应该用concurrentHashMap可能会更好,不顾我这边分派的主线程只有一个,不涉及多个线程并发的问题,所以用了Treemap,汗一个,貌似应该hashmap,当时考虑不同
然后,在接收消息的时候根据发消息的用户,判定窗口是否存在,存在,转发消息到该窗口,不存在,建立新的窗口
若是关闭窗口,注销之
这是显示用户列表方面的
1. 用户列表
Smack主要使用Roster进行列表管理的
connection.getRoster();
这里注意下,与gtalk通讯,貌似gtalk是没有分组的,汗,所以使用第三个方法直接取
当然,还要处理,若是刚注册用户,一个组都没有的,需要默认两个组,我的好友及黑名单
黑名单的消息,一律杀掉,不会接受处理
2. 用户头像的获取
使用VCard,很强大,具体自己看API吧
可以看看VCard传回来XML的组成,含有很多信息的
3. 组操作和用户分组操作
主要是建立删除分组,用户添加到分组等操作
4. 用户查询
本来是用户操作的,分组和增删在3里讲了,这里主要是查询操作
查询用户
以上查询貌似是多字段查询,即用户多个属性中某一个符合即作为查询结果
实际是可以实现根据某一特定字段查询的,如用户名,或昵称,这里笼统了,若需扩展去查看下API重写下
1. 修改自身状态
包括上线,隐身,对某人隐身,对某人上线
2. 心情修改
3. 修改用户头像
有点麻烦,主要是读入图片文件,编码,传输之
4. 补充,用户状态的监听
即对方改变头像,状态,心情时,更新自己用户列表,其实这里已经有smack实现的监听器
1. 文件的发送
开一个文件选择框,选中文件后再调用下面的方法
2. 文件接收,必须使用监听
1.离线消息
openfire本身是支持离线消息的,不需要进行额外处理,可以用spark测试下
使用smack,其实他提供了相应的方法
Class OfflineMessageManager
可以看下描述
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.
英文退化了点,汗,大意就是,必须在发送在线信息之前去获取离线消息
刚开始没看这个,结果在上线之后,去取,结果。。。。离线消息数量总是为零,囧
首先,连接,状态要设为离线
然后,登陆
connection.login(userName, pwd);
接着,拿离线消息
记得最后要把离线消息删除,即通知服务器删除离线消息
offlineManager.deleteMessages();
否则,下次上了消息还存在
接着,上线
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
2.离线文件
这个我没实现,汗
主要思想:开发openfire插件,拦截离线文件,将文件存到服务器上,同时在数据库里开一张表,存储文件信息
当用户上线时,查表,若是有,根据路径,拿了发送
当然,大家可以谷歌下是否有相应的插件,时间紧迫,我倒是没找着
到这里,大概就这些了,对了,还扩展了个视频音频聊天,不过使用的是JMF,点对点的,本来打算使用jingle的,结果连API文档都没找到,晕死
就这些