XMPP协议--即时通讯工具实现原理_第1页
XMPP协议--即时通讯工具实现原理_第2页
XMPP协议--即时通讯工具实现原理_第3页
XMPP协议--即时通讯工具实现原理_第4页
XMPP协议--即时通讯工具实现原理_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、XMPP协议-即时通讯工具实现原理(服务器,客户端)分类:C# jabber/XMPP 2010-12-10 21:26 292 人阅读 评论(0)收藏 举报第一篇:.net平台基于XMPP协议的即时消息服务端简单实现昨天抽空学习了一下 XMPP,在网上找了好久,中文的资料太少了所以做这个简单的例子,今天才完成。公司也正在准备开发基于XMPP协议的即时通讯工具所以也算是打一个基础吧!如果你还没有了解过 XMPP请先阅读附录中链接的文章,本实例是基agsXMPP上开发的,agsXMPP是C#写的支持开源XMPP协议软件,我们可以在agsXMPP上快速构建自已的即时通讯平台,我的这个例子只是修改了

2、服务器端,因为 a gsXMPP本身自带的服务器端没有实现聊天功能、签名和登录密码认证。服务器端XmppSeverConnection类事件/在流开始时触发,一般是最初的响应流streamParser.OnStreamStart +=new StreamHandler(streamParser_OnStreamStart);/在流结束时触发,一般是发送</stream:stream> 并关闭套接字连接 streamParser.OnStreamEnd += new StreamHandler(streamParser_OnStreamEnd);/在接收到流结点时触发,这是用得最多的

