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)
//
}
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>
本文作者:ranbolwb 来源:CSDN
CIO之家 www.ciozj.com 微信公众号:imciow