开源 IM 工具编译与环境搭建攻略

鉴客 发布于 2011/10/16 22:23
阅读 4K+
收藏 20

因为工作的缘故,需要考察一下目前比较流行的开源 IM 客户端与服务器。由于本人是搞 C++ 的,并且需要 IM 平台与现有的一款产品能够实现互联互通,所以将 IM 平台开发语言基本锁定在 C++ 或者 C# ,经过考察后发现一款优秀的 C# 语言开发的 IM 开源平台 agsXMPP 。并且采用了一款非常优秀的 JAVA 语言开发的 IM 客户端 spark 作为测试参考,服务器则采用了 openfire

这篇文章并不完全是我的原创,为了能够顺利的实现利用 agsXMPP 开源平台制作的客户端能够通过 openfire 服务器与另外一个客户端 spark 进行互联互通以及相互发送文件,我参考了 openfire 的网站相关内容,也在网上参考了其它一些解决方案,不过我将在整个过程中遇到的问题进行了一些总结和归纳,希望后来的同学们能够从这篇文章中得到帮助。

一、 搭建环境所需要的源码工程及其 SVN 地址

1.     agsXMPP SVN 地址是:

svn://svn.ag-software.de/agsxmpp/trunk

2.     openfire SVN 地址是:

http://svn.igniterealtime.org/svn/repos/openfire/trunk

3.     spark SVN 地址是:

http://svn.igniterealtime.org/svn/repos/spark/tags/spark_2_5_8

二、 编译 agsXMPP

编译 agsXMPP 很简单,只需要用 Visual Studio .NET 2008 打开相关工程文件并且编译即可,一般情况下不会出现什么错误。

但是由于客户端采用的是 agsXMPP 自带的实例 miniclient ,服务器端采用的是 openfire ,所以我们在编译源码的时候需要考虑到这两者之间的连通性,经过实际的验证发现,必须对 miniclient 中的相关源代码进行修改后方能顺利通信。

1.    认证协议问题

agsXMPP 在认证的时候,默认使用 DIGEST-MD5 ,但是在 openfire 下无法认证通过,改成 PLAIN 即可,也就是在 miniclient frmMain.cs XmppCon_OnSaslStart 方法中,将如下两行的注释去掉:

args.Auto = false;

args.Mechanism = agsXMPP.protocol.sasl.Mechanism.GetMechanismName(agsXMPP.protocol.sasl.MechanismType.PLAIN);

2.    Iq

Openfire 不支持 Iq 节带 to 的属性,所以在 agsXMPP 中发送 Iq 节的时候先 RemoveAttribute("to") 一下就行了,具体的就是找到 agsXMPP 源代码目录下的 sasl/saslHandler.cs 文件中,所有调用 SendIq 方法的前面,都加入如下语句:

bIq.RemoveAttribute("to"); 

好了经过修改后重新编译,我们就可以顺利的与 openfire 服务器进行身份认证并可以发送消息了。

三、 编译 spark

编译 spark 也很简单, spark openfire 的官方网站上提供了 SVN 下载,编译以及搭建调试环境的方法,我也顺便抄录到这里。

1.    安装 JDK

这个不用说了,注意版本,最少要 1.5 ,推荐使用最新的 1.6 版本

2.    安装 Eclipse3.3

a)         从官网下载 Eclipse 3.3 ( Java 开发者用的 )

b)         假设你把 eclipse 安装在 c:/program files/eclipse, 进入这个文件夹,为 eclipse.exe 创造一个桌面图标,右击这个图标,选择属性,打开属性对话框,在目标的输入框里,输入如下

"C:/Program Files/Eclipse/eclipse.exe" -vm "C:/Program Files/Java/jdk1.6.0/bin/javaw"

熟悉 eclipse 的都知道这是为 eclipse 指定使用哪个 Java VM

3.    eclipse 安装 Subversive 插件

a)         用上面建的图标打开 eclipse ,下面开始安装 Subversive 插件,由于我用的是英文版的 ecplipse 下面的菜单我都用英文。

b)         点击 Help::Software Updates::Find and Install...

c)         点击 Search for new features to install ,点 Next

d)         New Remote Site... 按钮

e)         name 的输入框里输入 Subversive ,并且在 URL 输入框里输入

http://www.polarion.org/projects/subversive/download/1.1/update-site             (最新的 Subversive 地址上 http://www.eclipse.org/subversive 查询)

