目前在用redis的订阅功能,做一个web版的及时聊天程序,因为是ajax长连接实现的及时消息,所以肯定会遇到timeout的问题,不管是socket还是php的最大执行时间都是会遇到的。
最简单的解决办法就是将系统的时间参数都是设置为不限制。但是一个老程序员了,不想用这么原始的方法解决问题,也不愿意去修改服务器的配置。所以想到了每隔30秒自动断开再重新请求的原理。虽然有些轮询的味道,但是依然是长连接的及时没有30秒的延迟。
自动断开请求,首先就想到了ajax有没有能够取消请求的方法,百度了,确实有,jquery的ajax封装也可以取消请求。而且有两种方式,一个是$.ajax的timeout,另一个就是XMLHttpRequest对象的abort()方法。
我自己的递归代码:
function sub(){
$.ajax({
type:'POST',
url:'sub.php',
data:'',
timeout:30000,
success:function(data){
if(data!=""){//如果有数据发布,就会插入到div层当中
$("#show").append(data+"
");
}
$("textarea").val("");//清空textarea里面的值
sub();//重新调用自己,重新去订阅redis服务器(无限循环的)
},
error:function(){
sub();//重新调用自己,重新去订阅redis服务器(无限循环的)
}
});
}
sub();//第一次调用订阅函数
引用代码说明:
jquery的ajax方法有自己的超时时间设置参数:
$.ajax({type:'POST',
url:'b.php',
data:'',
timeout:5000,
success:function(){
}
})
同时
$.get返回的数据类型是XMLHttpRequest,请参考手册。($.post、$.ajax、$.getJSON、$.getScript也同样)
XMLHttpRequest对象有abort()方法
也可以自己手动去调用abort方法:
var xhr = $.ajax({type:'POST',
url:'b.php',
data:'',
success:function(){
alert('ok');
}
})
alert(xhr);
console.log(xhr);
abort
$(function(){
$("#song").click(function(){
alert('click');
xhr.abort();
})
})
对于原生的xhr:
xmlHttp.open("POST","theUrl",true);
xmlHttp.onreadystatechange=function(){
...//得到响应之后的操作
}
xmlHttp.send();
//设置8秒钟后检查xmlHttp对象所发送的数据是否得到响应.
setTimeout("CheckRequest()","8000");
function CheckRequest(){
//为4时代表请求完成了
if(xmlHttp.readyState!=4){
alert('响应超时');
//关闭请求
xmlHttp.close();
}
}