13

私は、一連のワーカーインスタンスのいずれかにタスクをファームアウトするマスター/ワーカーシステムにタスクを送信するWebアプリケーションに取り組んでいます。ワークキューマスターは(完全に別のマシン上で)別のプロセスとして実行され、タスクはHTTP/RESTリクエストを介してマスターに送信されます。タスクがワークキューに送信されると、クライアントアプリケーションは別のHTTPリクエストを送信して、タスクに関するステータス情報を取得できます。

私のWebアプリケーションでは、タスク処理がどの程度進んだかをユーザーに示す、ある種のプログレスバービューを提供したいと思います。これを実装する明白な方法は、送信されたタスクのステータスについてワークキューを定期的にポーリングするAJAXプログレスメーターウィジェットです。私の質問は、頻繁なポーリングなしでこれを達成するためのより良い方法はありますか?

クライアントWebアプリケーションで、ワークマスターからの通知をリッスンできるサーバーソケットを開くことを検討しました。私が持っていたもう1つの同様の考えは、ステータス通知にXMPPまたは同様のプロトコルを使用することです。(もちろん、いずれかの方法で通知を提供するには、マスター/ワーカーシステムを更新する必要がありますが、そのためのコードを所有しているため、必要な更新を自分で行うことができます。)

このような通知システムを設定するための最良の方法について何か考えはありますか?余分な労力はそれだけの価値がありますか、それとも単純なポーリングソリューションが進むべき道ですか?

4

7 に答える 7

11

ポーリング

クライアントは、応答のステータスを取得するためにサーバーをポーリングし続けます。

長所

  • 本当にRESTfulであるということは、キャッシュ可能でスケーラブルであることを意味します。

短所

  • サーバーをあまりポーリングしたくない場合は、最高の応答性ではありません。

持続的接続

サーバーは、応答が完了するまでクライアントとのHTTP接続を閉じません。サーバーは、HTTPマルチパートを使用して、この接続を介して中間ステータスを送信できます。

コメットは、この動作を実装するための最も有名なフレームワークです。

長所

  • 最高の応答性、サーバーからのほぼリアルタイムの通知。

短所

  • Webサーバーでは接続制限が制限されており、接続を長時間開いたままにしておくと、せいぜいサーバーに負荷がかかり、最悪の場合、サーバーがサービス拒否攻撃にさらされる可能性があります。

サーバーとしてのクライアント

別のRESTfulアプリケーションであるかのように、サーバーにステータスの更新とクライアントへの応答を投稿させます。

長所

  • すべての世界で最も優れているのは、サーバー側でもクライアント側でも、応答を待つためにリソースが無駄になることはないということです。

短所

  • クライアントに完全なHTTPサーバーとWebアプリケーションスタックが必要です
  • デフォルトの「着信接続がまったくない」ファイアウォールとルーターが邪魔になります。

あなたの考えや新しい方法を追加するために自由に編集してください!

于 2009-06-25T14:01:10.440 に答える
6

私はそれがいくつかの要因に依存すると思います

  • フィードバックの正確さ(1パーセント、5パーセント、50パーセント)
    正確なフィードバックは、ある種のプログレスバーとコメットスタイルのプッシュを追求する価値があります。「忙しい...ちょっと待って...ほぼそこに...完了」としか言えない場合は、単純なajax「まだそこにいますか」という投票の方が確かにコーディングが簡単です。
  • クライアントが完了メッセージをタイムリーに表示する必要があるか
  • 各タスクにかかる時間(1秒、10秒、10分)
    1秒は、少し意味がありません。10秒はそれだけの価値があります。10分は、ユーザーがコーヒーブレイクに行くことを提案したほうがよいことを意味します:-)
  • 同時リクエストの数
    「特別な」サーバーがない限り、ライブプッシュスタイルのシステムは接続を消費する傾向があり、すぐに限界に達します。派手なプログレスバーのためにもっと多くのウェブサーバーを投入しなければならないことは、予算を傷つけるかもしれません。

私は871184にいくつかのサンプルコードを持っています。これは、うまく機能しているように見える「永遠のフレーム」を手で巻いたものを示しています。私が開発したプロジェクトはそれほど難しくはありませんが、操作には数秒かかり、かなり正確なパーセントを与えることができます。コードはasp.netとjqueryを使用しますが、一般的な手法はどのサーバーとjavascriptフレームワークでも機能します。

編集ジョンが指摘しているように、ステータスレポートはおそらくRESTfulサービスの仕事ではありません。ただし、サービスをポーリングするサーバー上のページにフックするiframeをクライアントで開くことができないということは何もありません。理論によれば、サーバーとサービスは少なくとも互いに近くなるでしょう:-)

于 2009-06-25T13:47:59.267 に答える
2

彗星を調べてください。サーバーに単一の要求を行うと、サーバーはステータスの更新が発生するまで接続をブロックして開いたままにします。それが発生すると、応答が送信されてコミットされます。ブラウザはこの応答を受信して​​処理し、すぐに同じURLを再要求します。その効果は、イベントがブラウザにプッシュされることです。長所と短所があり、すべてのユースケースに適しているとは限りませんが、最もタイムリーなステータス更新を提供します。

于 2009-06-25T13:32:32.557 に答える
1

私の意見はポーリングソリューションに固執することですが、 HTTPプッシュテクノロジーに関するこのウィキペディアの記事に興味があるかもしれません。

于 2009-06-25T13:26:06.253 に答える
1

RESTは、要求/応答プロトコルであるHTTPに依存しています。ステータスを付けてクライアントにコールバックする純粋なHTTPサーバーを取得することはないと思います。

その上、ステータスレポートはサービスの仕事ではありません。ステータスをいつ報告するか、または報告するかどうかを決定するのはクライアント次第です。

于 2009-06-25T13:27:12.880 に答える
1

私が使用したアプローチの1つは次のとおりです。

  1. ジョブがサーバーにポストされると、サーバーはpubnub-channel idを返します(代わりに、GoogleのPUB-SUBの種類のサービスを使用することもできます)。
  2. ブラウザ上のクライアントはそのチャネルにサブスクライブし、メッセージのリッスンを開始します。
  3. ワーカー/タスクサーバーは、進行状況を更新するために、そのpubnubチャネルでステータスを公開します。
  4. サブスクライブされたpubnub-channelでメッセージを受信すると、クライアントはWebUIを更新します。
于 2020-09-24T04:14:09.440 に答える
0

自己更新iframeを使用することもできますが、AJAX呼び出しの方がはるかに優れています。他に方法はないと思います。

PS:クライアントからソケットを開く場合、それはあまり変わりません-PHPブラウザーはページをまだ「ロード中」と表示しますが、これはあまりユーザーフレンドリーではありません。(前に他のものを表示するためにバッファーをプッシュまたはフラッシュすると仮定します)

于 2009-06-25T13:24:24.477 に答える