web-dev-qa-db-ja.com

ハートビートAPIロングポーリング

私は最近、Heartbeat API js clientに0間隔の「ロングポーリング」と呼ばれるティックスピードのオプションが追加されたことに気づきました。私は彼らが何を達成しようとしているのかについてはかなり理解していますが、この機能を使ってプラグインを実装する方法について混乱しています。

私のサーバーがブラウザからリクエストを受信するたびに、フックが起動され、データがクエリされ、レスポンスが作成されてクライアントに返送されました。しかし、間隔が0の場合は、実際に何らかのイベントがトリガーされるのを待ってから応答を作成する必要があります。

この新機能の例として、誰かが簡単なコードを提供できますか?

5
user3562259

Hearbeat APIは、クライアントに返されるデータを添付するためのWordPress /プラグイン/テーマ用のフックを使用して、定期的にXHRリクエストをサーバーに送信することによって機能します。データが返されると、新しいビートがスケジュールされます。ハートビートの速度(または「パルス」)は、イベント(例えば、ユーザの非アクティブ)に反応して、サーバ側またはクライアント側のいずれかで緩和され得る。

ロングポーリング

ロングポーリングは同じように機能しますが(source: ウィキペディア

空の応答を送信する代わりに、ポーリングを受信したときにサーバーがクライアントに使用できる情報を持っていない場合、サーバーは要求を開いたままにし、応答情報が使用可能になるのを待ちます。それが行われると、サーバーは直ちにHTTP/S応答をクライアントに送信し、オープンHTTP/S要求を完了します。

そのため、定期的にリクエストを送信して何かが戻ってくるのではなく、リクエストを1つ送信し、サーバーは準備ができたらデータを返信します。それが完了したら、すぐに新しいXHR要求を開始します、従って間隔は0です。

健康警告

質問のコメントで述べたように、 ロングポーリング はWordPressの「潜在的な」機能です。 Heartbeat APIは、実際には実装せずに、そのための準備をします。実装されていない理由は track ticket#23216 でカバーされているので、この議論を読むことをお勧めします。

しかし、一言で言えば、欠点/潜在的な問題は次のとおりです。

  • キャッシング - ロングポールリクエストはWordPressをロードします。データベースクエリ(オプション、投稿などを含む)がキャッシュされます。スクリプトがデータが変更されるのを待っている場合は、キャッシュをクリアしない限り変更されないキャッシュデータをチェックしていないことに注意する必要があります。
  • サーバー設定 - このコンテキストでの長いポーリング要求は、(潜在的に)非常に長いページ要求と考えることができます。以下の例は20秒後に自分自身を殺します、しかしあなたのホストはそれよりずっと前にそれを殺すかもしれません、長い投票をかなり無力にします。
  • サーバーリソース - 各訪問者はサーバーリソースを拘束します。ほぼ 常に です。

これらの理由から、私はあなたが管理された環境でのみそれを使用することをお勧めします(例えばあなたがサーバーを管理し、そしてどのプラグイン/テーマが実行されているか)。しかし、その程度の制御では、代わりにWebSocketを使用することを検討することをお勧めします。

ロングポーリングを設定する

1.間隔を設定する

まず、間隔を 'ロングポーリング'に設定する必要があります。事実上これは0間隔を意味します。

function wpse162220_heartbeat_settings( $settings ) {
    $settings['interval'] = 'long-polling';
    return $settings;
}
add_filter( 'heartbeat_settings', 'wpse162220_heartbeat_settings' );

2.ロングポーリングリスナーを追加します

これは、クライアントに返されるデータを添付することを可能にするコールバックです。トラックチケットからNacinの例をコピーすると、2秒の期間があり、最大20秒待ちます。

function wpse162220_poll() {

    for ( $i = 0; $i < 10; $i++ ) {

        $val = apply_filters( 'wpse162220_poll', array() );

        if ( ! empty($val) ) {
            echo json_encode($val);
            exit;
        }

        sleep(2);
    }

    echo '0';
    exit;
}

add_action( 'heartbeat_tick', 'wpse162220_poll' );
add_action( 'heartbeat_nopriv_tick', 'wpse162220_poll' ); 

3.(a)データを添付する

これは、前のセクションの3回目のループの繰り返しまで待機してからデータを追加する「ダミー」関数です。

function wpse162220_populate_data( $value ){
    static $counter = 0;

    $counter++;

    if( $counter == 3 ){
        $value['wpse162220'] = 'foobar';
    }

    return $value;

}
add_filter( 'wpse162220_poll', 'wpse162220_populate_data' );

3.(b)受信データを表示する

私はここで怠惰になっていて、ジャバスクリプトを直接ページに印刷しました。通常は、JavaScriptファイルを登録してエンキューするという全体的な問題を経験します。

これはコンソールへの応答を表示することだけです。

function wpse162220_print_javascript(){
    ?>  
    <script>
    jQuery(document).ready( function($) {
        $(document).on( 'heartbeat-tick.wpse162220', function( event, data ) {
            if ( data.hasOwnProperty( 'wpse162220' ) ) {
                console.log( data );
            }
        });
    });
    </script>
    <?php
}
add_action( 'admin_print_footer_scripts', 'wpse162220_print_javascript', 999 );

あなたはそれが次のように何かを印刷するのを見るべきです

 Object {wpse162220: "foobar"} 

4秒ごとにコンソールに。

7
Stephen Harris