f)          点击 Finish ,开始安装 Subversive eclipse 将搜索网站,并且在下一个窗口中显示你想安装的功能

选择安装 Subversive SVN Team Provider Plugin Subversive Client Libraries 下面所有的功能

g)         Next eclipse 开始安装过程,安装结束后重启 eclipse

4.    利用 svn 方式下载 spark 代码

a)         点击如下 Windows::Open Perspective::Other...

b)         弹出一个 “Open Perspective” 对话框,选择 “SVN Repository Exploring” ,单击 OK

c)         这是 eclipse 界面发生变化,在左边的 “ SVN Repositories” 面板上,右击鼠标选择 New::Repository Location...

d)         “New Repository Location” 的位置输入上面提供的 SVN 地址,单击 “Finish”

e)         SVN Repositories 面板上,会发生变化,展开它,找到 spark 的选项,右击 spark 下面的 trunk 项,选择 “Check Out” ,下载 spark 的代码。

f)          下载完成后,选择 Window::Open Perspective::Java ,在 Project Explorer 面板上,   看到 Spark 项目,删掉它,在弹出来的对话框中选择 “Do not delete contents”  在工作目录下面找到 spark 文件夹,里面就是 spark 的源代码。其实我们可以通过打包下载源码的方式来获得源码,但那样我们就无法及时跟踪 spark 最新的源码升级,同时有了版本管理,还可以在修改 spark 的过程中,方便的比较与原版的差异,所以还是强烈建议大家采用 SVN 方式下载。

5.    创建 Spark 项目

a)         点击 Window::Open Perspective::Java 菜单

b)         Project Explorer 窗口中 , 如果有 spark 这个项目 , 把它删了 , 删除时 , 会问你要不要删除文件 , 选择不要 .

c)         选择 File::New::Project..., 再选择 Java::Java Project, New Java Project 窗口选择 "Create project from existiing source", 然后把 spark 文件所在的文件夹加进去 .

d)         "project name" 中输入 spark, 要和文件夹的名字相同 .

e)         Finish.

6.    生成 Spark

a)         点击 Window::Show View::Ant

b)         右击 Ant 面板 , 选择 Add Buildfiles

c)         展开 spark::build 文件夹 , 选择 build.xml, 点击 "OK"

d)         Ant 面板 , 展开 Spark, 双击 "release", 等一段时间 , 会提示 "Build Successful".

7.    Create Project Builder

a)         点击 Run::Open Debug Dialog..., 出现 "Run" 窗口

b)         选择 "Java Application", 点击 "New" 按钮 .

c)         "Main" 标签页 , New_configuration 换成 Spark 或其它的这个无所谓 .

d)         点击 Project::Browse 按钮 , 选择 Spark, 再点 OK.

e)         点击 Main class::Search 按钮 , 选择 main 所在的类 Startup-org.jivesoftware.launcher, 再点击 OK

f)          建议勾选 Stop in main.

g)         点击 Classpath 标签页 , 选择 User Entries , 使得 Advanced.. 按钮变的可用 .

h)         点击 Advanced 按钮 . 在弹出来的 Advanced Options 窗口 , 选择 Add Folders, 再点 OK, Folder Selection 窗口选择 spark::src::resources 文件夹 , 点击 OK

i)          选择 Common 标签页 , 勾选 Debug,Run 前面的框

j)          点击 Apply, 再点击 Close

8.    Run/Debug

点击 Run::Open Run Dialog.., 在弹出的对话框选择 Spark, 然后点 Run 就行了 .

9.    特别需要注意的是,我在实际的编译当中发现, GSSAPIConfiguration.java 文件被放到了 src/java 目录下,导致 ant 编译失败,报告找不到 GSSAPIConfiguration 类错误,其实这个源码应该被移动到(是移动而不是拷贝) src/java/org/jivesoftware 目录下,这样就可以顺利编译了。

四、 编译 openfire

1.    Install JDK

这个不用说了,注意版本,最少要 1.5 ,推荐使用最新的 1.6 版本 .

2.    安装 Eclipse3.3

a)         从官网下载 Eclipse 3.3 ( Java 开发者用的 )

b)         假设你把 eclipse 安装在 c:/program files/eclipse, 进入这个文件夹,为 eclipse.exe 创造一个桌面图标,右击这个图标,选择属性,打开属性对话框,在目标的输入框里,输入如下

"C:/Program Files/Eclipse/eclipse.exe" -vm "C:/Program Files/Java/jdk1.6.0/bin/javaw"

熟悉 eclipse 的都知道这是为 eclipse 指定使用哪个 Java VM

3.    eclipse 安装 Subversive 插件

a)         用上面建的图标打开 eclipse ,下面开始安装 Subversive 插件,由于我用的是英文版的 ecplipse 下面的菜单我都用英文。

b)         点击 Help::Software Updates::Find and Install...

c)         点击 Search for new features to install ,点 Next

d)         New Remote Site... 按钮

e)         name 的输入框里输入 Subversive ,并且在 URL 输入框里输入

http://www.polarion.org/projects/subversive/download/1.1/update-site             (最新的 Subversive 地址上 http://www.eclipse.org/subversive 查询)

f)          点击 Finish ,开始安装 Subversive eclipse 将搜索网站,并且在下一个窗口中显示你想安装的功能

选择安装 Subversive SVN Team Provider Plugin Subversive Client Libraries 下面所有的功能

Next eclipse 开始安装过程,安装结束后重启 eclipse

4.    利用 svn 方式下载 Openfire 代码

g)         点击如下 Windows::Open Perspective::Other...

h)         弹出一个 “Open Perspective” 对话框,选择 “SVN Repository Exploring” ,单击 OK

i)          这是 eclipse 界面发生变化,在左边的 “ SVN Repositories” 面板上,右击鼠标选择 New::Repository Location...

j)          “New Repository Location” 的位置输入 http://svn.igniterealtime.org/svn/repos ,单击 “Finish”

k)         SVN Repositories 面板上,会发生变化,展开它,找到 openfire 的选项,右击 openfire 下面的 trunk 项,选择 “Check Out” ,下载 openfire 的代码。

下载完成后,选择 Window::Open Perspective::Java ,在 Project Explorer 面板上,   看到 openfire 项目,删掉它,在弹出来的对话框中选择 “Do not delete contents”  在工作目录下面找到 openfire 文件夹,里面就是 openfire 的源代码。

5.    创建 Openfire 项目

f)          点击 Window::Open Perspective::Java 菜单

g)         Project Explorer 窗口中 , 如果有 Openfire 这个项目 , 把它删了 , 删除时 , 会问你要不要删除文件 , 选择不要 .

h)         选择 File::New::Project..., 再选择 Java::Java Project, New Java Project 窗口选择 "Create project from existing source", 然后把 Openfire 文件所在的文件夹加进去 .

i)          "project name" 中输入 Openfire, 要和文件夹的名字相同 .

j)          如果“ Open Associated Perspective ”窗口打开,选择“ Yes ”;

k)         Finish.

6.    生成 Openfire

e)         点击 Window::Show View::Ant

f)          右击 Ant 面板 , 选择 Add Buildfiles

g)         展开 openfire::build 文件夹 , 选择 build.xml, 点击 "OK"

h)         Ant 面板 , 展开 Openfire XMPP Server , 双击 " openfire ", 等一段时间 , 会提示 "Build Successful".

7.    Create Project Builder

k)         点击 Run::Open Debug Dialog..., 出现 "Run" 窗口

l)          选择 "Java Application", 点击 "New" 按钮 .

m)       "Main" 标签页 , New_configuration 换成 Openfire 或其它的这个无所谓 .

n)         点击 Project::Browse 按钮 , 选择 openfire , 再点 OK.

o)         点击 Main class::Search 按钮 , 选择 main 所在的类 ServerStarter - org.jivesoftware.openfire.starter , 再点击 OK

p)         建议勾选 Stop in main.

q)         点击 Arguments 标签页,在 VM 参数框中输入 -DopenfireHome="${workspace_loc:openfire}/target/openfire"

r)          点击 Classpath 标签页 , 选择 User Entries , 使得 Advanced.. 按钮变的可用 .

s)         点击 Advanced 按钮 . 在弹出来的 Advanced Options 窗口 , 选择 Add Folders, 再点 OK, Folder Selection 窗口选择 openfire::src::i18n 文件夹 , 点击 OK

t)          再次点击 Advanced->Advanced Options-> Add Folders->Folder Selection 窗口选择 openfire::src::resources::jar 文件夹 , 点击 OK

u)         再次点击 Advanced->Advanced Options-> Add Folders->Folder Selection 窗口选择 openfire::build::lib::dist 文件夹 , 点击 OK

v)         选择 Common 标签页 , 勾选 Debug,Run 前面的框

w)        点击 Apply, 再点击 Close

8.    Run/Debug

点击 Run:: Run History::Openfire 以及 Run::Debug History::Openfire ,然后点 Run/Debug 就行了。

五、 编译过程中遇到的问题及解决方案

1.    解决 openfire 在使用 MySQL 数据库后的中文乱码问题

首先要保证你为 openfire 创建的数据库编码是 utf8 的,建表语句如下:

create database openfire default character set utf8 default collate utf8_general_ci;

当你原来就创建好数据库时,你可以用:

alter database openfire default character set utf8 default collate utf8_general_ci;

其次,在初始化 openfire 数据库,即第一次配置 openfire 服务器时,在连接数据库那里的连接串要加入字符编码格式,必须在连接里增加 UTF8 的编码要求,连接字符串设置如下:

jdbc:mysql://127.0.0.1:3306/openfire?useUnicode=true&characterEncoding=utf8

如果已经安装完成,这个配置也是可以改动的,直接到 openfire 的安装目录下,找到 conf/openfire.xml 这样一个文件,打开找到如下的 XML 节,修改其中的 serverURL 即可

<database>

<defaultProvider>

<driver>com.mysql.jdbc.Driver</driver>

<serverURL>jdbc:mysql://127.0.0.1:3306/openfire?useUnicode=true&amp;characterEncoding=utf8</serverURL>

2.    agsXMPP openfire 之间实现文件传输问题

agsXMPP 的实例 miniclient 提供了两种客户端 - 客户端的文件传输机制,一种是 P2P 的直接传输技术,也就是传输的接收方打开一个侦听端口(本例为 1000 ),发送方直接与接收方的侦听端口建立 socket 连接,这种方式的好处是, 1 )建立 P2P 的直接通信,可以最大化利用网络带宽,文件发送效率最高, 2 )降低了对中转服务器的压力, 3 )软件架构比较简单容易实现。不过这种方式也存在很多问题, 1 )发送和接收方必须在同一个子网当中,要能够相互寻址到, 2 )如果发送或者接收方分别处于 NAT 网络或者防火墙的后面,那么这种连接将无法建立, 3 )在接收方需要打开侦听端口,可能导致本机防火墙或者杀毒软件的禁止。

另外一种是通过 file transfer proxy 机制在两个相互无法连通的主机之间的文件传输机制。由于两个客户端都可以连接 openfire 服务器(可能的情况是, 1 )客户端 A 和客户端 B 都连接在服务器 B1 上, 2 )客户端 A 连接服务器 S1 ,客户端 B 连接另外一个服务器 B2 ),无论哪种情况,客户端 A B 都应该可以连接到一个代理服务器上(也可能这个代理服务器就在 B1 或者 B2 上),因此我们完全可以在 A B 之间建立一个文件传输代理,发送方 A 将文件发送到代理服务器上,而 B 则从代理服务器读取文件。

文件传输代理一般可以采用 bytestream SOCKS5 代理)或者 proxy65 代理技术。目前有很多开源的 SOCKS5 代理和 proxy65 代理服务器可用,不过 openfire 内置了一个 SOCKS5 代理服务器,我们完全可以利用它来完成文件代理传输任务。

如果要用 openfire 做文件传输代理,需要做如下配置:

1)     openfire 配置域名

使用 openfire 需要配置机器的域名。如果局域网内没有安装域服务器,则需要手工为机器配置域名,打开 C:/WINDOWS/system32/drivers/etc/hosts 文件,增加一新行:

127.0.0.1                         im.openfire.com  (用户根据自己的需要可配置称别的名字,但最好符合带 . 的域名格式)

127.0.0.1                         proxy.im.openfire.com

其他机器使用域名访问 openfire, 也需要在 C:/WINDOWS/system32/drivers/etc/hosts 中指定 bzwang.tzsoft.com 对应的 ip 地址,假设安装 openfire 的主机 IP 192.168.1.10, hosts 文件中应增加一新行 :

192.168.1.10                    im.openfire.com

通过这种方式指定主机域名,建议安装 openfire 的机器配置静态 ip 地址以免 ip 发生改变。

2)     配置 openfire 文件代理

配置好 openfire 的域名后,可以通过 http 访问其管理界面,在浏览器中输入: http://im.openfire.com:9090 即可登陆管理界面。

