10

建立一个社交网络,我正在尝试获取实时通知。目前,该站点使用 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);

这非常有效,但我非常担心创建服务器过载。我尝试了彗星技术,但由于某种原因,它发送的请求比上面的代码多得多。还有其他更有用的技术可以实时推送这些数据吗?

编辑:为了实现长轮询,我使用了以下内容(使用此处提到的示例: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,他们是如何做到的?

4

2 回答 2

8

你应该使用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/

于 2013-01-01T18:02:13.237 回答
2

一旦 Websockets 在主要浏览器中得到更普遍的实施,它们将成为必经之路——我猜至少需要 5 年。

我最后一次听说 Facebook 聊天使用 Comet 和一大堆服务器。如果你想要更轻量级的东西,我可以想到两个选择。

  1. 减少轮询间隔。这严格来说是一个 UI 问题——用户可能会在几分钟内获得完全可以接受的体验。确定的唯一方法是通过用户测试,但每 5 秒轮询一次可能是矫枉过正。无论您选择什么作为最佳间隔,如果您受到打击,这确实为您提供了一种快速扩展的方法 - 只需加快间隔直到服务器停止融化。

  2. 使用 HTTP 验证缓存。如果服务器仅在自上次请求后内容发生更改时才返回响应正文,则可以使请求更轻量级。您必须使用 ETag 或 Last-Modified 标头和服务器上的轻量级修改检查系统构建自定义内容,但它可能会为您节省一些字节。

于 2013-01-02T16:18:09.050 回答