3、,常用的<message> 消息,<Presence>出席消息,< IQ>请求应答消息都在这里处理streamParser.OnStreamElement +=new StreamHandler(streamParser_OnStreamElement);/此处处理大部份的消息,包括消息路由private void streamParser_OnStreamElement( object sender,Node e)(Console.WriteLine("OnStreamElement: " + e.ToString();if (e.Ge

4、tType() = typeof (Presence)(/ 路由 presences 节)else if (e.GetType() = typeof (Message)(/ 路由 messages 节)else if (e.GetType() = typeof (IQ)(/处理IQ节)/ <summary>/ IQ节处理函数/ </summary>/ <param name="iq"> . </param> private void ProcessIQ(IQ iq)(if (iq.Query.GetType() = typeo

5、f (Auth)(Auth auth = iq.Queryas Auth;this .Username = auth.Username.ToString();switch (iq.Type)(case IqType. get :iq.SwitchDirection();iq.Type = IqType.result;auth.AddChild(new Element("password");auth.AddChild(new Element("digest");Send(iq);break ;case IqType. set :/进行登录认证if (Ac

6、countBus.CheckLogin(auth.Username, auth.Digest,this .SessionId)(iq.SwitchDirection();iq.Type = IqType.result;iq.Query =null ;Send(iq);Console.WriteLine(auth.Username + "登录了 "+ "登录时间:"+ System.DateTime.Now.ToString();else(/登录失败返回错误信息iq.SwitchDirection();iq.Type = IqType.error;iq.Q

7、uery =null ;Send(iq);break ;else if (iq.Query.GetType() = typeof (Roster)(ProcessRosterIQ(iq);/ <summary>III处理IQ节的杂项数据./ </summary>/ <param name="iq"> The iq. </param>private void ProcessRosterIQ(IQ iq)(if (iq.Type = IqType. get)(/发送IQ节的杂项数据/这里我用来下载好友列表iq.SwitchDire

8、ction();iq.Type = IqType.result;List< string > friendList = new List< string >();friendList = AccountBus.GetFriendName(this .username);foreach (string str in friendList)(RosterItem ri =new RosterItem();ri.Name = str.Trim();ri.Subscription = SubscriptionType.both;ri.Jid = new agsXMPP.Jid(

9、str.Trim() + "localhost");ri.AddGroup("localhost");iq.Query.AddChild(ri);)Send(iq);)服务器端开启监听5222端口while (running)(/ /allDone.Reset();/ Start an asynchronous socket to listen for connections.Console.WriteLine("等待连接.");listener.BeginAccept(new AsyncCallback(AcceptCallback

10、), null );/ /等待客户端连接allDone.WaitOne();)如果收到客户端请求就异步调用AcceptCallback初始化套接字连接 ,并为客户端建立一个通信线程,新建初始化套接字连接采用异步调 用读取套接字信息public XmppSeverConnection(Socket sock)this () (m_Sock = sock;m_Sock.BeginReceive(buffer, 0, BUFFERSIZE, 0,new AsyncCallback(ReadCallback), null );m_Sock.SendTimeout = 100; 客户端与服务器端的交互过

11、程 1客户端异步向服务器端发送连接请求 <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http:/etherx.jabber. org/streams' version='1.0' xml:lang='en'>2服务器端收到请求,初始化回应流,并随机生成一相SessionID <stream:stream xmlns:stream="/streams&quo

12、t;from="localhost" id="30e3b8c0">3等待服务器返回消息后客户端发送用户名(由于在客户端采用了异步调用 方式,所以UI界面感觉不到等待)<iq xmlns="jabber:client" id="agsXMPP_1" type="get" to="localhost"> <query xmlns="jabber:iq:auth"><username>test</username&

13、gt;</query></iq>4服务器端收到用户名等待用户提供密码<iq xmlns="jabber:client" from="localhost" type="result" id="agsXMPP_1"><query xmlns="jabber:iq:auth"><username>test</username><password/><digest /></query></i

14、q>5客户端提供加密后的密码<iq xmlns="jabber:client" id="agsXMPP_2" to="localhost" type="set"> <query xmlns="jabber:iq:auth"><username>test</username> <digest>e66557d2b67256bf7e9b317a51b6101674a56b5e</digest> <resource>

15、;MiniClient</resource></query></iq>6服务器端从数据库验证用户名和密码,并返回结果 iq xmlns="jabber:client" from="localhost" type="result" id="agsXMPP_2" />7如果返回错误,客户端提示并终断连接,否则客户端发送响应数据8服务器端返回数据 9客户端发送状态,10服务器收到状态,发送IQ节并通知其它用户.项目解决万案和斐图解决方案X1PP制心W个顼目)寻 XMPPServe

16、rf Propertiesf> 鼻引用-J Business兰)AccountBus.cs哟 FriendBus.es4 Q DataAcces哨 AccountDaLcsFriendDal.cs4 _i Mode!'少 AceountModel.esFriendModel.esflpp.conriJPragram.es5essionld.esXmppServernCSKmpp5er verConnettion. csAccountBusAccountDa!CigAccountModelCIk:FrrendBusXmppScrvcrKnippcverConn.FtiendDdl孕

17、(JanJFriendModel c_|gProgramclassSessio诚 d1附录:推荐使用Pandion作为客户端服务器端下载客户端下载agsXMPP源码下载XMPP RFC 3920 可扩展消息出席协议jabber 官方网站第二篇:基于XMPP协议的服务器端 文件互传的简单实现昨天我们讲了客户端实现用户互发消息的原理,今天我们继续学习一下基于XMPP协议的文件传输,首先我们假设用户已经登录,这里我们假设 Clinet Send 对Clinet Receive发送文件,这里记录了 Clinet Send的发送和接收XML流记录1、发送请求表示要向 Clinet test 发送文件,并

18、发送文件大小和文件名SEND:< iq xmlns ="jabber:client" id ="agsXMPP_6" to ="Receive localhost/" type ="set">< si xmlns ="/protocol/si"profile ="/protocol/si/profile/file-transfer" id ="b3b5f49c-8a94-49e2-90

19、8a-3de694b98af0”>< file xmlns ="/protocol/si/profile/file-transfer"name ="MiniClient.exe.config" size ="382">< range ></ file >< feature xmlns ="/protocol/feature-neg">< x xmlns ="jabber:x:data

20、" type ="form">< field type ="list-single" var ="stream-method">< option >< value > /protocol/byReceive reams</ value ></ option ></ field ></ x></ feature ></ si ></ iq>2、Receive收到Send发

21、实来的请求后,发送出响应流RECV:< iq xmlns ="jabber:client" to ="Sendlocalhost" type ="result" id ="agsXMPP_6">< si xmlns ="/protocol/si"id ="b3b5f49c-8a94-49e2-908a-3de694b98af0">< feature xmlns ="/pro

22、tocol/feature-neg">< x xmlns ="jabber:x:data" type ="submit">< field var ="stream-method">< value > /protocol/byReceive reams</ value ></ field ></ x></ feature ></ si ></ iq>3、Send收到Receive 愿

23、意接收的响应后,发出如下 XML流SEND:< iq xmlns ="jabber:client" id ="agsXMPP_7" to ="Receivelocalhost" type ="set">< query xmlns ="/protocol/bySendreams"sid ="71f1b875-4d84-429c-b39d-7dabcd400f3d">< streamhost jid ="Se

24、ndlocalhost/MiniClient" host ="localhost" port ="1000"/>< streamhost jid ="proxy.ag-software.de" host ="proxy.ag-software.de" port ="7777 "/></ query ></ iq>注意这里注要是代理的设置,agsXMPP自带的客户端是使用代理传输数据的 使其支持局域网内支持发送文件.下面我们来看一下服务器端是如何

25、路由消息的呢?从上面所发送的XML流我们可以看出,实际上用户传送文件所发送的都是路由才能使其找到相应的接收者,所以我们需要在XmppServerConnectionprivate void ProcessIQ(IQ iq)(/传送文件得理if (iq.Query = null)(if (iq.Type = IqType.result)this .Send(iq);ProcessOobIQ(iq); else if (iq.Query.GetType() = typeof (Auth)(Auth auth = iq.Queryas Auth;this .Username = auth.Usern

26、ame.ToString();switch (iq.Type)(case IqType. get :iq.SwitchDirection();iq.Type = IqType.result;auth.AddChild(new Element("password");auth.AddChild(new Element("digest");Send(iq);break ;case IqType. set :/ Here we should verify the authentication credentialsif (AccountBus.CheckLog

27、in(auth.Username, auth.Digest,(iq.SwitchDirection();iq.Type = IqType.result;iq.Query =null ;Send(iq);Console.WriteLine(auth.Username + ”登录了DateTime.Now.ToString();else(/ iq.SwitchDirection();iq.Type = IqType.error;iq.Query =null ;,所以必须对其做相应的修改IQ节,我们必须对IQ节进行 类中添加如下代码:this .SessionId)+ "登录时间:&quo

28、t;+ System.Send(iq);)break ;)else if (iq.Query.GetType() = typeof (Roster)(ProcessRosterIQ(iq);)/用代理传送文件处理else if(iq.Query.FirstChild != null )(/ iq.SwitchDirection();/ /iq.Type = IqType.result;/ /Send(iq);/ iq.Type = IqType.set;/this.Send(iq);ProcessOobIQ(iq);)传送文件载图:重构(也项目回生成(E)调试。数据工具测试窗口险社区帮助* D

29、ebug Mixed Platformsproxy .ag-softi*,testtocthshumilocathost - Parr.:t.C5 Xmpp5erverxsent.exexij3Cl'4(FJ操作(手工具幕助:H)test空闱MvNBBub ek4A8C F7CFRQ oC6bsA 4h2Ball 8o $cQ7T8shumi空氐b有空locathosttest|jT£dlocalhostshumi醪 99% ofwin2OO3.GHO 接收中。fwi 心g3.GH0发送者:文件名:地点:shunmwin2003,GHOH:Mn2g3.GH。接收者:文件名:理

30、点:testwin2003.GHOD:l5v5Ba&Vn2003.奇1099%99%进度:刺余时间:少于1分钟-速度17.3 MB®进度:刺余时间S1.2GBM.3GB少于1分钟-速度17.3 MB渺放弃打开eh390eGB</de sc ></Query ></iq>这里我们讲解完了服务器是如何处理用户互传文件,以后我将继续讲解客户端的实现原理这篇文章本来是昨晚上写好的,但由于源码留在公司了 ,所以今早上才贴出来。第三篇:前面两篇,我们主要学习了基于 XMPP协议的即时通讯工具的服务器端实现 ,下面我们将要来共同学习一下 基于XMPP协议

31、的即时通讯工具的客户端实现原理 ,本篇将主要分析 agsXMPPP客户端用户登录认证的实 现原理(关于XMPP协议与agsXMPP的相关知识请认真看第一篇中的附件 )1、主窗体初始化时将订阅一大堆的事件 /读取接收到的XML流信息XmppCon.OnReadXml+=/向服务器发送XML流信息XmppCon.OnWriteXml+=XmppCon.OnRosterStart+=XmppCon.OnRosterEnd +=XmppCon.OnRosterltem+=ler(XmppCon_OnRosterItem);XmppCon.OnAgentStart+=XmppCon.OnAgentEnd

32、+=XmppCon.OnAgentltem+=new XmlHandler(XmppCon_OnReadXml);new XmlHandler(XmppCon_OnWriteXml);new ObjectHandler(XmppCon_OnRosterStart);new ObjectHandler(XmppCon_OnRosterEnd);new agsXMPP.XmppClientConnection.RosterHandnew ObjectHandler(XmppCon_OnAgentStart);new ObjectHandler(XmppCon_OnAgentEnd);new ags

33、XMPP.XmppClientConnection.AgentHa/用户登录事件XmppCon.OnLogin+=/关闭连接事件XmppCon.OnClose+=/连接错误事件XmppCon.OnError+=/ 收至ij Presence节时引发的事件XmppCon.OnPresence += andler(XmppCon_OnPresence);/收到Message节时引发的事件XmppCon.OnMessage +=ndler(XmppCon_OnMessage);/收到IQ节时引发的事件XmppCon.Onlq+=/认证错误事件XmppCon.OnAuthError += ror);

34、/读取Socket事件XmppConSocket.OnReadSocketData += DataHandler(ClientSocket_OnReceive);/写入Socket事件new ObjectHandler(XmppCon_OnLogin);new ObjectHandler(XmppCon_OnClose);new ErrorHandler(XmppCon_OnError);new agsXMPP.XmppClientConnection.PresenceHnew agsXMPP.XmppClientConnection.MessageHanew StreamHandler(XmppCon_OnIq);new OnXmppErrorHandler(XmppCon_OnAuthErnew agsXMPP.net.BaseSocket.OnSocketndler(X

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论