2016-10-25 22 views
1

私はtcpソケットを通してクライアントからの接続を受け入れるためにserver.phpを書いています。 と私はバックグラウンドでPHPスクリプトを実行する

set_time_limit(0); 
include_once("include/class.db.php"); 
while (true) 
{ 
receive_message('x.x.x.x','8855',50); 
} 

function receive_message($ipServer,$portNumber,$nbSecondsIdle) 
{ 
// creating the socket... 
$socket = stream_socket_server('tcp://'.$ipServer.':'.$portNumber, $errno, $errstr); 
if (!$socket) 
{ 
echo "$errstr ($errno)<br />\n"; 
} 
else 
{ 
// while there is connection, i'll receive it... if I didn't receive a message within $nbSecondsIdle seconds, the following function will stop. 
while ($conn = @stream_socket_accept($socket,$nbSecondsIdle)) 
{ 
$message= fread($conn, 1024); 
if($message!=''){ 
echo 'I have received that : '.$message; 
// insert into database 
$sql = "insert into `data_log` (`id`,`message_text`) values (NULL,'$message')"; 
$query=mysql_query($sql) or die(mysql_error() . "<br>" . $sql); 
} 
fputs ($conn, "OK\n"); 
fclose ($conn); 
} 
fclose($socket); 
} 
} 

を使用し、私は、バックグラウンドでサーバーを実行するために

nohup php server.php >/dev/null 2>&1 & 

を実行しました。それはすべて正常に動作します。しかし、ソケットは数時間後に自動的に閉じたり、数時間後にPHPスクリプトが終了すると言うことができます。手動で停止するまで、私の必要性はバックグラウンドでスクリプトを実行することです。 何が問題なのですか? ありがとうございます

+0

でも、プログラム出力を/ dev/nullではなくログファイルにパイプしてトラブルシューティングを開始できます。予備的な手段として、毎回cronjobをチェックしてスクリプトがまだ実行中であるかどうかをチェックし、そうでない場合はcronjobを再起動することができます。 –

+0

おそらくしばらくしてdb接続が閉じられ、スクリプトの実行が停止したか、メモリが不足している可能性があります。最初に接続を確認してください。 –

+0

@FranzGleichmannは、/ dev/nullの代わりにファイルを使用すると、1日で約20GBの膨大なファイルが作成されます。だから私は/ dev/nullを使用して –

答えて

0

あなたのスクリプトをループで実行して、sleep時間を数秒間スリープ状態にすることができます。たとえば、次のように

while(1 < 2) { 
    //your code 
    sleep(1); 
} 

それがバックグラウンドで実行され、それが実行しているかどうかをチェックするためにそのそれではあなたは

nohup php yourscript.php & 

としてnohupコマンドを使用することができます。 topコマンドを使用して、バックグラウンドporcessが実行されていることを確認します。

1

phpがそのようなものに使用されるはずではないことをはっきりと理解する必要があります。 PHPスクリプトが実行され、いくつかの作業と死があります - それはその運命です。そして、あなたがPHP上で作成する悪魔はなんらかの理由で死ぬでしょう。

しかし、phpで悪魔を作成するのは非常に簡単です。だから何をすべきか?

デーモンスクリプトの場合は、スーパーバイザを実装する必要があります。

まず、上記のとおり、スクリプトを作成します。場合によっては、このスクリプトにいくつかのブレーク条件を実装すると便利です。たとえば、プロセスメモリの制限など、memory_get_usage

第2に、あなたのデーモン用のスーパーバイザースクリプトを実装します。そのことは何ですか?単純に、cronから1分ごとに呼び出す必要のあるスクリプトです。このスクリプトは次のようになります。

  1. 悪魔スクリプトがまだ実行中であることを確認してください。現在、シェルを介して実行中のプロセスをこの目的のために使用することができます。
  2. デーモンが終了した場合、別のインスタンスを実行します。
  3. 出口

監督の概念は非常に便利です。そこにビジネスロジックを実装することができます。悪魔のインスタンスの正確な数を実行します。 RabbitMQの消費者のようなスクリプトのためのその素晴らしい。

関連する問題