-
処理時間が長いとき、すばやくページ表示したい(6)
フォーム送信後、サーバ側の処理時間が長いとき、なかなか画面が変わらないことがあります。サーバ側の処理時間が長いときでも、すばやくページを表示するいくつかの方法について説明します。
(6) 前回(5)の改良版
前回の(5)では、ブラウザと直接つながっているサーバ側スクリプトがメイン処理をしました。connection:closeとflush()を使った、変則的な方法なので、ブラウザによっては挙動が違うかもしれません。例えばケータイです。softbank 931SHでは、期待どおりだったのは(2)だけで、(1)(3)(4)(5)は期待どおりではありませんでした。
そこで、ブラウザ – task.php – task_server.php、という構成にします。task.phpからは、サーバ内通信で、task_server.phpへリクエストします。task_server.phpは、チケットを取得し、メイン処理をします。task.php と task_server.php は私の手の届く範囲ですから、多少変則的なことをしても、ブラウザの違いによる影響を受けません。
オモテ向きのページ遷移は、form.html ⇒ task.php ⇒ show_status.php ⇒ thanks.html となります。オモテにはでてきませんが、task_server.php がメイン処理を担当します。

最初は、task.phpで、ここでのポイントは1つです。
task_server.phpとの通信に、file_get_contents()を使わないようにします。fgets()で1行読み込んだら、すぐにfclose()します。
task_server.phpの設置場所に合わせて、YOUR_HOST、YOUR_PATHを置き換えてください。また、fopenで、http:// を使えないphp設定のwebサーバもあります。その場合は、このスクリプトは動きません。
<?php $url = "http://YOUR_HOST/YOUR_PATH/task_server.php"; $fp = fopen( $url, "rb" ); assert( $fp ); $buf = fgets( $fp ); fclose( $fp ); $vars = unserialize( $buf ); session_start(); $_SESSION['ticket_id'] = $vars['ticket_id']; session_write_close(); ?> <meta http-equiv="refresh" content="0; url=show_status.php" />
次は、task_server.php です。チケットIDをserializeして返します。このとき、最後に、”\n” を追加します。これがないと、task_server.phpが終わるまで、呼び出し元の task.php の fgets($fp) が終わりません。
<?php require( 'ticket.php' ); $ticket = new Ticket; $ticket_id = $ticket->create( 'Start' ); $vars['ticket_id'] = $ticket_id; $buf = serialize( $vars ); ob_start(); echo "$buf\n"; $buf = ob_get_clean(); $len = strlen( $buf ); header( "connection: close" ); header( "Content-length: $len" ); echo $buf; flush(); // メイン処理 for ( $i = 0; $i < 10; ++$i ) { sleep( 1 ); $ticket->update( $ticket_id, "Running\t$i/10" ); } $ticket->update( $ticket_id, 'Finished' ); exit(); ?>ケータイの softbank 931SHでの結果は、(4)と同じく、metaタグのリロード回数の制限があるのか、途中で「ページを表示できません」と表示されます。その後、手動で「更新」すると、thanks.htmlへ移動しますので、サーバ側は無事にメイン処理を終えているようです。プログレスバーをあきらめて、ページ遷移を変更するのも手です。最近のケータイ機種なら、FlashやAjaxを使う方法もありそうです。
このテーマは今回で終わりです。
task.phpとtask_server.phpの接続が変則的で気になる人向けに、もう1つ方法を紹介します。
task.php がバッチをキューに登録します。1分に1回起動するcronジョブや常駐サービスが、キューからバッチを取り出して、処理をします。これは、先祖がえり的なものを感じますね。
Leave a reply



最近のコメント