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

Langages de programmation Discussion :

Bonnes pratiques client-serveur


Sujet :

Langages de programmation

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 66
    Points : 63
    Points
    63
    Par défaut Bonnes pratiques client-serveur
    Salut à tous,

    C'est après une longue hésitation que je place ce message dans cette rubrique, si ce n'est pas la bonne, veuillez m'excusez et m'indiquer ou poster

    Je développe un petit système client-serveur, en C++, via sockets TCP asynchrones (boost asio). La plupart du temps, le fonctionnement de mon application générale colle bien avec le système client serveur, les clients font leur petit bonhomme de chemin et interrogent le serveur quand c'est nécessaire. Le serveur, lui, se contente de répondre aux requêtes des clients.

    Mais deux petites choses viennent un peu perturber ce fonctionnement :

    1. Les requêtes trop longues à exécuter
    2. La remontée d'infos (maintenance)


    Je m'explique. Pour le 1), les requêtes trop longues à éxecuter : ça m'embête un peu de laisser mon client en écoute de la réponse du serveur. Parfois, je demande la réalisation d'une tâche drôlement compliquée au serveur qui peut prendre plusieurs dizaines de minutes. Ce que je fais en ce moment, plutôt que d'attendre la réponse du serveur en écoute bloquante pendant 20 minutes, c'est laisser le serveur faire son calcul, et repasser régulièrement voir si la réponse est sortie ou non. Je reste donc dans un fonctionnement client-serveur, le client interroge le serveur. Mais je me demande si je fais bien. Sachant qu'obtenir la réponse n'est pas une chose urgente pour mon client, dois-je garder un fonctionnement identique à celui-ci ou alors laisser mon serveur prendre la décision d'envoyer au client la réponse. Ce point m'embête car dans ce cas le client/serveur est inversé, c'est le serveur qui devient client et qui "push" la réponse sur le client. Je trouve ça tordu, ça voudrait dire qu'une appli serait en écoute d'une réponse sur le client...

    Mon deuxième point rejoint mon premier. Parfois j'aimerai obtenir des infos de mes clients, ou leur envoyer un signal particulier pour de la maintenance. Sachant que j'aurai la main sur le serveur, mais pas sur mes clients. Je vois deux solutions et là encore j'hésite.
    Soit je crée une liste de messages sur le serveurs, adressés aux clients et à intervalles réguliers les clients viennent vérifier qu'aucun message ne leur est adressé. C'est pas optimal mais ça me permet de garder un fonctionnement client/serveur classique.
    L'autre solution c'est de mettre en écoute une appli sur le client, et ordonner au serveur l'envoi d'un message vers tel client. Ce qui m'embête c'est que j'ai l'impression de détourner le fonctionnement client/serveur.

    Qu'en pensez vous ? Suis-je complètement dans le faux avec mes solutions ? Vaut-il mieux avoir un client avec une petite partie en écoute, capable de traiter des messages entrants (et dénaturer ainsi le fonctionnement client serveur) ou alors vaut-il mieux garder un fonctionnement homogène, quitte à faire des requêtes régulières pour rien ?

    Merci

    Guiz

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par ZeGuizmo Voir le message
    Salut à tous,

    C'est après une longue hésitation que je place ce message dans cette rubrique, si ce n'est pas la bonne, veuillez m'excusez et m'indiquer ou poster

    Je développe un petit système client-serveur, en C++, via sockets TCP asynchrones (boost asio). La plupart du temps, le fonctionnement de mon application générale colle bien avec le système client serveur, les clients font leur petit bonhomme de chemin et interrogent le serveur quand c'est nécessaire. Le serveur, lui, se contente de répondre aux requêtes des clients.

    Mais deux petites choses viennent un peu perturber ce fonctionnement :

    1. Les requêtes trop longues à exécuter
    2. La remontée d'infos (maintenance)


    Je m'explique. Pour le 1), les requêtes trop longues à éxecuter : ça m'embête un peu de laisser mon client en écoute de la réponse du serveur. Parfois, je demande la réalisation d'une tâche drôlement compliquée au serveur qui peut prendre plusieurs dizaines de minutes. Ce que je fais en ce moment, plutôt que d'attendre la réponse du serveur en écoute bloquante pendant 20 minutes, c'est laisser le serveur faire son calcul, et repasser régulièrement voir si la réponse est sortie ou non. Je reste donc dans un fonctionnement client-serveur, le client interroge le serveur. Mais je me demande si je fais bien. Sachant qu'obtenir la réponse n'est pas une chose urgente pour mon client, dois-je garder un fonctionnement identique à celui-ci ou alors laisser mon serveur prendre la décision d'envoyer au client la réponse. Ce point m'embête car dans ce cas le client/serveur est inversé, c'est le serveur qui devient client et qui "push" la réponse sur le client. Je trouve ça tordu, ça voudrait dire qu'une appli serait en écoute d'une réponse sur le client...

    Mon deuxième point rejoint mon premier. Parfois j'aimerai obtenir des infos de mes clients, ou leur envoyer un signal particulier pour de la maintenance. Sachant que j'aurai la main sur le serveur, mais pas sur mes clients. Je vois deux solutions et là encore j'hésite.
    Soit je crée une liste de messages sur le serveurs, adressés aux clients et à intervalles réguliers les clients viennent vérifier qu'aucun message ne leur est adressé. C'est pas optimal mais ça me permet de garder un fonctionnement client/serveur classique.
    L'autre solution c'est de mettre en écoute une appli sur le client, et ordonner au serveur l'envoi d'un message vers tel client. Ce qui m'embête c'est que j'ai l'impression de détourner le fonctionnement client/serveur.

    Qu'en pensez vous ? Suis-je complètement dans le faux avec mes solutions ? Vaut-il mieux avoir un client avec une petite partie en écoute, capable de traiter des messages entrants (et dénaturer ainsi le fonctionnement client serveur) ou alors vaut-il mieux garder un fonctionnement homogène, quitte à faire des requêtes régulières pour rien ?

    Merci

    Guiz


    Quelques pistes :

    • Question 1 :

      Le principe d'une communication asynchrone est que on est "réveillé" quand on en a besoin.

      Je suppose que dans ta communication, tu as établis un protocole dans lequel pour une action demandée tu as une réponse. Et que cette réponse peut-être asyncrhone, non ??

      Je pense que dans ce cas tu as pris le problème à l'envers..

      Ce n'est pas au client d'aller voir , c'est au serveur d'envoyer quand il est prêt.. Tu peux mettre à jour régulièrement par l'envoi d'un message "Working on request xxx...", comme ça ton client peux griser/interdire les champs concernés (ou avoir un message affiché du style "le calcul xxx est en train de se faire")..

      Mais de toutes façons, la réponse doit être asynchrone..

      Je ne sais pas comment tu as conçu cette communication, mais la différence entre synchrone et asyncrhone, c'est que dans le mode syncrhone, tu envoies la requête, et immédiatement tu vas attendre la réponse, en bloquant.. En mode asynchrone, tu envoies la requête, puis tu continues à vaquer à d'autres occupations, sans bloquer et sans plus t(occuper du lien de communication, et quand le serveur est prêt il envoie la réponse. Là les mécanismes te signale qu'il y a une réponse, et tu vas la lire....


      Je crois que fondamentalement tu as mélangé syncrhone et asynchrone...



    • Question 2 :

      Cela devrait faire partie de l'échange initial (le "handshake" de ton protocole)..
      Le client, quand il envoie une demande de connection, devrait par exemple envoyer "Connect with version 3.4". Le serveur devrait alors répondre "Welcome. Connect OK". PLUS un message du style "New version 3.5 is available"... Ou quelque chose comme ça..


  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 66
    Points : 63
    Points
    63
    Par défaut
    Salut,

    Merci pour cette réponse détaillée.

    En effet, je viens de passer mon C/S en asynchrone alors qu'il était en synchrone/multi thread auparavant Ca répond donc à ma question, qui ne se pose plus trop

    Par contre pour le deuxième point, je ne vois pas en quoi ça répond à ma question. J'ai du mal m'exprimer. Je souhaite obtenir des informations sur mon client (dans un cas très isolé, mais j'en ai vraiment besoin). Si mon client est muet pendant 3 jours, je ne vais pas attendre trois jours pour obtenir ces infos (le client décide de l'appel au serveur)

    Ce que je peux faire, c'est envoyer depuis mon client une petite requête régulière, pour vérifier que mon serveur (moi en l'occurence) n'a pas une petite exception à lui demander. Ca me semble gâcher de la bande passante et du temps de calcul serveur pour rien dans tous les cas où le serveur n'aura pas besoin d'infos (et donc les cas ou la réponse au client serait négative, ce qui correspond à 99% des cas). L'autre solution est de laisser un truc en écoute sur mon client, mais là ça ne me plait pas trop (cf premier post).

    En gros pour te situer l'application et pourquoi j'ai besoin de cet accès : mon client est un poste de contrôle, qui pilote de l'équipement électronique de manière autonome. Mais pour piloter cet équipement, il a besoin d'informations prévisionnelles sur l'environnement dans lequel évolue l'équipement. Ce qu'on a imaginé, c'est un client autonome, pilotant son équipement avec une série de paramètres. L'équipement lui fait des retours sur le fonctionnement, et lorsqu'un défaut de fonctionnement est constaté, le client va demander au serveur un nouveau jeu de paramètres. Sachant que bien sur, le calcul de ce jeu de paramètres est un truc de bourrin, qui nécessite des tonnes d'infos et une capacité de calcul que le client n'a pas.

    Pour en revenir à mon système, si le jeu de paramètres du client fonctionne bien, il peut rester des semaines (quasi-impossible, au mieux quelques jours, mais travaillons avec les extrêmes) sans demander au serveur quoi que ce soit. Du coup, si j'ai besoin (et j'en ai vraiment besoin dans de rares cas) de demander une info, ben j'ai plus qu'à attendre que mon client fasse sa demande. Ce fonctionnement ne me convient pas.

    J'ai donc isolé les deux méthodes que je décris précédemment, mais je n'arrive pas à me décider. Existe-t-il une autre méthode ? L'une des deux que je présente est elle LA bonne ? (et dans ce cas pourquoi ?)

    Merci beaucoup et bonne soirée,

    Guiz

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Ton explication est contradictoire :


    Citation Envoyé par ZeGuizmo Voir le message
    Par contre pour le deuxième point, je ne vois pas en quoi ça répond à ma question. J'ai du mal m'exprimer. Je souhaite obtenir des informations sur mon client (dans un cas très isolé, mais j'en ai vraiment besoin). Si mon client est muet pendant 3 jours, je ne vais pas attendre trois jours pour obtenir ces infos (le client décide de l'appel au serveur)
    ...
    Ce qu'on a imaginé, c'est un client autonome, pilotant son équipement avec une série de paramètres. L'équipement lui fait des retours sur le fonctionnement, et lorsqu'un défaut de fonctionnement est constaté, le client va demander au serveur un nouveau jeu de paramètres.
    ...
    Du coup, si j'ai besoin (et j'en ai vraiment besoin dans de rares cas) de demander une info, ben j'ai plus qu'à attendre que mon client fasse sa demande. Ce fonctionnement ne me convient pas.

    Tu dis simultanément que c'est le client qui va demander au serveur et que le serveur doit demander au client....

    D'autre part, il y a également un mélange de fonctionalités. L'une consiste à envoyer de l'info ("mise à jour disponible" par exemple), l'autre consiste à demander de l'info...


    Pour ce qui est des délais (plusieurs mois), il n'y a aucun problème. J'ai fait cela sur des données arrivant parfois plus de 1000 à la seconde, puis plus rien pendant 3 ou 4 mois, et un fonctionnement asynchrone marche parfaitement...


    La solution 1 est la plus propre..

    C'est une requête de fond, du même style (j'espère que vous l'avez prévu des 2 côtés) que le fait de vérifier que la connection est toujours là ("frozen sockets", ctrl-C, kill , hangups, etc...).

    Cela reste dans l'esprit client-serveur, et ne mange pas franchement de bande passante, et fait partie des tâches ok...




    Une autre approche peut être (en restant dans le même esprit) d'ajouter une requête correspondant à la demande éventuelle du serveur.

    Pour garder la philosophie de base, ce n'est pas compliqué..

    C'est une requête asynchrone du style "Get update needs". Le client envoie cette requête après avoir tout intialisé. Comme c'est une requête asynchrone, il n'attend pas la réponse. Si il reçoit "Update Needed", il répond...


    Cela "twiste" un peu le schéma, puisque le client, à réception, doit répondre, mais cela garde quand même l'esprit que c'est le client qui a fait la demande initiale....



    Une autre solution (propre) est de faire un second client, minimum, qui n'est démarré que quand le client démarre, et qui ne gère que les demandes d'infos du serveur.. Et dans ce cas-là, ton serveur devient client et ton petit client devient serveur...

    Pour ma part, j'hésiterais entre la solution 1 et celle-ci. Cela dépendra sans doute d'une discussion de tour de table...

    La dernière solution pourrait éventuellement être ma solution préférée, dans la mesure où le besoin est pour vous et non pour le client (le vrai), et que donc c'est une spécification totalement déconnectée de celle du client. Et comme le besoin est pour vous, et que le serveur est pour vous, il serait naturel dans sa spécification que il puisse avoir la dualité serveur-client en son sein..

    Maintenant, la solution 1 à l'avantage d'être cohérente de bout en bout (pour les infos). En ce qui concerne la demande d'info, comme je l'ai dit plus haut c'est un peu "twisté"...

    Donc vraisemblablement je pencherais pour le petit serveur séparé... uniquement pour les demandes d'infos de votre part.. Quant à la signalisation d'infos de votre part vers le client, je pencherais vers la solution 1..

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 66
    Points : 63
    Points
    63
    Par défaut
    Je m'exprime vraiment mal En effet, dans le texte c'est contradictoire, c'est simplement que j'ai omis de différencier le comportement normal (client -> serveur) du comportement exceptionnel (serveur -> client) ...

    Citation Envoyé par souviron34 Voir le message
    Donc vraisemblablement je pencherais pour le petit serveur séparé... uniquement pour les demandes d'infos de votre part.. Quant à la signalisation d'infos de votre part vers le client, je pencherais vers la solution 1..
    Cela répond à ma question initiale. Je rencontre en effet les deux cas, de la descente d'informations pour de la maintenance classique (mises à jour ...) et de la remontée d'infos qui sera beaucoup plus rare. Pour le second cas je vais opter pour un mini serveur sur le client, en écoute permanente (voire même synchrone, car à priori l'asynchronisme ne se justifie pas tellement).

    Merci de ton aide et désolé pour les imprécisions

    Bon week end,

    Guiz

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

Discussions similaires

  1. [AVIS & BONNE PRATIQUE] application client / serveur
    Par richard_sraing dans le forum Interfaces Graphiques en Java
    Réponses: 20
    Dernier message: 15/05/2013, 16h45
  2. Bonne pratique serveur Webdav
    Par Zoizoi dans le forum IIS
    Réponses: 0
    Dernier message: 24/09/2010, 22h39
  3. Bonne pratiques sauvegarde auto d'un serveur
    Par Concombre Masqué dans le forum Général Conception Web
    Réponses: 4
    Dernier message: 14/06/2010, 18h33
  4. [Client] Bonne pratique de consommation
    Par JWillow dans le forum Services Web
    Réponses: 2
    Dernier message: 25/01/2010, 16h24

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