Symfoware

Symfowareについての考察blog

PHP クライアントに応答した後、http connectionを閉じて重い処理を継続する

webサーバーへのリクエストが行われた時、メール送信や画像変換など
時間のかかる処理を行う場合、一旦レスポンスを返してからじっくり処理したい。

exec("nohup php background.php > /dev/null &");

を実行して、別プロセスに投げるのもよいですが、これだとwebリクエストとバッチ処理で
2つのphpプロセスが起動してしまうのがもったいない気がします。


Connection: close



レスポンスを書き込んだ後、とっとと接続を閉じればいいんじゃないかと思い調べていると、
こちらのページに行き着きました。

close a connection early
How to kill an HTTP connection and continue processing (PHP and Apache2)

「Connection: close」をヘッダーに出力すれば良いようです。

サンプルはこんな感じになりました。


  1. <?php
  2. ob_start();
  3. echo 'ok';
  4. header("Connection: close");
  5. header("Content-length: " . (string)ob_get_length());
  6. ob_end_flush();
  7. ob_flush();
  8. flush();
  9. sleep(10);
  10. file_put_contents('debug.txt', 'fin');



ブラウザでアクセスすると、すぐに「ok」と表示されます。
10秒後、サーバーにdebug.txtファイルが出力されました。

プログラムからのアクセスも、すぐに応答が得られます。
こんなPythonプログラムで試してみました。


  1. # -*- coding:utf-8 -*-
  2. import urllib2
  3. url = 'http://192.168.1.102:8000/'
  4. request = urllib2.Request(url)
  5. # 送信実行
  6. response = urllib2.urlopen(request)
  7. ret = response.read()
  8. print('Response:', ret)



実行すると一瞬で応答が得られます。


$ python sample.py
('Response:', 'ok')



これは使えそう。



【参考URL】

close a connection early
How to kill an HTTP connection and continue processing (PHP and Apache2)

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/28(木) 21:52:49|
  2. PHP
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Ubuntu Server 18.04にnodejs 8.11.3 LTSと最新版(10.4.1)をインストール | ホーム | Redis + FuelPHP 1.8でリストをソートして取得する(sort)>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
https://symfoware.blog.fc2.com/tb.php/2216-48817d38
この記事にトラックバックする(FC2ブログユーザー)