[PHP] Socket still alive...

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • TheDuke
  • Registratie: Juni 1999
  • Niet online
Het betreft het volgende...
Ik heb een PHP script dat ik draai vanaf de shell ( php -q /path/to/script.php ) en wat een oneindige while loop bevat. Dit scriptje moet eigenlijk 24/7 draaien... In deze loop word gecommuniceerd via non-blocking sockets...

Pseudo code achtig komt het neer op het volgende:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
while( true )
{
  // kijk of de andere kant de connectie gesloten heeft...
  if ( feof( $socket ) )
  {
     break; // of reconnect, whatever...
  }

  // kijk of er een packet available is en idle anders even.
  if ( $packet = fread( $socket , 4096 ) )
  {  
     // blabla doe leuke dingen hier...
  }
  else
  {
    usleep( 5 );
  }
}


In principe sluit de andere kant de socket nooit maar als het gebeurd dan kan ik dat detecteren door de feof() constructie aan het begin van de loop...

Als echter mijn kabel er voor enige tijd uit dondert (5 minuten of zo)... en hij komt even later weer up dan is de socket gewoon onbruikbaar. Echter, de feof() constructie werkt dan niet omdat nooit een end-of-file is ontvangen... In dit geval blijft ie dus doorloopen maar zal nooit meer iets ontvangen...

Ik wilde het eerst oplossen met socket_set_timeout(), maar dat is alleen van toepassing op het lezen/schrijven van en naar de socket en aangezien ik een non-blocking socket gebruik returned ie gewoon bij een leespoging en werkt dit dus volgens mij niet...

Is iemand hier bekend mee? Een andere oplossing zou een soort PING PONG systeem a la IRC zijn...

Acties:
  • 0 Henk 'm!

  • Evilbee
  • Registratie: November 2002
  • Laatst online: 18-09 17:40
kan je niet kijk of je een ipadres hebt door middel van $_SERVER["SERVER_ADDR"].
Als dat leeg is kan je een EOF te sturen.

LinkedIn - Collega worden?


Acties:
  • 0 Henk 'm!

  • TheDuke
  • Registratie: Juni 1999
  • Niet online
Script draait op een bak achter een NAT freesco routertje dus dat gaat niet lukken omdat $_SERVER['SERVER_ADDR'] een LAN ip bevat...

Acties:
  • 0 Henk 'm!

  • MikeN
  • Registratie: April 2001
  • Laatst online: 15-09 18:48
De enige manier om dit soort dingen te detecteren is door af en toe wat data te versturen. Een andere manier is er gewoonweg niet, want zonder een pakketje terug te krijgen waarin staat dat een pakketje niet afgeleverd kon worden (wat bij tcp zo hoort te gebeuren) weet je pc ook niet dat de socket niet meer werkt. (Mijn ervaring met PHP sockets is overigens dat ze lang niet altijd een foutmelding geven als ze deze wel horen te geven)
Een soort ping/pong systeem zou dus de oplossing zijn :)

[ Voor 16% gewijzigd door MikeN op 03-11-2003 18:42 ]


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Met sockets moet je ook niet op eof checken. Gewoon checken of het false returned.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
while( true )
{
  // kijk of er een packet available is en idle anders even.
  $packet = fread( $socket , 4096 );
  if ( $packet !== false ) {
      if ($packet) {  
         // blabla doe leuke dingen hier...
         $leuk = $anders;
         // reset $packet
         $packet = false;
     } else {
        usleep( 5 );
     }
  } else {
      break; // reconnect of whatever
  }
}

[ Voor 22% gewijzigd door stekkel op 03-11-2003 18:57 ]


Acties:
  • 0 Henk 'm!

Verwijderd

En waarom non blocking, als er niet is geconnect verbruik je onnodig veel cpu tijd

Acties:
  • 0 Henk 'm!

  • TheDuke
  • Registratie: Juni 1999
  • Niet online
De manier van stekkel werkt dus niet omdat een non-blocking socket bij fread altijd false retourneert als er geen data is...

En ik gebruik non-blocking sockets omdat het eigenlijke script meerdere socket verbindingen tegelijk moet onderhouden en als er een socket dan een tijdje geen data zou krijgen blijft heel het script daarop hangen terwijl andere sockets misschien wel data te verwerken hebben...

Ik denk dat MikeN gelijk heeft en dat het dus met PING PONG zal moeten zoals ik in de topic start ook al voorstelde...

Acties:
  • 0 Henk 'm!

  • MikeN
  • Registratie: April 2001
  • Laatst online: 15-09 18:48
TheDuke schreef op 03 november 2003 @ 19:05:
En ik gebruik non-blocking sockets omdat het eigenlijke script meerdere socket verbindingen tegelijk moet onderhouden en als er een socket dan een tijdje geen data zou krijgen blijft heel het script daarop hangen terwijl andere sockets misschien wel data te verwerken hebben...
Je zou kunnen proberen de socket_select of de stream_select functies daarvoor te gebruiken. Dan kun je gewoon blocking sockets gebruiken :)

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
TheDuke schreef op 03 november 2003 @ 19:05:
De manier van stekkel werkt dus niet omdat een non-blocking socket bij fread altijd false retourneert als er geen data is...
Wordt er false of '' (empty string) gereturned ?

De php manual gaf mij niet zo snel het antwoord . Non blocking connections zijn wat sumier gedocumenteerd.
Pagina: 1