基于XMPP的即时通讯系统
XMPP是一种基于XML的协议,它继承了在XML环境中灵活的发展性。因此,基于XMPP的应用具有超强的可扩展性。经过扩展以后的XMPP可以通过发送扩展的信息来处理用户的需求,以及在XMPP的顶端建立如内容发布系统和基于地址的服务等应用程 序。而且,XMPP包含了针对服务器端的软件协议,使之能与另一个进行通话,这使得开发者更容易建立客户应用程序或给一个配好系统添加功能。
XMPP是开源的中最受欢迎的即时通讯的应用协议.许多知名的国人所熟知的IM软件都是基于此协议或支持此协议.如:Google Talk/网易泡泡/MirandaIM等等…
而在国内本来最适合企业内部应用的IM系统应该是RTX的,可惜Tencent太讨厌,也狡猾狡猾的…免费的先让你用上瘾了,然后突然不让用了.实在是让人恨得牙根痒痒的.无奈只好另外再找免费的了,话说想找一个又免费功能又可以跟RTX媲美的还真不容易,我前前后后花了一两个月的时间,安装了无数的IM软件进行对比,最后无奈的发现,能做到比RTX更好或甚至于跟它差不多,居然还真没有.
本着少花钱多办事的原则,我把眼光转向了颇有好评的XMPP,XMPP里边做得最好的最著名的就是Openfire.
为此我特地分别在Windows/Centos/Freebsd里边分别安装Openfire来进行测试和试用.
Openfire在Windows下边安装起来非常简单,几乎不用怎么设置,也不用怎么等待,一下子就装好了.
Centos里边也不难,大致几个步骤就能安装完毕.
不过Freebsd里边稍微麻烦一点点,用ports去安装,系统会提示你需要去java的官网下载若干文件或补丁,然后放置到指定目录,再去安装,就也可以继续安装了.
总之,Openfire的安装还是很容易的.安装完成之后,可以打开浏览器,输入管理地址:
http://server:9090/
来进行设置.
Openfire支持使用MySQL做为管理数据库.也支持使用第三方认证数据库进行用户验证.以下可以做一个简单的介绍.
以企业内部应用为例,为每个部门建立一个组,然后使用公司的邮箱系统进行验证.
在Openfire的数据库RTC之外,另外建立一个rtc_auth的数据库,数据库中建立两个表,如下:
CREATE TABLE `Depts` ( `DeptName` char(20) COLLATE utf8_unicode_ci DEFAULT NULL, `DeptOrder` int(2) DEFAULT NULL, `DeptAdminUserName` char(20) COLLATE utf8_unicode_ci DEFAULT NULL, `DeptDescription` char(200) COLLATE utf8_unicode_ci DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE `Users` ( `UserName` char(25) COLLATE utf8_unicode_ci DEFAULT NULL, `UserDisplayName` char(50) COLLATE utf8_unicode_ci DEFAULT NULL, `Gender` char(2) COLLATE utf8_unicode_ci DEFAULT NULL, `DeptName` char(20) COLLATE utf8_unicode_ci DEFAULT NULL, `Position` char(30) COLLATE utf8_unicode_ci DEFAULT NULL, `UserEmailAddress` char(50) COLLATE utf8_unicode_ci DEFAULT NULL, `UserPassword` char(200) COLLATE utf8_unicode_ci DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
然后在rtc数据库中的ofProperty表中加入如下内容:
INSERT INTO `ofProperty` VALUES ('jdbcAuthProvider.passwordType', 'md5'); INSERT INTO `ofProperty` VALUES ('jdbcUserProvider.allUsersSQL', 'select UserName from Users'); INSERT INTO `ofProperty` VALUES ('jdbcProvider.driver', 'com.mysql.jdbc.Driver'); INSERT INTO `ofProperty` VALUES ('jdbcAuthProvider.passwordSQL', 'select UserPassword from Users where UserName=?'); INSERT INTO `ofProperty` VALUES ('jdbcUserProvider.emailField', 'UserEmailAddress'); INSERT INTO `ofProperty` VALUES ('jdbcUserProvider.loadUserSQL', 'select UserDisplayName,UserEmailAddress from Users where UserName=?'); INSERT INTO `ofProperty` VALUES ('jdbcUserProvider.nameField', 'UserDisplayName'); INSERT INTO `ofProperty` VALUES ('jdbcUserProvider.userCountSQL', 'select count(*) from Users'); INSERT INTO `ofProperty` VALUES ('jdbcUserProvider.usernameField', 'UserName'); INSERT INTO `ofProperty` VALUES ('provider.admin.className', 'org.jivesoftware.openfire.admin.DefaultAdminProvider'); INSERT INTO `ofProperty` VALUES ('provider.auth.className', 'org.jivesoftware.openfire.auth.JDBCAuthProvider'); INSERT INTO `ofProperty` VALUES ('provider.group.className', 'org.jivesoftware.openfire.group.JDBCGroupProvider'); INSERT INTO `ofProperty` VALUES ('provider.lockout.className', 'org.jivesoftware.openfire.lockout.DefaultLockOutProvider'); INSERT INTO `ofProperty` VALUES ('provider.securityAudit.className', 'org.jivesoftware.openfire.security.DefaultSecurityAuditProvider'); INSERT INTO `ofProperty` VALUES ('provider.user.className', 'org.jivesoftware.openfire.user.JDBCUserProvider'); INSERT INTO `ofProperty` VALUES ('provider.vcard.className', 'org.jivesoftware.openfire.vcard.DefaultVCardProvider'); INSERT INTO `ofProperty` VALUES ('xmpp.auth.anonymous', 'false'); INSERT INTO `ofProperty` VALUES ('jdbcGroupProvider.groupCountSQL', 'select count(*) from Depts'); INSERT INTO `ofProperty` VALUES ('jdbcGroupProvider.allGroupsSQL', 'select DeptName from Depts order by DeptOrder'); INSERT INTO `ofProperty` VALUES ('jdbcGroupProvider.descriptionSQL', 'select DeptDescription from Depts where DeptName=?'); INSERT INTO `ofProperty` VALUES ('jdbcGroupProvider.userGroupsSQL', 'select Depts.DeptName from Depts,Users where Depts.DeptName=Users.DeptName and Users.UserName=?'); INSERT INTO `ofProperty` VALUES ('jdbcGroupProvider.loadMembersSQL', 'select Users.UserName from Users,Depts where Depts.DeptName=Users.DeptName and Depts.DeptAdminUserName<>Users.UserName and Depts.DeptName=?'); INSERT INTO `ofProperty` VALUES ('jdbcGroupProvider.loadAdminsSQL', 'select Users.UserName from Users,Depts where Depts.DeptName=Users.DeptName and Depts.DeptAdminUserName=Users.UserName and Depts.DeptName=?');
这样,Openfire的服务器就可以使用以MD5加密密码的邮件系统验证的用户来进行登录了(嗯,这话有点儿拗口).
为了能得到近似或好于RTX的用户体验,我几乎试用了所有Wiki里边提到的免费的XMPP客户端.很遗憾居然没有一个真正合适的.最后我还是选择使用Openfire官方出品的Spark.
总的来说,Spark是XMPP的客户端中功能比较全面的一个,也很稳定,使用起来也很方便.常用的操作系统都有可以使用的客户端.
也说说它的一些问题吧.
它的设置太简单,简单到连聊天的字体都无法设置;
作为一款基于java应用的软件,它的界面没有普通Windows客户端使用起来那么舒服.在使用中文语言的时候,界面的字体比较怪且小;
spark不支持离线文件….不知道是XMPP不支持还是Spark不支持….反正就是不支持…可惜啊….
而且好象是XMPP客户端的一个通病,XMPP的群聊都比较麻烦,远没有RTX那样直接选一些人或一个组就可以群聊,XMPP要弄一个聊天室才可以;
RTX在聊天的时候截屏可以直接显示在聊天窗口中,Spark也有截屏功能,不过是把截屏内容文件的方式传送出去,不够直观;
Spark虽然是内置多语言的,不过它的简体中文的翻译比较怪异,怪异到我有相当的理由相信它是直接从繁体中文转过来的,现在官网的2.5.x版本甚至从中文切换到其它语言之后不能直接从程序界面切换回来.当然,最新的2.6rc已经修正了这个Bug.
目前已经在公司内使用了一段时间,除了聊天界面的字体丑得无法让人忍受之外,其它的还可以慢慢接受了…
总的来说,Openfire+Spark是目前比较合适的可以替代RTX之类的免费开源的IM解决方案.虽然还有不完善的地方,但希望日后能慢慢改善吧.