基于 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);
            }

}
传送文件载图:

这里我们讲解完了服务器是如何处理用户互传文件,以后我将继续讲解客户端的实现原理.
         这篇文章本来是昨晚上写好的,但由于源码留在公司了,所以今早上才贴出来。

posted on 2006-09-22 08:04 舒密 阅读(5227) 评论(14) 编辑 收藏

评论

#1楼  回复 引用   

关注中
2006-09-22 11:24 | weejie[未注册用户]

#2楼  回复 引用   

fsfs
2006-09-22 12:51 | fsfs[未注册用户]

#3楼  回复 引用   

不错
2006-09-27 23:07 | TimYang[未注册用户]

#4楼  回复 引用   

搂主的源码共享吗?给小弟发一份学习学习 wapasp@hotmail.com
2006-10-10 09:33 | wapasp[未注册用户]

#5楼[楼主]  回复 引用 查看   

@wapasp
只是简单实现了一下,现在没有时间做了,等以后有时间整理好了后再开源
2006-10-10 12:49 | 舒密      

#6楼  回复 引用   

我需要你的资料,能否给我发一份 nyzfl@hotmail.com
2007-04-23 17:04 | nyzfl[未注册用户]

#7楼  回复 引用 查看   

ProcessOobIQ(iq);
这段代码的内容怎么没有了
2007-08-12 19:40 | 登峰      

#8楼  回复 引用   

楼主要抓紧时间整理呀,我们等着用呢,
2007-11-27 11:17 | 轻风漫语[未注册用户]

#9楼  回复 引用   

看了您的几篇文章,非常受启发,想研究一下xmpp,能不能给我共享一下您的源代码,谢谢。xyyk1@126.com
2008-01-20 22:07 | 蓝海治家[未注册用户]

#10楼  回复 引用 查看   

看了您介绍agsxmpp文章,非常受启发。现在正在研究XMPP。能否发些agsxmpp中文资料或DEMO给我学习下,网络上资料太少了。谢谢。ghotvbu03@sina.com
2008-10-16 13:46 | seeker      

#11楼  回复 引用   

发给我一个源代码给我,谢谢了
2008-12-20 09:11 | eyer[未注册用户]

#12楼  回复 引用   

博主是不是Pandion已经支持XEP-0065了
2008-12-31 17:27 | yhgroup[未注册用户]

#13楼  回复 引用   

看到截图是Pandion的,如果支持XEP-0065了能不能发份给我
chenwenwei_2000@163.cim
2008-12-31 17:29 | chenwenwei[未注册用户]

#14楼  回复 引用 查看   

我下载agsxmpp不能收文件,能给SPARK发文件,不知道楼主是否稳定,
2010-03-16 16:05 | LeeFly