基于 XMPP协议的服务器端 文件互传的简单实现

         昨天我们讲了客户端实现用户互发消息的原理,今天我们继续学习一下基于XMPP协议的文件传输,首先我们假设用户已经登录,这里我们假设Clinet Send对Clinet Receive 发送文件,这里记录了Clinet Send的发送和接收XML流记录

1、发送请求表示要向Clinet test发送文件,并发送文件大小和文件名
SEND:  < iq  xmlns ="jabber:client"  id ="agsXMPP_6"  to ="Receive @localhost/"  type ="set" >< si  xmlns ="http://jabber.org/protocol/si"  profile ="http://jabber.org/protocol/si/profile/file-transfer"  id ="b3b5f49c-8a94-49e2-908a-3de694b98af0" >< file  xmlns ="http://jabber.org/protocol/si/profile/file-transfer"  name ="MiniClient.exe.config"  size ="382" >< range  /></ file >< feature  xmlns ="http://jabber.org/protocol/feature-neg" >< xmlns ="jabber:x:data"  type ="form" >< field  type ="list-single"  var ="stream-method" >< option >< value > http://jabber.org/protocol/byReceive reams </ value ></ option ></ field ></ x ></ feature ></ si ></ iq >

2、Receive 收到Send发实来的请求后,发送出响应流
RECV:  < iq  xmlns ="jabber:client"  to ="Send@localhost"  type ="result"  id ="agsXMPP_6" >< si  xmlns ="http://jabber.org/protocol/si"  id ="b3b5f49c-8a94-49e2-908a-3de694b98af0" >< feature  xmlns ="http://jabber.org/protocol/feature-neg" >< xmlns ="jabber:x:data"  type ="submit" >< field  var ="stream-method" >< value > http://jabber.org/protocol/byReceive reams </ value ></ field ></ x ></ feature ></ si ></ iq >

3、Send收到Receive 愿意接收的响应后,发出如下XML流
SEND:  < iq  xmlns ="jabber:client"  id ="agsXMPP_7"  to ="Receive@localhost"  type ="set" >< query  xmlns ="http://jabber.org/protocol/bySendreams"  sid ="71f1b875-4d84-429c-b39d-7dabcd400f3d" >< streamhost  jid ="Send@localhost/MiniClient"  host ="localhost"  port ="1000"   />< streamhost  jid ="proxy.ag-software.de"  host ="proxy.ag-software.de"  port ="7777"   /></ query ></ iq >


注意这里注要是代理的设置,agsXMPP 自带的客户端是使用代理传输数据的,所以必须对其做相应的修改,使其支持局域网内支持发送文件.

下面我们来看一下服务器端是如何路由消息的呢?
从上面所发送的XML流我们可以看出,实际上用户传送文件所发送的都是IQ节,我们必须对IQ节进行路由才能使其找到相应的接收者 ,所以我们需要在XmppServerConnection类中添加如下代码:
 

private   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.Query  as  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 :
                        
//  Here we should verify the authentication credentials
                         if  (AccountBus.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.Query 
=   null ;
                            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);
            }

}
传送文件载图:
基于 XMPP协议的服务器端 文件互传的简单实现_第1张图片
这里我们讲解完了服务器是如何处理用户互传文件,以后我将继续讲解客户端的实现原理.
         这篇文章本来是昨晚上写好的,但由于源码留在公司了,所以今早上才贴出来。

你可能感兴趣的:(基于 XMPP协议的服务器端 文件互传的简单实现)