このトピックについて Google 検索を行ったところ、質問に対する答えが見つかりませんでした。
私が達成したいことは次のとおりです。
- クライアントがサーバー内の関数を非同期で呼び出す
- サーバーはその機能をバックグラウンドで実行し (その機能は時間がかかるため)、その間クライアントはハングしません。
- クライアントは常にバックグラウンド ジョブのステータスを要求するサーバーを呼び出します。
私の問題を解決するためのアドバイスをください。
どうもありがとうございました!^-^
このトピックについて Google 検索を行ったところ、質問に対する答えが見つかりませんでした。
私が達成したいことは次のとおりです。
私の問題を解決するためのアドバイスをください。
どうもありがとうございました!^-^
非同期呼び出しの言語を指定していませんが、両端で PHP を想定しています。最もエレガントな方法はこれだと思います:
HTML ページが読み込まれ、操作のランダム キーが定義されます (たとえば、rand()または既に使用可能なセッション ID を使用 [同じユーザーが 2 つの操作を開始する可能性があることに注意してください])。
HTML ページは、PHP スクリプトへの Ajax 呼び出しを行い、start_process.php
start_process.php実行exec /path/to/scriptname.phpしてプロセスを開始します。バックグラウンドでプロセスを開始する方法の提案については、ユーザー寄稿ノートをexec()参照してください。どちらが適切かは、主に OS によって異なります。
long_process.phpAjaxページが生成したランダムキーにちなんで名付けられたステータスファイルにステータスを頻繁に書き込みます
show_status.phpHTML ページは、ステータス ファイルを読み取り、進行状況を返すを頻繁に呼び出します。
長時間実行されている php プロセスについては、Google を使用してください (このトピックについては、Pekka が言及したメモを含め、多くの悪いアドバイスがあることに注意してください。これは Microsoft では機能しますが、他のものでは予測できない方法で失敗します)。
ソケットを介してリクエストに応答するサービスを開発できます (クライアントは fsockopen を使用して接続します)。これを実現する簡単な方法は、Aleksey Zapparov のソケット サーバー ( http://www.phpclasses.org/browse/package ) を使用することです。 /5758.html ) はソケットを介して着信するリクエストを処理しますが、これは単一のスレッドとして実行されるため、多くの処理を必要とするものにはあまり適していない可能性があります。別の方法として、Microsoft 以外のシステムを使用している場合は、スクリプトを [x]inetd から切り離すこともできますが、クライアントが切断されたときに終了しないようにするために、いくつかの巧妙な操作を行う必要があります。
クライアントが切断された後も物事を実行し続けるには、PHP コードを (Web サーバー経由ではなく) スタンドアロンの PHP 実行可能ファイルから実行する必要があります。新しいプロセス グループでプロセスを生成します (posix_setsid() および pcntl_fork() を参照)。クライアントが戻ってきて進行状況を確認できるようにする最も簡単な方法は、クライアントが読み取れる場所にステータスを書き出すようにサーバーを構成することです。
C.
すべての Ajax 呼び出しは、定義ごとに非同期です。
(厳密に必要な手順ではありませんが) AJAX を使用して呼び出しをインスタンス化すると、スクリプトは共有メモリ内のバックグラウンド ジョブのステータスへの参照を作成できます (または SQL テーブル内の一時的なエントリ、または temp.ファイル)、一意のジョブ ID の形式で。
その後、スクリプトはバックグラウンド プロセスを開始し、すぐにジョブ ID をクライアントに返すことができます。
その後、クライアントはサーバーを繰り返し呼び出して (別の AJAX インターフェイスなどを介して)、ジョブのステータス (「進行中」、「完了」など) を照会できます。
実行されるバックグラウンド プロセス自体が PHP で記述されている場合 (コマンド ライン PHP スクリプトなど)、それにジョブ ID を渡すことができ、意味のある進行状況の更新をクライアントに返すことができます (同じ共有メモリ領域に書き込むことにより、またはデータベース テーブル)。
実行するプロセス自体が PHP で記述されていない場合は、コマンドライン PHP スクリプトにラップして、実行中のプロセスの実行が終了したことを監視し (出力をチェックして成功したかどうかを確認し)、ステータスを更新できるようにすることをお勧めします。そのタスクのエントリを適切に。
注: これには共有メモリを使用するのがベスト プラクティスですが、たとえば共有ホスティングを使用している場合は使用できない場合があります。古いステータス エントリをクリーンアップする手段が必要であることを忘れないでください。そのため、「started_on」/「completed_on」タイムスタンプ値をそれぞれに保存し、古いデータのエントリを削除します (たとえば、completed_on タイムスタンプがX 分以上 - そして、理想的には、しばらく前に開始されたが、完了としてマークされていないジョブもチェックし、それらについて警告を発します)。