您的位置:首页 > 其它

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

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

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



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

实现代码:

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

1: 数据列表:o<br />

2: <div id="con" style=" width:400; height:200px; border:1px solid #FF0">

3: </div>

4: <iframe id="flush" src="Flush.aspx" style=" display:none" />

5:

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

1: protected void Page_Load(object sender, EventArgs e)

2: {

3: string startHTML = "<!DOCTYPE HTML PUBLIC /"-//W3C//DTD XHTML 1.0
Transitional//EN/"
/"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd/">" +
Environment.NewLine

4: + "<html xmlns=/"http://www.w3.org/1999/xhtml/" >" + Environment.NewLine

5: + "<head>" + Environment.NewLine

6: + "</head>" + Environment.NewLine

7: + "<body>" + Environment.NewLine;

8:

9: startHTML += new String(' ', 1024) + Environment.NewLine;

10:

11: Response.Write(startHTML);

12: Response.Flush();

13:

14: string data = "<script type=/"text/javascript/">parent.$('#con').append(/"{0}/");</script>";

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

16: Response.Flush();

17:

18: int index = 0;

19: while (true)

20: {

21: System.Threading.Thread.Sleep(2000);

22: if (index % 2 == 0)

23: {

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

25: }

26: else

27: {

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

29: }

30: Response.Flush();

31:

32: index++;

33: }

34: }

35:

运行Default.aspx的结果:



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

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

修改Default.aspx的页面代码:

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

2: <div id="con" style=" width:400; height:200px; border:1px solid #FF0">

3: </div>

4: <script type="text/javascript">

5: function getData(d)

6: {

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

8: }

9:

10: function rpc_iframe() {

11: var transferDoc = new ActiveXObject("htmlfile");

12: transferDoc.open();

13: transferDoc.write("<html>")

14: transferDoc.write("<div><iframe src=/"Flush.aspx/"></iframe></div>");

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

16: transferDoc.parentWindow.getData = getData;

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

18: }

19:

20: rpc_iframe();

21: </script>

22:

修改Flush.aspx.cs代码:

1: //string data = "<script type=/"text/javascript/">parent.$('#con').append(/"{0}/");</script>";

2: string data = "<script type=/"text/javascript/">parent.getData(/"{0}/");</script>";

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