openfire 的管理界面中,选择 “System Properties (系统属性),将属性 xmpp.domain 值改为 im.openfire.com ,另外添加一个属性 xmpp.proxy.transfer.required ,将其值设置为 false

点击 “Server Settings (服务器设置)标签页,点击File Transfer Settings (文件传输设置),将其属性设置为 “Enable” ,对应的端口设置为 “7777”.

如果要在不同的传输代理服务器之间传输文件,还需要在 “Server Settings (服务器设置)标签页中,点击 “Server to Server (服务器到服务器),将属性设置为 “Enable” 并将侦听端口设置为 “5269”

重启 openfire 服务器。

3)     修改 miniclient 源码,设置传输代理服务器

Miniclient 源代码中负责文件传输的源码文件是 frmFileTransfer.cs ,在文件的开头有一个常量字符串定义了所用到的传输代理名称如下:

const string PROXY = "proxy.im.openfire.com" ;

注意一定要将 PROXY 指向 proxy.im.openfire.com ,因为 XMPP service discovery 规定了文件传输代理的域名规则,前面一定要加 “proxy” ,否则无法解析。另外也不能直接用传输代理的 IP 地址,我浪费了很多时间才找到这个问题的。

另外,再检查一下 frmFileTransfer.cs 中的 SendStreamHosts 方法,找到如下几行:

string hostname = System .Net .Dns .GetHostName ();

System .Net .IPHostEntry iphe = System .Net .Dns .Resolve (hostname );

    for (int i = 0; i < iphe .AddressList .Length ;i ++)

    {

               Console .WriteLine ("IP address: {0}" , iphe .AddressList [i ].ToString ());

          //bsIq.Query.AddStreamHost(m_XmppCon.MyJID, iphe.AddressList[i].ToString(), 1000 );

}

bsIq .Query .AddStreamHost (new Jid (PROXY ), PROXY , 7777 );

这几句的意思是,首先将本机地址列表加入流主机列表中,并在 1000 端口进行侦听,同时将代理服务器加入流主机列表,并在 7777 端口侦听,如果将注释取消,那么客户端之间的文件传输将优先使用 P2P 模式,如果无法连通才使用代理模式,由于我们这里主要演示的如何使用代理,因此将 P2P 的代码注释掉了,实际的使用过程中,可以将其打开。

通过上述设置,我们可以实现两个 miniclient 之间, miniclient spark 客户端之间的文件收发,而且在内网的环境当中,无论是 P2P 模式还是代理模式,发送大文件时效率都是很高的。

六、 我采用 agsXMPP 开发的一款商用的 IM 客户端

在学习的过程中,我基本了解了 agsXMPP 的工作原理,并且利用该平台花了三个月的时间,制作了一款目前基本可以用在我产品当中的 IM 客户端,下面就是该软件的一些截图,已经能够实现单人聊天,群组聊天, P2P 发送文件以及服务器中转发送文件等基本功能,后面有空的话还会考虑加入语音聊天等功能。

1 主界面


2 单人聊天模式

3 多人群组聊天模式


4 查看历史记录

 

5 发送文件

6 系统设置

由于这个项目目前只有我一个在做,包括美工在内的相应配置都没有,所以感觉界面还是很粗糙,希望以后能够将这个项目继续做下去,能够做成一个不错的东西。

加载中
0
G.
G.
发了3个 .lnk 的文件? 太强了!
0
z
zhengliit

你做的这个商务通话的能发源码吗,我最近在搞agsxmpp,菜鸟,希望学习更多啊

0
akee
akee

开源IM,推荐一个entboost云通讯平台:
entboost是跨平台、跨应用的实时通讯开放平台,今天发布第一个开源版本(r172beta),主要功能支持文本、表情,图片,文件共享,语音视频,云盘,群组,离线消息等功能,开放客户端源码,支持PC SDK API,REST API等接口,支持对接企业内部各种业务系统;

恩布网络致力于提供跨终端、跨应用的信息实时互通开源解决方案;目前Android安卓版本、IOS版本,以及基于REST API开发的900在线客服已经在内测,近日会对外开放,敬请关注!

详细介绍地址:http://www.oschina.net/p/entboost

恩布云通讯技术论坛:http://forum.entboost.com/forum.php

0
范拾沙
范拾沙

Github上有好多开源im呀,找到一个大厂开源出来的,应该是去哪儿网内部使用的沟通工具,看着挺靠谱的。https://github.com/qunarcorp/qtalk

返回顶部
顶部