asp.net 服务器推送(Server Push) 支持 IE、火狐、谷歌等 仅供参考

asp.net 服务器推送(Server Push) 这个示例只支持IE的推送,但在现在浏览器多元化的时代,
只支持IE在大多数时候还是不够的,如何兼容多种浏览器是摆在我们程序员面前的一大难题,
算了,不诉苦了,回归正题,在非IE浏览器下,我们在借助 HttpRequest 对象来实现推送,
判断 request.readyState == 3 就可以了。


废话就不说了,示例代码如下:
(已上传示例程序:服务器推送示例-支持IE火狐谷歌等)本页代码已更新,上传的示例程序也已更新。
经测试,本代码在IE6/8、火狐、傲游极速模式下,可以长时间推送数据,已测时间大于3小时。
已解决在IE下,推送时间短于1分钟的问题。其罪魁祸首就是原来网上的代码将htmlfile定义在了onload方法内了,将htmlfile定义为全局变量就可以解决问题了,真郁闷啊,花一天时间找到这个BUG,隐藏太深了。。。

注意,在同一时间同一浏览器,用推送技术不能超过一个,如果同时保持两个长链接,那IE下其它请求均会被阻塞。

 

在实际项目应用中,服务器端使用的是Oracle的变化通知功能,但并不能保证每一个客户端都会通知到,本文仅供参考。 --2013.4.8



Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected override void Render(HtmlTextWriter output)
    {
        //long index = 0;
        string str;
        while (this.Context.Response.IsClientConnected)
        {
            //死循环保持长链接 
            str = "<script>window.top.Change('" + DateTime.Now.ToLongTimeString() + "');</script>";
            this.Context.Response.Write(str);
            this.Context.Response.Flush();//输脚本调用出
            System.Threading.Thread.Sleep(1000);
            
            //测试意外关闭
            //index++;
            //if (index > 10)
            //    break; 
        }
        base.Render(output);
    }
}


PushTest.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PushTest.aspx.cs" Inherits="PushTest" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Asp.Net Server Push</title>


    <script type="text/javascript">
        function Change(str) {
            document.getElementById("div1").innerHTML = str;
        }
        var ifrpush = null;  //将变量定义在onload方法之外可以长时间保持长链接
        var request = null;  
        var responseDIV = document.createElement("div");
        responseDIV.style.display = "none";
        if (navigator.userAgent.indexOf("Firefox") > -1)
            document.body.appendChild(responseDIV);
        //非IE长链数据处理或重新打开
        function NOTIEReadyStateChange() {
            if (request.readyState == 3) {
                //长链接数据处理
                var restr = request.responseText.replace(responseDIV.innerHTML, "");
                restr = restr.replace(/<script>/g, "").replace(/<\/script>/g, "");
                window.eval(restr);
                responseDIV.innerHTML = request.responseText;
            } else if (request.readyState == 4) {
                //长链接中断导致加载完成
                request = new window.XMLHttpRequest();
                responseDIV.innerHTML = "";
                var url = "default.aspx";
                request.open("GET", url, true);
                request.onreadystatechange = NOTIEReadyStateChange;
                request.send(null);
            }
        }
        //IE长链接是否已断开
        function IsLoaded() {
            if (ifrpush != null && ifrpush.readyState == 'complete') {
                alert("refresh");
                //长链接意外断开导致加载完成处理
                ifrpush = null;
                ifrpush = new ActiveXObject("htmlfile"); // 创建对象
                ifrpush.open(); //打开 
                var ifrDiv = ifrpush.createElement("div"); //添加一个DIV
                ifrpush.appendChild(ifrDiv); //添加到 htmlfile
                ifrpush.parentWindow.Change = Change;
                ifrDiv.innerHTML = "<iframe src='Default.aspx'></iframe>"; //在div里添加 iframe
                ifrpush.close(); //关闭
            }
        }
        function onload() {
            var isIE = !!window.ActiveXObject;
            if (isIE) {
                ifrpush = new ActiveXObject("htmlfile"); // 创建对象
                ifrpush.open(); //打开 
                var ifrDiv = ifrpush.createElement("div"); //添加一个DIV 
                ifrpush.appendChild(ifrDiv); //添加到 htmlfile 
                ifrpush.parentWindow.Change = Change; //注册 javascript 方法
                ifrDiv.innerHTML = "<iframe src='Default.aspx'></iframe>"; //在div里添加 iframe
                ifrpush.close(); //关闭
                setInterval("IsLoaded()", 1000); //监视长链接状态
            } else {
                request = new window.XMLHttpRequest();
                responseDIV.innerHTML = "";
                var url = "default.aspx";
                request.open("GET", url, true);
                request.onreadystatechange = NOTIEReadyStateChange;
                request.send(null);
            }
        }
        onload(); 
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div style="float: left">
            现在时间是:</div>
        <div id="div1">
        </div>
    </div>
    </form>
</body>
</html>

参考:http://topic.csdn.net/u/20081123/11/9e35b163-f25e-41d5-8079-f7425dc001e5.html   
感谢zhaoguo2007





你可能感兴趣的:(server,IE,服务器,asp.net,div)