0

本当にシンプルなコメットテストページをまとめようとしています。#TextHistoryのdivIDを持つメインクライアントページがあります。このページのjavascriptは、javascriptを使用して値を更新し、それをクライアントページにフラッシュバックするbackend.phpへのオープン接続を作成する必要があります。これを正しく行っているかどうかは本当にわかりません...基本的な「ロングポーリング」を実装するにはどうすればよいですか?

私が見つけたのは、クライアントページ(FireFox)で、backend.phpが何も返さず、10秒後にタイムアウトしたようです。backend.phpのphpループを削除すると、常に「DefaultData」が返され、すぐにTextHistoryDIVに追加されます。近くにいるような気がしますが、何か間違ったことをしています。ここでの奇妙なフォーマットについて申し訳ありませんが、一部のヘッダーとphpタグは許可されていないようです。

クライアント側:

 $(document).ready(function() {

    waitForMsg(); /* Start the inital request */


});


    function addmsg(type, msg){
        /* Simple helper to add a div.
        type is the name of a CSS class (old/new/error).
        msg is the contents of the div */
        $("#TextHistory").append(
            "<div class='msg "+ type +"'>New MSG: "+ msg +"</div>"
        );
    }

    function waitForMsg(){
        /* This requests the url "msgsrv.php"
        When it complete (or errors)*/
        $.ajax({
            type: "GET",
            url: "backend.php",

            async: true, /* If set to non-async, browser shows page as "Loading.."*/
            cache: false,
            timeout:50000, /* Timeout in ms */

            success: function(data){ /* called when request to barge.php completes */
                addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
                setTimeout(
                    'waitForMsg()', /* Request next message */
                    1000 /* ..after 1 seconds */
                );
            },
            error: function(XMLHttpRequest, textStatus, errorThrown){
                addmsg("error", textStatus + " (" + errorThrown + ")");
                setTimeout(
                    'waitForMsg()', /* Try again after.. */
                    "15000"); /* milliseconds (15seconds) */
            },
        });
    };


    </script>


 </head>

 <body>


  <div id="container">

    <div id="main">

     <h2>Text Scrolling Test</h2>


      <div id="TextHistory">

       <p>First default line of text</p>
       <p>Second default line of text</p>

      </div>

    </div>

  </div>



 </body>


</html>

呼び出されるBackend.php:

<---php start --->

session_start();

  header("Cache-Control: no-cache, must-revalidate");

  header("Expires: Mon, 26 Jul 2012 05:00:00 GMT");

flush();

<---php end --->

次に、デフォルトのhtml doctype、head、meta、jquery include、

その後、体内で:

 <div id="LastMsg">DefaultData</div>

<---PHP Start --->

     $OutputMsg = "Initial";


    while (true) {

    $OutputMsg .= "Something.";

  echo "

      <script type=\"text/javascript\">
        $('#LastMsg').html(\"<p>$OutputMsg</p>\");
      </script>

     ";



      flush(); // Ensure the Javascript tag is written out immediately
      sleep(1);
    }



  <---PHP END --->
4

2 に答える 2

1

出力バッファリングでflush()を使用することを検討する必要があります。PHPは内部で奇妙なことを行うため、通常は両方を使用する必要があります。

ob_start();

while(true){

if($ newcontent){echo'私の新しいコンテンツ'; ob_flush(); 流す(); }

sleep(1); }

ただし、長いポーリングへのアプローチは正しくありません。クライアントにプッシュするデータができるまで、ブラウザ接続を永久に開いたままにしたくはありません。データを受信したら、接続を閉じてから再度開きます。それは基本的にメモリ/接続管理と関係があります。

于 2011-01-27T22:37:05.093 に答える
0

PHPは仕事に適したツールではないため、そもそもPHPでロングポーリングを行うべきではないと思います(#1を参照)。PHPにはスレッドモデル(シェアードナッシングアーキテクチャ)がなく、拡張性が低くなります。

たとえば、これにはpusherapp (小さなアプリの場合は無料)を使用できます。これにより、はるかに効率的で実装が簡単になります。

于 2011-01-27T22:44:29.703 に答える