您的位置:首页 > 其它

利用Response.Flush和iframe实现”服务器推”技术

2010-09-07 23:17 288 查看
通过在HTML页面里陷入一个隐藏的iframe,然后将这个iframe的src属性设为对一个长连接的请求(利用chunked传输response),服务器端就能源源不断地往客户推送数据。

基于流方式的”服务器推”模型:





服务端在接到客户端的请求时,通过Response的Flush()方法发送数据,可以使用定时器的方式发送数据,没有数据也发送”无数据”,让客户端保持长连接,直至客户端断开连接,请求结束。每次数据传送不会关闭连接,连接只会在通信出现错误时,或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接,服务器端可以设置一个超时时间,超时后通知客户端重新建立连接,并关闭原来的连接)。

实现代码:

页面Default.aspx,用来展示数据:

数据列表:o<br/>

<divid="con"style="width:400;height:200px;border:1pxsolid#FF0">

</div>

<iframeid="flush"src="Flush.aspx"style="display:none"/>



ifame的src对应的Flash.aspx后台代码,模拟后台发送数据:

protectedvoidPage_Load(objectsender,EventArgse)

{

stringstartHTML="<!DOCTYPEHTMLPUBLIC\"-//W3C//DTDXHTML1.0Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"+Environment.NewLine

+"<htmlxmlns=\"http://www.w3.org/1999/xhtml\">"+Environment.NewLine

+"<head>"+Environment.NewLine

+"</head>"+Environment.NewLine

+"<body>"+Environment.NewLine;


startHTML+=newString('',1024)+Environment.NewLine;


Response.Write(startHTML);

Response.Flush();


stringdata="<scripttype=\"text/javascript\">parent.$('#con').append(\"{0}\");</script>";

Response.Write(string.Format(data,"开始发送数据:<br/>"));

Response.Flush();


intindex=0;

while(true)

{

System.Threading.Thread.Sleep(2000);

if(index%2==0)

{

Response.Write(string.Format(data,DateTime.Now.ToString("yyyy-MM-ddHH:mm:ss")+"服务端发送数据<br/>"));

}

else

{

Response.Write(string.Format(data,DateTime.Now.ToString("yyyy-MM-ddHH:mm:ss")+"无数据发送<br/>"));

}

Response.Flush();


index++;

}

}



运行Default.aspx的结果:





使用iframe请求一个长连接有一个很明显的不足之处:IE、MorzillaFirefox下端的进度栏都会显示加载没有完成,而且IE上方的图标会不停的转动,表示加载正在进行;刷新当前页面反应也是会很慢。

解决IE的进度栏显示加载没有完成,可以使用一个称为“htmlfile”的ActiveX,是Google的天才们使用的方法,该控件也被用到gmail+gtalk产品中。

修改Default.aspx的页面代码:

数y据Y列D表í:o<br/>

<divid="con"style="width:400;height:200px;border:1pxsolid#FF0">

</div>

<scripttype="text/javascript">

functiongetData(d)

{

$("#con").append(d);

}


functionrpc_iframe(){

vartransferDoc=newActiveXObject("htmlfile");

transferDoc.open();

transferDoc.write("<html>")

transferDoc.write("<div><iframesrc=\"Flush.aspx\"></iframe></div>");

transferDoc.close("</html>");

transferDoc.parentWindow.getData=getData;

setInterval(function(){},10000);//不加这句会使连接断开

}


rpc_iframe();

</script>



修改Flush.aspx.cs代码:

//stringdata="<scripttype=\"text/javascript\">parent.$('#con').append(\"{0}\");</script>";

stringdata="<scripttype=\"text/javascript\">parent.getData(\"{0}\");</script>";


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: