2012-10-29 13 views
5

Czytam plik w Linuksie, który jest plikiem dziennika, który stale aktualizuje pogodę, plik zmienił się i wyświetla go na stronie internetowej. Robię to za pomocą phot inotify, ale moim problemem jest to, że blokuje.PHP Inotify Bez blokowania

W jaki sposób mogę zrobić php inotify bez blokowania, więc mogę robić inne rzeczy podczas monitorowania pliku tekstowego ?.

<?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) 

?> 

Czy mogę to zrobić w java? .. Dzięki.

Odpowiedz

3

Tak, można. Czy spojrzałeś na instrukcję? Zapewnia niezablokowane przykłady oddzwonienia zdarzeń? Jeśli ta odpowiedź nie odpowie na ciebie w odpowiedni sposób, dodaj więcej informacji.

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); 
+0

Cóż, to nie działa, nadal ładuje się, nawet jeśli jest w trybie bez blokowania i nie można zrobić nic innego, gdy wciąż czeka na dane. Potrzebuję go do wyrzucenia danych po dokonaniu zmian w plikach i robieniu czegoś innego w php. – demic0de

+3

Właściwie to działa, ale Layke zawierał także blokujące wywołanie odczytu. Poprawiłem kod. –

2

To jak Layke powiedział. Możesz go zablokować lub zablokować. Jeśli nie blokujesz, musisz sondować. Myślę, że to, czego chcesz, blokuje się w sposób wielowątkowy. Jeden wątek działa w trybie blokowania lub braku blokowania, częstego odpytywania, podczas gdy drugi wątek robi coś innego.

+0

Czy możesz podać przykład, jak głosować inotify? – Alex

1

I sugerują, że to będzie dużo łatwiejsze do tej rzeczy za pomocą node.js.

wystarczy poniższy kod: (Nazwa pliku: 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); 
    }); 

następnie można go uruchomić:

node watch.js 

Będzie działać z uporem.

node.js przy użyciu javascript do napisania programu server-side, ma model non-blocking I/O. Pomoże ci to łatwo zrobić tego rodzaju rzeczy.

Oto powiązany dokument fs.watchFile

+0

Czy katalogi zegarka node.js również mogą uruchamiać tę funkcję, gdy pliki są dodawane do podkatalogu katalogu, który jest śledzony? – Alex

+0

tak, może oglądać plik w całym katalogu. ale nie włączaj podkatalogu do metody raw node.js. ale możemy zrobić to za pomocą małego kodu, jest też ktoś, kto wykonał tę pracę. node.js jest potężny i lekki. dowolne pytanie, prosimy o komentarz tutaj. – srain

+0

funkcja zostanie uruchomiona, gdy plik zostanie dodany lub przeniesiony z obserwowanego katalogu. – srain

1

Moje preferencje na coś takiego byłoby wykorzystanie Javy jak łatwiej zarządzać zadaniami tła jak co opisujesz.

Backend

Moje podejście byłoby użyć Java EE, aby utworzyć singleton wątku startowego, który implementuje usługę harmonogramu. Powodem użycia pojedynczego wątku startowego jest to, że twoje zadanie może działać jako proces w tle, a zatem nie jest blokowane, uwalniając zasoby dla reszty aplikacji. Dostęp do wątku można uzyskać również po prostu wywołując metodę na klasie. Możesz zaplanować, że zadanie będzie odczytywać twój plik co każde 'n' sekunda/minutę itd. Dla każdej aktualizacji, a następnie można je udostępnić w twoim interfejsie.

Podstawowe Przykład:

@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 
    } 
} 

Ten prosty przykład tworzy wątek sigleton jako kontenera aplikacji internetowych (polecam przy użyciu JBoss 7) uruchamia. Następnie tworzy zaplanowane zadanie, które wykonuje się co 10 sekund. Podany kod wykonuje podstawowy plik Java 7 w postaci ciągu znaków, a kod weather.parse() powinien zawierać pewną logikę, która przekształci ciąg znaków w obiekt Weather. Obiekt pogody jest następnie gotowy do przepchnięcia przez gniazdo sieciowe lub odpytywany przez niektóre żądania AJAX na interfejsie.

Frontend

Istnieją dwa możliwe podejścia Proponuję tutaj:

  1. gniazda sieci wykorzystujące HTML5
  2. AJAX wzywa

1. Gniazda sieci

Gniazda sieciowe zostały wprowadzone do HTML5 jako sposób dostarczania dynamicznej zawartości na stronie bez potrzeby odświeżania lub korzystania z wywołań AJAX. Here to świetne wprowadzenie do websockets w HTML5. Here is another great example of how to set up HTML5 websockets with Java.

2. AJAX wzywa

jQuery stanowi wielką API dla AJAX. W jQuery można wdrożyć zadanie Timeout, które będzie sporadycznie wykonywać niektóre funkcje. Funkcją, którą chcesz zaimplementować, jest i AJAX Get request.

Podstawowe przykład:

$.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 
}); 
1

Można spojrzeć do biblioteki zareagować, to dostarczenie zdarzeniami, non-blocking I/O API w PHP, w oparciu o wzór reaktorze: http://reactphp.org/

+0

A w szczególności: https://github.com/mkraemer/react-inotify – TheStoryCoder

Powiązane problemy