Libjingle学习
综合网上资料和个人理解,主要分为以下几大部分: 1. libjingle概念 2. libjingle 知识点
3. libjingle 编译(源代码的编译和一个例子myjingle的编译) 4. libjingle 程序创建(一个简要的过程) 5. libjingle 知识点扩展(一些重要概念) 6. libjingle底层的主要代码理解
文档还未完成,每一部分都有待进一步学习和研究后再修改。
Libjingle概念:
Libjingle是一个开发库,由c++的源码和文档组成,这些文档可以使你设计应用程序,通过一个网络,能够连接和交换数据。值得注意的是这个源码需要一些外部的依赖,例如: 声音的聊天例子依赖于Linphone或者GIPS,这取决于你自己的平台。这个源码包含网络和代理服务器的协商层,XML的分析层,一个STUN的服务器,所有的源码需要发起一个连接和交换数据在两台电脑之间。通过使用ICE(Internet Communication Engine)的机制,STUN服务器,以及交换UDP或者TCP的数据包,这些连接的源码能够强行穿越NAT(网络地址转换)和防火墙的装置。你可以使用提供的源码,或者扩展它,以适合你自己特定的需要,根据Berkeley-style的许可。
Jingle和libjingle的区别:
Libjingle大概和jingle XMPP 扩展在同一时间被建立。Libjingle的团队建立了他们自己的协议去处理回话协商,后来和使用标准化的jingle(基于XMPP的标准)一起工作。尽管,jingle和libjingle是非常相似的,但是它们是不一样的,而且不能共同使用。现在libjingle的源码版本依然使用原始的网络协议,跟以前的稍微有些不同,而且无法兼容jingle的规范。不过它还是足够的接近jingle,所以学习jingle的说明书是值得的。类似的“接近但不是一样”,libjingle的视频内容描述(早期的jingle的视频内容描述格式XEP-0167),ICE的传输描述(早期的jingle的ICE传输XEP-0176),以及流的UDP描述(早期的jingle流UDP的传输描述XEP-0177).
学习libjingle的条件:
首先得熟悉XMPP协议,普通的网络概念,和C++。除此以外,它能帮助熟悉jingle提出的扩展(XEP-0166),和其他的相关的扩展。
Libjingle 知识点:
1.Login handler是所有东西的缘起. 登陆服务器之后生成一个Login handler.
2. XmppPump Libjingle把XmppPump作为Login handler. XmppPump,注意Pump,顾名思义就是一整个系统的动力源.由这个pump源源不断地把Message送给等待接受这些Message
的地方.
3.XmppClient是在XmppPump的控制下,可以认为它是XmppPump的一部分.他负责从网上接受和发送Xmpp格式的消息.
4.XmppEngine是协助XmppClient工作的.可能是为它提供一些Utility API.diagram上面的三个圆环套圆环其实是包含关系.
5.stanza的原本的意思是英文诗里面的一段.在这里的意思是一个XMPP消息,有两种stanza,一种是正常的Message,一种是做negotiating用的.
6.task 是XMPP任务对象,由XmppPump管理,以Task结尾的类都是线程类。Task订阅了自己感兴趣的消息.来了消息就Pump到对应的Task里面去了.
7.PresencePushTask.首先解释一下Presence,这个单词是指这个账号目前的状态,是在线,还是下线还是离开.PresencePushTask主要是为了接收在线好友状态的线程.
8.PresenceOutTask是起把自己的状态提交出去的作用,里面有一个变量叫stanza_.它是用来存储将要发送的消息的指针的.Send函数实际上是把要发送的值赋上.
9.JingleInfoTask是专门管STUN服务器和中继传输服务器的.
10.SessionClient是沟通application和p2p模块的中间桥梁。比如,再共享文件的例子中。SessionClient就被派生成FileShareSessionClient。要传输的文件列表之类的东西都是由他控制.
11. Session 当一个新会话请求接收或发送连接请求,将会创建一个新的Session对象,Session用来监视着来自对方的请求,并调用Session::Accept或Session::Reject来接受或拒绝请求,Session会把stanza的到来事件提醒SessionClient,Session类型被定义在stanza的一个Unique ID中;每个Session都管理着多个Transport 对象。
12. SessionManager管理着Session,如果是进入的连接,SessionClient直接把这个连接给SessionManager,由SessionManager调用SessionClient::OnSessionCreate来创建一个新的Session;如果是出去的连接,session wrapper显示创建一个Session.在文件共享例子中这个session wrapper就是FileShareSession
13.Resource Allocator/Resource Classes是控制文件传输或者语音传输等等资源的。他们需要从Session中获得TransportChannel进行事实上的数据传输。
14. Channel,有两种channel,一种是negotiation channel,一种是transport channel。
15.P2PTransport里面持有多个P2PTransportChannel。这些都是候选Channel。按照ICT,
这些Channel事所有源IP和目的IP的组合。P2P传输是从这一堆Channel里面选出一个最好的。
16.PortAllocator事专门响应P2PTransport的请求生成所需要的端口的。
17.Thread,一种是signaling thread,也就是主管XMPP消息处理的主线程。另外一种是work thread,也叫channel thread。主要用来进行P2P数据传输的。libjingle都用talk_base::Thread来包含一个Thread;Thread中的Start()和Run(),Start是新起一个线程,马上开始运行,Run是在本身这个线程里面开始消息循环,是被阻塞的。
18.ThreadManager 管理着Thread,每个新建的Thread都要加进ThreadManager(在Thread构造中调用ThreadManager::add())
19.MessageQueue 要发消息的Thread要继承MessageQueue;
20.MessageQueueManage 管理着MassageQueue。
21.MessageHandler要收消息的对象要实现MessageHandler的OnMessage(),如果有消息传入,接受消息的对象要调用OnMessage()
22.connection一个connection对象有一个Port类,Port类是由PortAllocator分配的。
23.候选IP地址 有三种(1)本机IP地址。(2)NAT外面看到的地址和端口。(3)中继服务器的IP。
24.JingleInfoTask和google的STUN服务器联系主要接收Jingle相关的一些消息,比如外网地址阿,中继服务器地址阿之类的
25.buzz是XMPP相关的namespace.
26.cricket是P2P相关的namespace.
27.scoped_ptr是一个智能指针(smart pointer).里面的reset是重新给这个指针负值,并且把原来指向的内存释放掉.
28.Tls Lbjingle采用了Tls来记录线程信息.放在Tls里面的是Thread对象.这个对象记录了该线程的信息.
29.stanza被SessionManagerTask发送到SessionManager中.SessionManager又调用对应的Session来处理这些stanza.如果在Sesssion发现传进来的stanza是用来商议建立p2p连接的.就把这个stanza传送给P2PTransportChannel.其他的stanza就传送给订阅了这种stanza的Task,也就是其他消息处理线程.
Libjingle的编译
一、libjingle源码的编译
1. 首先下载
libjingle
的源代码,在如下地址:
https://sourceforge.net/projects/libjingle/,我下载的是libjingle-0[1].4.0版本 2. 然后安装Visual C++ 2005 Express Edition,具体下载地址,google一把,非常多的链接。
3. 安装好Visual C++ 2005 Express Edition后,需要安装platform SDK,在如下
地
址
中
下
载
:
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm,按照提示说明安装platform SDK。
4. 在sourceforge.net上下载Expat XML Parser ,地址如下:http://sourceforge.net/project/downloading.php?group_id=10127&use_mirror=nchc&filename=expat_win32bin_2_0_0.exe&33064126,我下载的是2.0.0版本,安装完成后,需要到Visual C++ 2005 Express Edition版本中更新选项,Tools-》Options-》Projects and Solutions-》VC++ directories
Library files: C:\\Expat-2.0.0\\StaticLibs Include files: C:\\Expat-2.0.0\\Source\\Lib
Include files: C:\\Program Files\\Microsoft SDK\\include 5. 编译工程,仍旧有以下提示:
------ Build started: Project: libjingle, Configuration: Debug Win32 ------ Compiling...
gipslitemediaengine.cc
d:\\p2p\\xmpp\\libjingle\\libjingle-0[1].4.0\\libjingle-0.4.0\\talk\\session\\phone\\gipslitemediaengine.h(33) : fatal error C1083: Cannot open include file: ''talk/third_party/gips/Interface/GipsVoiceEngineLite.h'': No such file or directory
channelmanager.cc
d:\\p2p\\xmpp\\libjingle\\libjingle-0[1].4.0\\libjingle-0.4.0\\talk\\session\\phone\\gipslitemediaengine.h(33) : fatal error C1083: Cannot open include file: ''talk/third_party/gips/Interface/GipsVoiceEngineLite.h'': No such file or directory
winfirewall.cc
d:\\p2p\\xmpp\\libjingle\\libjingle-0[1].4.0\\libjingle-0.4.0\\talk\\base\\winfirewall.cc(29) : fatal error C1083: Cannot open include file: ''netfw.h'': No such file or directory
Generating Code... Build log
was
saved
at
\ldLog.htm\
libjingle - 3 error(s), 0 warning(s)
6. 前面两个编译错误,可以通过下载GipsVoiceEngineLite包完成,但是现在GipsVoiceEngineLite是需要许可才能下载,由于项目中暂时不需要语音功能,所以在项目
中去掉了session\\phone子项目,前面两个编译错误消失。
7. 在http://www.codeproject.com/KB/winsdk/WinXPSP2Firewall.aspx中下载WinXPSP2Firewall_demo文件包,将icftypes.h和netfw.h拷贝到\\talk\\base目录下,在base工程中加入icftypes.h文件。
8. 重新编译,libjingle - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========大功告成,libjingle编译成功。
二、myjingle的编译
1.MyJingle简介
MyJingle只是一个LibJingle的Win/MFC的DEMO.
简单来说,MyJingle利用LibJingle和一个叫Speex的音频编码,组成一个P2P的语音通讯软件.当然他还依赖XMPP作为服务端进行一些连接通讯.详细介绍可以上官方网站.
2.准备工作
安装VC 8(在VS2005里面).
安装Microsoft DirectX SDK (February 2006)
安装Microsoft Platform SDK for Windows Server 2003 R2 3.设置,编译
用VC打开MyJingle.sln,需要先设置两个lib和inclue 工具-选项-项目和解决方案, 选择\包含文件\添加
E:\\Microsoft DirectX SDK (February 2006)\\Include
E:\\Microsoft Platform SDK for Windows Server 2003 R2\\Include 选择\库文件\添加
E:\\Microsoft DirectX SDK (February 2006)\\Lib\\x86
E:\\Microsoft Platform SDK for Windows Server 2003 R2\\Lib
好了,现在可以编译通过了.
但是会提示LIBCMT库冲突.
然后在MyJingle项目右键-属性-配置属性-链接器-输入,\忽略特定库\那里输入LIBCMT
4.修改
MyJingle只能连上Gmail,其他XMPP的服务端连不上,需要修改一下代码.
修改 saslplainmechanism.h文件
virtual XmlElement * StartSaslAuth() { std::string sUser;
int i = user_jid_.Str().find(\ sUser = user_jid_.Str().substr(0,i);