如何在不使用setInterval/timeout的情况下检查实时更新
How can I check for live updates without using setInterval/timeout?
建立一个社交网络,我试图获取实时通知。目前,站点使用setInterval每隔几秒发送一个AJAX请求。它看起来像这样:
setInterval ( function(){
url = base_dir+"/ajax/file.php";
data = "data=someData";
$.ajax({
type: "POST",
url: url,
data: data,
dataType: "json",
beforeSend: function(x) {
if(x && x.overrideMimeType) {
x.overrideMimeType("application/json;charset=UTF-8");
}
},
success: function(JSON){
// retrieve data here
}
});
}, 5000);
这非常有效,但我非常担心这会导致服务器过载。我尝试了comet技术,但由于某种原因,它发送的请求比上面的代码多得多。是否有其他更有用的技术来实时推送这些数据?
编辑:为了实现长轮询,我使用了以下方法(使用这里提到的示例):http://techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery):
(function poll(){
url = base_dir+"/ajax/file.php";
data = "data=someData";
$.ajax({
type: "POST",
url: url,
data: data,
dataType: "json",
beforeSend: function(x) {
if(x && x.overrideMimeType) {
x.overrideMimeType("application/json;charset=UTF-8");
}
},
success: function(JSON){
// retrieve data here
},
complete: poll,
timeout: 5000
});
})();
有可能我没有把彗星原理理解对。
PHP代码:// Checks for new notifications, and updates the title and notifications bar if there are any
private static function NotificationsCounter (){
//self::$it_user_id = query that retrieves my id for further checks;
//$friend_requests_count = query that retrieves the friend requests count;
//$updates_count = query that retrieves the updates count;
$total_notifications = $friend_requests_count+$updates_count;
if ($total_notifications > 0) $addToTitle = "(".$total_notifications.")";
else $addToTitle = "";
if ($updates_count > 0) $counterHTML = "<span class='notification_counter' id='updates_counter' style='float: right;'>".$updates_count."</span>";
else $counterHTML = "";
$data = array("counter"=>$total_notifications,"addToTitle"=>$addToTitle,"counterHTML"=>$counterHTML,);
echo json_encode($data); // parse to json and print
}
既然Facebook也使用PHP,他们是怎么做到的?
你应该使用websockets。您可以连接到服务器并注册onmessage处理程序。每当服务器有任何东西要发送到客户端时,您的处理程序将被调用。不需要超时
检查浏览器是否支持websocket。到目前为止,只有Chrome、Opera和Safari支持。
if ('WebSocket' in window){
/* WebSocket is supported. You can proceed with your code*/
} else {
/*WebSockets are not supported. Try a fallback method like long-polling etc*/
}
连接var connection = new WebSocket('ws://example.org:12345/myapp');
处理程序
connection.onopen = function(){
console.log('Connection open!');
}
connection.onclose = function(){
console.log('Connection closed');
}
connection.onmessage = function(e){
var server_message = e.data;
console.log(server_message);
}
文档:http://www.developerfusion.com/article/143158/an-introduction-to-websockets/
Websockets将是未来的发展方向,一旦它们在各大浏览器中得到普遍实现——我猜至少需要5年时间。
我最后一次听到Facebook聊天使用comet和一大堆服务器。如果你想要更轻便的东西,我有两个选择。
-
减少轮询时间间隔。这是一个严格意义上的UI问题——用户可能会在几分钟的间隔内获得完全可以接受的体验。唯一确定的方法是通过用户测试,但每5秒轮询一次可能有点过头了。无论您选择什么作为最佳间隔,如果您受到打击,这确实为您提供了一种快速扩展的方法-只需调整间隔,直到服务器停止融化。
-
使用HTTP验证缓存。如果服务器只在内容自上次请求以来发生更改时返回响应体,则可以使请求更加轻量级。你将不得不在服务器上使用ETag或Last-Modified头和轻量级的修改检查系统来构建一些自定义的东西,但它可能会为你节省一些字节。
- 如何在未直接触发的情况下停止事件
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 在不使用jquery的情况下查找页面中的所有锚点并附加函数
- 在不打开聊天屏幕的情况下制作Zopim-ding代理
- 在不阻止默认行为的情况下检测IE10中的缩放
- 如何在不传递此信息的情况下查找被调用的元素
- 如何在不刷新页面的情况下更新显示框
- 有没有一种方法可以在控制台关闭的情况下让console.log()在IE中记录消息
- JavaScript-在手机上不工作的情况下,在外部单击时隐藏元素
- 在我的情况下,如何进行http请求
- 在不知道深度或父属性的情况下从对象中删除属性
- 在不破坏未定义函数的情况下,对多个视图使用单个js文件
- ROR:如何在不重新加载浏览器的情况下从控制器获取参数
- 如何在不影响其他元素的情况下扩展DIV
- 如何在内联依赖项并将图像转换为dataURI的情况下完全提取网页
- 在不移动内部文本的情况下缩放元素的效果
- 在不设置协议的情况下,使用javascript/jquery更改iframe-src
- 在这种情况下,.fail() 或 .timeout() 更好吗?
- UI 路由加载微调器在没有$timeout的情况下不起作用
- 如何在不使用setInterval/timeout的情况下检查实时更新