2009-07-10 10 views
14

サーバーからのクライアント要求Webページ。 Clentは、余分な計算を要求します。サーバーは一連の計算を実行し、利用可能になるとすぐに部分的な結果を送信します(テキスト形式、各行には別々の完全な項目が含まれています)。クライアントは、サーバーによって提供される情報を使用して、JavaScriptおよびDOMを使用してWebページを更新します。"HTTPストリーミング"(プッシュ)AJAXパターンのクロスブラウザ実装。

これは、AjaxパターンのサイトのHTTP Streamingcurrentバージョン)のパターンに適合すると思われます。

質問は、クロスブラウザ(ブラウザにとらわれない方法)で、JavaScriptフレームワークを使用しないで、またはjQueryのような軽量フレームワークを使用しないでください。

この問題は、ブラウザ間でXMLHttpRequestを生成することから始まりますが、主な項目は、すべてのブラウザが正しく実装されていないことです。onreadystatechangeからXMLHttpRequest;すべてのブラウザーが各サーバー上でonreadystatechangeイベントを呼び出すわけではありません(BTW。CGIスクリプト(Perl)内でサーバーを強制的にフラッシュする方法)。 Ajaxパターンのサンプルコードでは、timerを使用してこれを処理します。 onreadystatechangeから部分的な応答が検出された場合は、タイマーソリューションを削除する必要がありますか?


を追加しました2009年11月8日

現在のソリューション:私が使用した場合

function createRequestObject() { 
     var ro; 
     if (window.XMLHttpRequest) { 
       ro = new XMLHttpRequest(); 
     } else { 
       ro = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     if (!ro) 
       debug("Couldn't start XMLHttpRequest object"); 
     return ro; 
} 

:私はXMLHttpRequestオブジェクトを作成するには、次の機能を使用し
jQueryのような(できれば軽量の)JavaScriptフレームワークは、私がfallbackをしたいのですが、user jQueryをインストールしないことを選択します。

次のコードを使用してAJAXを開始します。いくつかのブラウザでは、サーバーが接続を終了した後にのみonreadystatechangeを呼び出すブラウザがあり(数十秒かかることがあります)、サーバーがデータをフラッシュするとすぐにはなりません(毎秒またはそれ以上頻繁に)。

function startProcess(dataUrl) { 
     http = createRequestObject(); 
     http.open('get', dataUrl); 
     http.onreadystatechange = handleResponse; 
     http.send(null); 

     pollTimer = setInterval(handleResponse, 1000); 
} 

handleResponse機能は、最も複雑なものですが、それのスケッチは次のようになります。それはより良くできますか?それは、軽量のJavaScriptフレームワーク(jQueryなど)を使用してどのように行われますか?

function handleResponse() { 
    if (http.readyState != 4 && http.readyState != 3) 
     return; 
    if (http.readyState == 3 && http.status != 200) 
     return; 
    if (http.readyState == 4 && http.status != 200) { 
     clearInterval(pollTimer); 
     inProgress = false; 
    } 
    // In konqueror http.responseText is sometimes null here... 
    if (http.responseText === null) 
     return; 

    while (prevDataLength != http.responseText.length) { 
     if (http.readyState == 4 && prevDataLength == http.responseText.length) 
      break; 
     prevDataLength = http.responseText.length; 
     var response = http.responseText.substring(nextLine); 
     var lines = response.split('\n'); 
     nextLine = nextLine + response.lastIndexOf('\n') + 1; 
     if (response[response.length-1] != '\n') 
      lines.pop(); 

     for (var i = 0; i < lines.length; i++) { 
      // ... 
     } 
    } 

    if (http.readyState == 4 && prevDataLength == http.responseText.length) 
     clearInterval(pollTimer); 

    inProgress = false; 
} 
+0

このコード例を返信として追加し、正しいものとしてマークする必要があります。 –

+4

"jQueryをインストールしないことをユーザーが選択した場合"? – Basic

+0

こんにちは、ちょうどあなたのソリューションに出くわしましたが、依然としてリクエストが終了していない間にresponseTextを取得しようとするとIEで動作しないことに恐れています。メッセージ:「この操作を完了するために必要なデータはまだ入手できません」 –

答えて

2

あなたがリンクした解決策は、実際にはAJAXではありません。彼らはそれをHTTPストリーミングと呼んでいますが、本質的にちょうど長いポーリングです。

これらのリンク先の例では、自分自身がファイヤーバグでかなり簡単に見ることができます。 Netパネルをオンにします - XHRエントリはありませんが、元のページをロードするのに10秒以上かかるだけです。これはHTMLの出力を遅延させるためにPHPの背後でPHPを使用しているからです。これは長いポーリングの本質であり、HTTP接続は開いたままであり、返される定期的なHTMLはjavascriptコマンドです。

あなたはjQueryの例にはsetTimeout()またはのsetInterval()

で、しかし、クライアント側で完全に

<script type="text/javascript"> 
    $(document).ready(function() 
    { 
    var ajaxInterval = setInterval(function() 
    { 
     $.getJSON(
     'some/servie/url.ext' 
     , { sample: "data" } 
     , function(response) 
      { 
      $('#output').append(response.whatever);   
      } 
    ); 
    }, 10000); 
    }); 
</script> 
+0

私は欲しいものをexaxtlyしません。サーバー上の計算では、プレーンテキスト形式の出力が生成されます。 XHRでは、クライアント(flush/timerのonreadystatechange)でこの応答を直接取得し、取得した部分データに従ってWebページを編集できます。 –

+0

あなたは何が欲しくないのですか?長いポーリング?私はどちらの方法も推薦していません - あなたの選択肢が何であるかを伝えています。 –

+0

長いプール(Comet)を使いたい場合は、Apacheがそのようなことをするように設計されていないため、Meteorサーバーソフトウェアの使用を検討する必要があります。そして、あなたのためのほとんどすべてを処理するjavascriptライブラリがあります。私はちょうどその名前を覚えていない、後でそれを投稿します。 – usoban

0

をポーリングを行うことを選ぶことができ、私は周回

を見てみましょう

設定やブラウザのスニッフィングに基づいて選択するいくつかのコメット転送の実装を使用します。異なるトランスポートの

http://orbited.org/svn/orbited/trunk/daemon/orbited/static/Orbited.js

を参照し、「Orbited.CometTransports」

を探していくつかは、バックエンドの実装にマッチしたので、また周回のためのサーバ側を見てする必要があります。

関連する問題