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

Websocket は、主要なブラウザー全体でより普遍的に実装されるようになると、進むべき道になります。少なくとも 5 年はかかると思います。

私が最後に聞いた Facebook のチャットでは、comet と多数のサーバーが使用されていました。もっと軽量なものが必要な場合は、2 つのオプションを考えることができます。

  1. ポーリング間隔を減らします。これは厳密には UI の問題です。ユーザーは、数分程度の間隔で完全に許容できるエクスペリエンスを得ることができます。確実に知る唯一の方法はユーザー テストですが、5 秒ごとにポーリングするのはおそらくやり過ぎです。最適な間隔として選択したものに関係なく、サーバーが溶けるのを止めるまで間隔を上げてください.

  2. HTTP 検証キャッシュを使用します。最後のリクエスト以降にコンテンツが変更された場合にのみサーバーがレスポンス本文を返す場合、リクエストをより軽量にすることができます。サーバー上で ETag または Last-Modified ヘッダーと軽量の変更チェック システムを使用して何かカスタムを構築する必要がありますが、数バイト節約できる可能性があります。

于 2013-01-02T16:18:09.050 に答える