IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Comment générer une erreur quand pas de réponse du serveur ?


Sujet :

Langage PHP

  1. #1
    Membre actif Avatar de renaudjuif
    Inscrit en
    Avril 2006
    Messages
    325
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 325
    Points : 258
    Points
    258
    Par défaut Comment générer une erreur quand pas de réponse du serveur ?
    Salut,

    Je développe un site qui interroge un serveur distant via des web services.
    Existe-t-il un moyen simple de générer une erreur quand le serveur distant de web services est tombé ?
    Je ne veux pas de ping à chaque accès client (qui pénaliserait le client en temps de réponse), mais plus un truc du genre "timeout" par exemple, où on considère que si on n'a pas de réponse du serveur distant au bout de 30 secondes, on redirige le client vers une page d'erreur.
    Ou une autre méthode, mais qui n'interroge pas le serveur avant chaque accès. Les accès concurrents seront nombreux, c'est pourquoi je ne veux pas surcharger le serveur avec des requêtes...
    Pour l'instant, quand le serveur est tombé, on voit la barre de progression dans le status du browser, le sablier, la page html est figée, et rien de plus...

    Merci de vos éclaircissements.
    C'est curieux chez les marins ce besoin de faire des phrases !

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    Comment interroges-tu le serveur distant? Une redirection ou une capture de contenu?

    La gestion des timeout n'a pas de solution simple, il faut passer par les sockets pour tester la durée de l'établissement d'une connexion (fsockopen) et les flux (stream_set_timeout) pour les temps de réponse de la page une fois la connexion établie. Je dois avoir dans mes cartons, une fonction perso qui fait ça.

    Dans le problème que tu décris, si la page consultée est toujours la même tu pourrais envisager de tester les temps de réponse (connexion et flux) en cron, toutes les minutes par exemple, et mettre un flag dans un fichier plat.

    Dans ton script, tu lis le flag, et si c'est bon, tu accèdes normalement à la page, en contenu (file_get_contents) ou redirection (header location)
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

  3. #3
    Membre actif Avatar de renaudjuif
    Inscrit en
    Avril 2006
    Messages
    325
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 325
    Points : 258
    Points
    258
    Par défaut
    merci pour ta réponse ripat,

    Le test en cron me plait bien.
    En fait, j'interroge un serveur IIS via soap/xml, sur des pages différentes. Je récupère donc un flux.
    Mais je peux effectivement prendre une page de référence qui me servira de tests.
    C'est curieux chez les marins ce besoin de faire des phrases !

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    J'ai retrouvé mes fonctions de flux avec timeout. J'en ai 3: fopen, fsockopen ou Curl. La plus simple c'est avec Curl.

    Laquelle veux-tu?
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

  5. #5
    Membre actif Avatar de renaudjuif
    Inscrit en
    Avril 2006
    Messages
    325
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 325
    Points : 258
    Points
    258
    Par défaut
    Super,

    Je dirais Curl et au choix, fopen ou fsockopen
    A priori je vais utiliser curl, mais je ne suis pas sur que le client ait installé la librairie.
    Donc au cas ou, j'utiliserai fsockopen, par exemple.

    Merci
    C'est curieux chez les marins ce besoin de faire des phrases !

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    • Curl
      De loin ma fonction la plus complète car elle retourne un tableau avec les temps de réponse (dns lookup, connection, transfert) avec la fonction curl_getinfo(). Je recommande chaudement dans ton cas car il te suffirait de mettre la valeur de $elapsed['total_time'] dans ton fichier plat et tu auras non seulement l'état de disponibilité de ta page mais en plus, le temps de réponse.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      function CurlFileGetContents($adresse, $timeout = 10){
        $ch = curl_init($adresse);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_USERAGENT, "PHP script");
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        $page    = curl_exec($ch);
        $elapsed  = curl_getinfo ($ch);
        echo '<pre>'; print_r($elapsed);
        $CurlErr = curl_error($ch);
        $elapsed  = curl_getinfo ($ch);
        curl_close($ch);
        if ($CurlErr){
          echo $CurlErr;
          return false;
        }else{
          return $page;
          // ou bien
          //return true;
        }
      }
      // utilisation:
      $timeout = 5;
      $adresse = 'http://www.developpez.net/forums/';
      echo CurlFileGetContents($adresse, $timeout);
    • Fopen().
      Un peu du bidouillage mais ça marche.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      function monFopen($adresse, $timeout = 10){
        $old  = ini_set('default_socket_timeout', $timeout);
        $fp   = fopen($adresse, 'r');
        ini_set('default_socket_timeout', $old);
        if ($fp){
          stream_set_timeout($fp, $timeout);
          stream_set_blocking($fp, 0);
          $page = null;
          while (!feof($fp)) {
            $page .= fread($fp, 8192);
          }
          fclose($fp);
          return $page;
        }else{
          return false;
        }
      }
    • fsockopen.
      Fait, à peu près ce que fait ma fonction monFopen mais en plus.... verbeux
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      function monFileGetContents($adresse, $timeout = 10){
        $url = parse_url($adresse);
        $url['port']   = isset($url['port'])   ? $url['port']               : '80';
        $url['scheme'] = isset($url['scheme']) ? strtoupper($url['scheme']) : 'HTTP';
        $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, $timeout);
        if (!$fp) {
          echo "Erreur de socket: $errno - $errstr<br />\n";
          return false;
        } else {
          $header  = 'GET '.$url['path'].' '.$url['scheme']."/1.1\r\n";
          $header .= 'Host: '.$url['host']."\r\n";
          $header .= "User-Agent: PHP Script\r\n";
          $header .= "Connection: Close\r\n\r\n";
          fputs($fp, $header);
          stream_set_timeout($fp, $timeout);
          while (!feof($fp)) {
            $page .= fread($fp, 262144);
          }
          $stream  = stream_get_meta_data($fp);
          fclose($fp);    
          if ($stream['timed_out']) {
            echo "Le délai de réponse de la page <b>".$adresse.
            '</b> a dépassé le timeout de <b>'.$timeout.'</b> sec.';
            return false;
          }else{
             /*//Pour debugging: echo des headers
              echo '<pre>'.$header;
              echo substr($page, 0, strpos($page, "\r\n\r\n"));
              echo '</pre>';
             */
            // séparation du header
            $page = substr($page, strpos($page, "\r\n\r\n"));
            $page = trim($page);
            return $page;
          }
        }
      }


    Dans chacune des fonctions, si tu n'as pas besoin du contenu de la page en test, remplace return $page; par return true; tu n'auras plus qu'à tester le retour des fonctions pour connaître l'état de disponibilité de la page:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (monFopen($adresse, $timeout)){
      ... mettre flag sur TRUE dans fichier plat.
    } else {
      ... sur FALSE
    }
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

  7. #7
    Membre actif Avatar de renaudjuif
    Inscrit en
    Avril 2006
    Messages
    325
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 325
    Points : 258
    Points
    258
    Par défaut
    Super, jai la totale !
    Je regarde tout ça de plus près, et je vais surement y trouver mon bonheur
    Merci à toi.
    C'est curieux chez les marins ce besoin de faire des phrases !

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    Citation Envoyé par renaudjuif
    A priori je vais utiliser curl, mais je ne suis pas sur que le client ait installé la librairie.
    Au pire, si la librairie PHP-Curl n'est pas installée, et s'il a un serveur Linux, tant qu'à faire un cron, autant appeler directement curl depuis un shell Linux. Comme ceci, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #! /bin/sh
     
    # écrit le temps de réponse total d'une page web dans un fichier tmpFlag
     
    curl \
        --write-out "%{time_total}" \
        --connect-timeout 5 \
        --max-time 5 \
        --silent \
        --output /dev/null \
        'http://www.ton-site/vers/ta/page.php' > tmpFlag
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment générer une erreur suite à une mauvaise saisie
    Par vivevba dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 02/05/2009, 18h23
  2. Réponses: 2
    Dernier message: 15/09/2008, 14h57
  3. Comment éviter d'afficher une erreur quand table vide
    Par lelapinrusse dans le forum Langage
    Réponses: 6
    Dernier message: 16/05/2008, 19h00
  4. Réponses: 4
    Dernier message: 08/05/2006, 16h41
  5. Comment fermer une fenêtre quand la souris et clavier sont inactifs ?
    Par Goldenkiller dans le forum Composants VCL
    Réponses: 7
    Dernier message: 06/12/2004, 22h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo