最近公司项目需要用到即时通讯功能,经过调研发现openfire+spark+smack可以实现。在网上找了很久,资料都十分有限,即使有些朋友实现了也说的不清不楚。于是决定自己研究,耗时一周的时间实现了文字通讯和文件传输的功能。现发帖分享给有需要的朋友,也希望大家能够把自己的资料都分享出来,不要敝扫自珍。
废话说够了,现在开始上干货:
1.openfire是什么?
openfire是一个即时通讯服务器,也称之为即时通讯平台。它是基于XMPP协议的,大家所熟悉的通讯软件QQ、MSN和Gtalk等等,其中Gtalk就是基于XMPP协议的实现。
在即时通讯中往往因为需要保存一些状态或者数据所以不能采用点对点通讯,而是需要搭建服务器来转发。
下载地址:http://www.igniterealtime.org/downloads/index.jsp
下载完毕以后根据提示安装、配置,然后访问所配置的服务器地址上的9090端口即可访问官方为我们实现好了的openfire后台管理系统。
2.spark是什么?
spark从本质上来说就是一个运行在PC上的java程序,你可以看成是官方为我们实现好的运行在PC上的客户端,我们只需要下载使用即可。
(当然如果你项目的需求现有的spark无法满足,你可以选择在官方下载spark的源码,对它进行修改)
下载地址:http://www.igniterealtime.org/downloads/index.jsp
3.smack是什么?
smack你可以看成是一套封装好了的用于实现XMPP协议传输的API,它是一个非常简单并且功能强大的类库,给用户发送消息只需要三行代码。
下载地址:http://www.igniterealtime.org/downloads/index.jsp
这里需要强调一点,我们在android上开发用的其实是移植版的类库asmack,而asmack现在在网上流传的版本是有BUG的,在传输文件的时候会报空指针异常。我在这个问题上也是耗时最多的,在网上找了许多网友修改过的版本,都不顶用,最后也是在eoe论坛中找到了靠谱的asmack修订版:
详见:http://www.eoeandroid.com/thread-186418-1-1.html
好了,读到这里,相信你对这套实现思路的一些基本概念已经清楚了,那么请准备好上面的三板斧,下面就开始写代码吧。
文字通讯的重要代码片段:(请注意更换你自己的服务器地址、用户名和密码以及想要访问的用户名)
// 连接参数
ConnectionConfiguration connConfig = new ConnectionConfiguration("192.168.0.1", 5222);
connConfig.setReconnectionAllowed(true);
connConfig.setSecurityMode(SecurityMode.disabled); // SecurityMode.required/disabled
connConfig.setSASLAuthenticationEnabled(false); // true/false
connConfig.setCompressionEnabled(false);
// 配置服务器
XMPPConnection connection = new XMPPConnection(connConfig);
try {
// 连接服务器
connection.connect();
// 用户登录
connection.login("joe", "123456");
// 向另一个用户发出聊天
Chat chat = connection.getChatManager().createChat("[email protected]/Spark 2.6.3", new MessageListener() {
// 消息回复函数
@Override
public void processMessage(Chat arg0, Message arg1) {
System.out.println("Received message: " + arg1.getBody());
try
{
arg0.sendMessage("我已收到");
} catch (XMPPException e)
{
e.printStackTrace();
}
}
});
// 发送聊天信息
chat.sendMessage("Hello!");
文件传输的重要代码片段:(请注意更换你自己的服务器地址、用户名和密码以及想要访问的用户名)
// 连接参数
ConnectionConfiguration connConfig = new ConnectionConfiguration("192.168.0.1", 5222);
connConfig.setReconnectionAllowed(true);
connConfig.setSecurityMode(SecurityMode.disabled); // SecurityMode.required/disabled
connConfig.setSASLAuthenticationEnabled(false); // true/false
connConfig.setCompressionEnabled(false);
// 配置服务器
XMPPConnection connection = new XMPPConnection(connConfig);
try {
// 连接服务器
connection.connect();
// 用户登录
connection.login("joe", "123456");
// 准备发送的文件
File file = new File(PATH);
FileTransferManager transferManager = new FileTransferManager(
connection);
OutgoingFileTransfer outgoingFileTransfer = transferManager
.createOutgoingFileTransfer("[email protected]/Spark 2.6.3");
// 发送文件
outgoingFileTransfer.sendFile(file, file.getName());
// 接收文件监听
transferManager
.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(
FileTransferRequest request) {
try {
// 接收文件
IncomingFileTransfer transfer = request
.accept();
// 接收文件存放的位置
transfer.recieveFile(new File(PATH));
} catch (Exception e) {
Log.e("RecFile Ex In!",
e.getMessage());
}
}
});
} catch (XMPPException e) {
e.printStackTrace();
}
}
OK,大功告成。最后再附上两个demo的工程文件: