代码
<! 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 > 无标题页 </ title >
< script type ="text/javascript" src ="script/jquery-1.2.6.js" ></ script >
< script type ="text/javascript" >
$(document).ready( function (){
$( " #Button1 " ).bind( " click " ,{btn:$( " #Button1 " )}, function (evdata){
$.ajax({
type: " POST " ,
http: // hi.baidu.com/fc/editor/%22JqueryAjaxLongPoll.aspx",
dataType: " json " ,
timeout: 10000 ,
data:{ajax: " 1 " ,time: " 10000 " },
success: function (data,textStatus){
// alert("ok!");
evdata.data.btn.click();
},
complete: function (XMLHttpRequest,textStatus){
if (XMLHttpRequest.readyState == " 4 " ){
alert(XMLHttpRequest.responseText);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown){
// $("#ajaxMessage").text($(this).text()+" out!")
alert( " error: " + textStatus);
if (textStatus == " timeout " )
evdata.data.btn.click();
}
});
});
/* $("#ajaxMessage").ajaxStart(function(){
$(this).text("准备建立请求.readyState0:");
});
$("#ajaxMessage").ajaxSend(function(evt, request, settings){
$(this).text("开始请求,准备发送数据.readyState1:"+request.readyState);
});
$("#ajaxMessage").ajaxComplete(function(event,request, settings){
if(request.status==200)
$(this).text("请求完成.readyState4:"+request.readyState);
});
$("#ajaxMessage").ajaxStop(function(){
$(this).text("请求结束.");
}); */
});
</ script >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< input id ="Button1" type ="button" value ="AjaxLongPoll" />
< label id ="ajaxMessage" ></ label >
</ div >
</ form >
</ body >
</ html >
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
public partial class JqueryAjaxLongPoll : System.Web.UI.Page
{
protected void Page_Load( object sender, EventArgs e)
{
if (Request.Form[ " ajax " ] == " 1 " )
{
// Response.End();
int time = Convert.ToInt32(Request.Form[ " time " ]);
DateTime date1 = DateTime.Now.AddMilliseconds(( double )time);
bool ready = false ;
while (Response.IsClientConnected)
{
Thread.Sleep( 3000 );
if (DateTime.Compare(date1, DateTime.Now) < 0 )
{
Response.End();
break ;
}
// ready = true;
if (ready)
{
Response.Write( " SetValue(' " + DateTime.Now.ToString() + " ') " );
// Response.Flush();
Response.End();
break ;
}
else
{
}
}
}
else
{
if ( ! Page.IsPostBack)
{
}
}
}
}
对代码的说明:利用jquery,很方便的就能实现ajax,上面设置了ajax的timeout时间,由于设置了timeout将会造成不能保持长连接,到了时间ajax自动会报“超时”的错误,也就是会调用error方法,此时textStatus=="timeout",timeout后重新进行ajax请求。服务器接受ajax请求的时候,会接收一个超时时间的值,超时的情况下服务器端的处理也立即停止。当客户端成功获取返回结果时,也会立即进行新的ajax请求,如此循环。
为什么要设置客户端的ajax超时值呢?因为服务器为了保持请求(阻塞请求),必须有一个无限循环,循环的结束条件就是获取到了返回结果,如果客户端关闭了(客户端浏览器的关闭不会发消息给服务器),服务器无法知道客户端已经关了,这个请求没必要处理下去了。最终会造成资源过度浪费,只要用一个折中的办法,限制超时时间。
可以不必设置客户端ajax的超时时间,但进行请求的时候传递一个超时值给服务器,服务器在处理的时候,如果超时时间到了的话,还没有客户端需要的结果,这时传递一个超时信息给客户端,客户端接收到了此信息,根据情况重新进行ajax请求。XMLHttpRequest没有超时的参数,Jquery用window.setTimeout自己封装的(到了定时时间运行超时处理方法,和XMLHttpRequest结束方法)。可以根据这个思路来改变一下,IBM上介绍的LONG POLL好像也是这样的。
$( " #Button1 " ).bind( " click " ,{btn:$( " #Button1 " )}, function (evdata){
$.ajax({
type: " POST " ,
http: // hi.baidu.com/fc/editor/%22JqueryAjaxLongPoll.aspx",
dataType: " json " ,
data:{ajax: " 1 " ,time: " 6000000 " },
success: function (data,textStatus){
// 成功
if (data.success == " 1 " ){
// 客户端处理
// ...
// /重新请求
evdata.data.btn.click();
}
// 超时
if (data.success == " 0 " ){
evdata.data.btn.click();
}
},
complete: function (XMLHttpRequest,textStatus){
if (XMLHttpRequest.readyState == " 4 " ){
alert(XMLHttpRequest.responseText);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown){
// $("#ajaxMessage").text($(this).text()+" out!")
// alert("error:"+textStatus);
// if(textStatus=="timeout")
evdata.data.btn.click();
}
});
});
{
int time = Convert.ToInt32(Request.Form[ " time " ]);
DateTime date1 = DateTime.Now.AddMilliseconds(( double )time);
bool ready = false ;
while (Response.IsClientConnected)
{
Thread.Sleep( 3000 );
if (DateTime.Compare(date1, DateTime.Now) < 0 )
{
Response.Write( " {success:'0'} " );
Response.End();
break ;
}
// 此处进行请求处理,有结果了置ready = true
// ready = true;
if (ready)
{
Response.Write( " {success:'1'} " );
Response.End();
break ;
}
}
}
else
{
if ( ! Page.IsPostBack)
{
}
}
上面的方法应该就可以满足要求了,具体的超时时间可以根据情况来设置。这也是根据IBM上介绍的“server push”思路,来实现了其中的一种。
如果你有更友好更简洁的解决方案,欢迎分享