6

ファイルが変更され、Webページに出力された天気を更新し続けるログファイルであるLinuxのファイルを読んでいます。私はphp inotifyを使用してそれを行いますが、私の問題はそれがブロックされていることです。

テキストファイルを監視している間に他のことをできるように、PHP inotify をノンブロッキングにするにはどうすればよいですか?

<?php

$fd = inotify_init();


$watch_descriptor = inotify_add_watch($fd, '/tmp/temp.txt', IN_MODIFY);


touch('/tmp/temp.txt');


    $events = inotify_read($fd);

    $contents = file_get_contents('/tmp/temp.txt');
    echo $contents;


inotify_rm_watch($fd, $watch_descriptor);
fclose($fd)

?>

それともJavaでこれを行うことができますか?..ありがとう。

4

5 に答える 5

7

はい、できます。マニュアルはご覧になりましたか?ノンブロッキング イベント コールバックの例を提供します。この回答で十分な回答が得られない場合は、さらに情報を追加してください。

http://php.net/manual/en/function.inotify-init.php

// Open an inotify instance
$fd = inotify_init();

// - Using stream_set_blocking() on $fd
stream_set_blocking($fd, 0);

// Watch __FILE__ for metadata changes (e.g. mtime)
$watch_descriptor = inotify_add_watch($fd, __FILE__, IN_ATTRIB);

// generate an event
touch(__FILE__);

// this is a loop
while(true){

  $events = inotify_read($fd); // Does no block, and return false if no events are pending  

  // do other stuff here, break when you want...
}

// Stop watching __FILE__ for metadata changes
inotify_rm_watch($fd, $watch_descriptor);

// Close the inotify instance
// This may have closed all watches if this was not already done
fclose($fd);
于 2012-10-29T15:47:44.017 に答える
2

ライクさんのおっしゃる通りです。ブロッキングまたはノンブロッキングのいずれかを使用できます。ノンブロッキングの場合は、ポーリングする必要があります。あなたが望むのは、マルチスレッドの方法でブロックしていると思います。一方のスレッドはブロッキングまたはノンブロッキングの頻繁なポーリング モードで動作し、もう一方のスレッドは別の処理を行います。

于 2012-12-07T11:02:02.383 に答える
1

を使用することで、このことがはるかに簡単になることをお勧めしますnode.js.

以下のコードのみが必要です: (filename:watch.js)

    var fs = require('fs');
    var file = '/tmp/temp.txt/';
    fs.watchFile(file, function (curr, prev) {
        console.log('the current mtime is: ' + curr.mtime);
        console.log('the previous mtime was: ' + prev.mtime);
    });

その後、実行できます:

    node watch.js

それは永続的に実行されます。

node.jsJavaScript を使ってserver-sideプログラムを書くにはモデルnon-blocking I/Oがあります。この種のことを簡単に行うのに役立ちます。

ここにいくつかの関連文書がありますfs.watchFile

于 2013-07-18T03:48:43.937 に答える
1

React ライブラリを見ることができます。これは、リアクター パターンに基づいて、PHP でイベント駆動型のノンブロッキング I/O Api を提供します: http://reactphp.org/

于 2013-07-19T10:10:46.657 に答える
1

あなたが説明したようなバックグラウンドタスクを管理する方が簡単だと思うので、このようなものに対する私の好みは Java を使用することです。

バックエンド

私のアプローチは、Java EE を使用して、スケジューラ サービスを実装するシングルトン スタートアップ スレッドを作成することです。シングルトン スタートアップ スレッドを使用する理由は、ジョブをバックグラウンド プロセスとして実行できるようにすることです。これにより、非ブロッキングになり、アプリケーションの残りのリソースを解放できます。また、クラスのメソッドを呼び出すだけでスレッドにアクセスできます。更新のために「n」秒/分ごとにファイルを読み取るようにタスクをスケジュールすると、これらをフロントエンドで利用できるようになります。

基本的な例:

@Singleton
@Startup
public class Scheduler {

    private static int count = 0;
    private Weather weather;

    public Weather getWeather() {
        return weather;
    }

    @PostConstruct
    public void onStartup() {
        System.out.println("Initialization success.");
    }

   @Schedule(second="*/10", minute="*", hour="*")
   public void execute() {

      byte[] encoded = Files.readAllBytes(Paths.get("weather_updates.txt"));
      String weatherUpdateStr = encoding.decode(ByteBuffer.wrap(encoded)).toString();

      weather = new Weather();
      weather.parse(weatherUpdateStr);

      // Possible addition of logic for push to web socket
   }
}

この基本的な例では、Web アプリケーション コンテナー (JBoss 7 の使用をお勧めします) の起動時に sigleton スレッドを作成します。次に、10 秒ごとに実行されるスケジュールされたタスクを作成します。提供されているコードは、基本的な Java 7 ファイルを文字列に読み取り、文字weather.parse()列を Weather オブジェクトに変換するロジックを含める必要があります。気象オブジェクトは、Web ソケットを介してプッシュされるか、フロントエンドの AJAX 要求を介してポーリングされる準備が整います。

フロントエンド

ここで提案する 2 つの可能なアプローチがあります。

  1. HTML5 を使用した Web ソケット
  2. AJAX 呼び出し

1. Web ソケット

Web ソケットは、ページを更新したり AJAX 呼び出しを使用したりせずに動的コンテンツを提供する方法として、HTML5 に導入されました。HTML5 の websocket の優れた紹介を次に示しますJava を使用して HTML5 WebSocket をセットアップする方法の別の優れた例を次に示します

2.AJAX 呼び出し

jQuery は、AJAX 用の優れた API を提供します。一部の機能を断続的に実行するTimeoutタスクを jQuery に実装できます。実装したい機能は、AJAX Get requestです。

基本的な例:

$.ajax({
    url: "getWeatherUpdate.html",
    error: function(){
        // will fire when timeout is reached
    },
    success: function(){
        // Update your webpage with weather info
    },
    timeout: 3000 // sets timeout to 3 seconds
});
于 2013-07-18T20:53:25.037 に答える