Forum Programmation.php Faire tourner un script PHP en boucle indéfiniment : bien ou pas bien ?

Posté par .
Tags : aucun
1
17
déc.
2008
Bonjour,

je veux afficher dans une page web des données issues d'une base de données ; ces dernières sont continuellement mises à jour par une autre application. Ma page web doit afficher les données en temps réel (à quelques secondes près).

Pour cela, j'ai fait d'un côté un service web qui fournit un flux XML contenant les données à afficher, et de l'autre une page web en ajax, qui fait une requête GET asynchrone sur mon service toutes les 5 secondes. Ça fonctionne.

Seulement, cela consomme trop de bande passante pour moi (connexion GPRS facturée au ko, et page web tournant 24/24h).

Du coup, j'ai testé ceci : côté serveur, le webservice tourne en boucle jusqu'à ce qu'une modification survienne dans la base de données. A ce moment là seulement le flux est envoyé.
Comme ça pendant ce temps, côté client, la requête Ajax reste en mode readyState = 3, donc pas de consommation réseau.

Sauf qu'au bout de 30 secondes, le webservice s'interrompt, normal

Je suis administrateur du serveur, donc je peux faire sauter cette restriction, mais je voudrais savoir si sur le principe, mon architecture est bonne, et si ce n'est pas le cas, comment faire plus propre.

Merci d'avance !
  • # lapin compris

    Posté par . Évalué à 2.

    a quoi ca sert de faire tourner ta requete en boucle (coté serveur)

    pour savoir si un truc à changer puis avertir l'usager (le navigateur du client) que ca a changé pour qu'il vienne chercher la mise à jour.

    pourquoi ne pas faire un refresh volontaire de la part du client.

    il a les données au moment ou il se connecte "au temps T"
    s'il veut (et qu'il est pres à mettre de la 3G/GPRS dedans) les données à T+60sec, ben il rafraichit 60s plus tard...

    sinon dans les 2 cas, tu vas forcer le "client" à rafraichir les données ....
    • [^] # Re: lapin compris

      Posté par . Évalué à 3.

      Actuellement, je fais un refresh volontaire toutes les 5 secondes, oui. Sauf qu'à chaque fois, ça fait télécharger un certain volume de données.
      Or, bien que je souhaite afficher les données avec un délai maximum de 5 secondes environ, en pratique les données changent occasionnellement, et surtout aléatoirement (en moyenne toutes les heures). Du coup, avec ma méthode, outre lors de l'initialisation de la requête, aucune donnée n'est transférée ni dans un sens ni dans l'autre tant que les données ne changent pas dans la base.

      En gros, c'est comme attendre que le facteur sonne à ma porte, plutôt que de guetter à intervalles réguliers, voir s'il n'est pas en train d'arriver.

      A moins que je me trompe, tant que mon script côté serveur n'est pas entièrement exécuté, la requête du client est en statut readyState = 3. Durant tout ce temps, qui dans mon cas, peut durer plusieurs heures (enfin si j'enlève la restriction de 30 secondes de PHP), aucune donnée n'est transférée, ni dans un sens ni dans l'autre.
  • # Not modified

    Posté par . Évalué à 9.

    Tu devrais plutôt modifier ton webservice pour qu'il renvoit un code 304 (cf http://www.freesoft.org/CIE/RFC/2068/87.htm ) si les données n'ont pas changé. La partie ajax doit alors envoyer un header qui indique la date de sa dernière requète.
    Cela devrait te limiter beaucoup la quantité de données envoyées.
    • [^] # Re: Not modified

      Posté par . Évalué à 2.

      En effet ça limite la quantité de données envoyées, mais pas assez. Surtout que les données envoyées ne sont de toute façon pas volumineuses (un flux XML avec une centaine de caractères, balises comprises).
      Avec cette solution, le client continue quand-même à initier une requête toutes les 5 secondes, et reçoit à chaque fois une réponse (même si effectivement elle n'est pas grosse, avec ce que tu proposes).
      Or, en pratique, les données ne changent en moyenne qu'une fois toutes les heures (mais ce délai est complètement aléatoire). Donc ça fait 719 requêtes inutiles par heures, ça fait plus de 500 000 requêtes inutiles par mois. Sur une connexion GPRS facturée au ko, c'est sensible.
      • [^] # Re: Not modified

        Posté par . Évalué à 2.

        Or, en pratique, les données ne changent en moyenne qu'une fois toutes les heures (mais ce délai est complètement aléatoire).

        Le délais est aléatoire, mais ton serveur peut-il l'estimer (même grossièrement)?
        Si oui tu peux ajouter le header Expires (http://www.freesoft.org/CIE/RFC/2068/182.htm ) pour indiquer au client à partir de quand ça vaut la peine de refaire une requète.
        • [^] # Re: Not modified

          Posté par . Évalué à 2.

          Malheureusement non, il ne peut pas l'estimer. Des fois il y a plusieurs modifications de suite, des fois il y a plusieurs heures, ce n'est pas prévisible (ou du moins, je cherche à mettre en place une solution indépendante de l'application métier qui est derrière).
    • [^] # Re: Not modified

      Posté par . Évalué à 2.

      C'est ce que je viens de faire, parce qu'avec ma solution, et la limite maximum de temps d'exécution de PHP ôtée, httpd crash sans arrêt.
    • [^] # Re: Not modified

      Posté par . Évalué à 2.

      Bon j'ai mis en place la solution que tu proposes.

      En termes de consommation en bande passante, j'ai regardé avec firebug :

      - le chargement de mon flux XML lorsqu'il contient des données mises à jour prend environ 900 octets ;

      - une réponse "304 Not modified" semble trop petite pour être évaluée par firebug (qui met un ? à la place de la taille).

      A mon avis c'est un bon compromis.
      • [^] # Re: Not modified

        Posté par . Évalué à 2.

        - le chargement de mon flux XML lorsqu'il contient des données mises à jour prend environ 900 octets ;

        - une réponse "304 Not modified" semble trop petite pour être évaluée par firebug (qui met un ? à la place de la taille).


        C'est parce qu'il n'y a aucun contenu avec la réponse 304, et dans tes 900 octets les headers ne sont probablement pas comptés.
        Côté serveur avec un apache tu peux voir la taille réellement reçue/envoyée avec le mod_logio
        http://httpd.apache.org/docs/2.2/mod/mod_logio.html
  • # PHP Socket Daemon

    Posté par (page perso) . Évalué à 2.

    Je te conseille de regarder du côté d'un petit daemon en php qui tourne en continu.

    http://code.google.com/p/phpsocketdaemon/
    http://www.chabotc.com/phpsocketdaemon/
  • # en prenant les choses par l'autre bout

    Posté par (page perso) . Évalué à 2.

    Tes données sont mise à jour aléatoirement.
    Le prog qui les met à jour ne peut pas envoyer un flux vers le poste client ?
    Dans cette optique, tu as un service qui tourne sur le poste client, et qui attend de recevoir un message. A réception, il affiche les données.
    Comme ça tu n'a des infos qui transitent que s'il y a mise à jour.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.