Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Problem z zatrzymującym się skryptem wysyłającym dane na serwer, funkcja fsockopen(); ma timeout a jednak skrypt nie odpowiada...
marcinpl87
post
Post #1





Grupa: Zarejestrowani
Postów: 21
Pomógł: 0
Dołączył: 22.05.2007

Ostrzeżenie: (0%)
-----


Witam
mam zdefiniowane kilka serwerów które pinguję i w pętli wywołuję wiele razy taki kod:
  1. if ($pinghandle = fsockopen($host, 80, $errno, $errstr, 30)) {
  2. @fputs( $pinghandle, $httpReq );
  3. while (!feof($pinghandle)) {
  4. $pingresponse = @fgets( $pinghandle, 128 );
  5. }
  6. @fclose( $pinghandle );
  7. }
w zmiennej $host mam adres serwera który będę pingował a w $httpReq jest to co do niego wysyłam. Pętla ma kilka tysięcy interacji i przy każdej iteracji mam zapytanie które mi zwiększa o 1 pewien rekord w bazie (to taki mój licznik pingnięć). No i bardzo często (średnio raz na 4 razy) w połowie pętli licznik zatrzymuje się i stoi w miejscu, choć w konsoli widzę że proces jest uruchomiony. Skrypt uruchamiałem albo z crona albo z konsoli bo wykonanie trwa kilka godzin więc jakbym go w przeglądarce uruchomił to raczej miałbym timeouta (IMG:style_emoticons/default/smile.gif) .
Najgorsze jest to że w funkcji fsockopen mam timeout w ostatnim argumencie i nawet jak ustawię ten timeout na 1 sekundę to widzę po komunikatach że ostatni komunikat jest przed tą funkcją i w tym miejscu iteracja pętli się zawiesza.
Podpowiedzcie co tu zrobić żeby zdefiniować jakiś działający timeout żeby w przypadku nie odpowiadającego serwera skrypt jechał dalej i nie zawieszał mi się tak jak teraz.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
XianN
post
Post #2





Grupa: Zarejestrowani
Postów: 57
Pomógł: 9
Dołączył: 12.11.2005
Skąd: ze wnowu?!

Ostrzeżenie: (0%)
-----


No wlasnie nie o to (IMG:style_emoticons/default/winksmiley.jpg) Teraz mozesz poczytac czym rozni sie while... od do...while (czyli tym, ze do... zrobi przynajmniej raz costam, sprawdzanie warunku petli wykonuje sie _PO_ wykonaniu petli)

A chodzi o to, ze fgets ma zabrac 127 bitow, ew linie ze znakiem jej konca lub napotkac koniec strumienia. Jesli trafisz na serwer, ktory nie zamyka socketa poprawnie to zawisniesz w tym miejscu, bo feof dalej zwraca false, z fgets nie ma juz nic do przeczytania. Zastosuj ten kod z safe_feof.

To moze byc jakos tak (nie mam teraz czasu, zeby zobaczyc czy to bedzie poprawnie...):
  1. <?php
  2. function safe_feof($fp, &$start = NULL) { // w manualu tutaj jest literowka
  3. $start = microtime(true);
  4.  
  5. return feof($fp);
  6. }
  7.  
  8. $start = NULL;
  9. $timeout = ini_get('default_socket_timeout');
  10.  
  11. echo $host."\n".'<br />';
  12. echo '1';
  13.  
  14. if ($pinghandle = fsockopen($host, 80, $errno, $errstr, 10))
  15. {
  16. @fputs( $pinghandle, $httpReq ); // to wysyla...
  17.  
  18. while(!safe_feof($fp, $start) && (microtime(true) - $start) < $timeout)
  19. {
  20. $pingresponse = @fgets( $pinghandle, 128 ); //wysyla dane o pingu <---- wcale nie! To nie wysyla, tylko odbiera informacje [!!!!!!]
  21. }
  22. fclose($pinghandle);
  23. }
  24. else
  25. {
  26. echo 'cos nie poszlo';
  27. }


A tak poza tym, to dlaczego uparles sie na socket? Chcesz zobaczyc czy dziala serwis, to zamiast robic to w ten sposob mozesz uzyc file_get_contents:
  1. $opts = array(
  2. 'http'=>array(
  3. 'method'=>"GET",
  4. 'header'=>"Accept-language: en\r\n" .
  5. "Cookie: foo=bar\r\n"
  6. )
  7. );
  8.  
  9. if ($context = stream_context_create($opts))
  10. {
  11. if (file_get_contents('http://www.google.pl/', false, $context, 0, 10)) // z ograniczeniem na dane, bo nie obchodzi nas co tam jest tylko czy w ogole jest cokolwiek
  12. {
  13. echo 'dziala';
  14. }
  15. }
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 12.10.2025 - 00:10