现在的位置: 首页 > 综合 > 正文

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

2011年07月21日 ⁄ 综合 ⁄ 共 10756字 ⁄ 字号 评论关闭

开源 IM 工具编译与环境搭建攻略
因为工作的缘故,需要考察一下目前比较流行的开源 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 系统设置

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

 

抱歉!评论已关闭.