Aide C++ pour reprise des automatismes

alexflex25 Messages postés 106 Date d'inscription vendredi 29 septembre 2006 Statut Membre Dernière intervention 6 mars 2012 - 6 mars 2012 à 10:27
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 6 mars 2012 à 16:17
Bonjour,

Je me retrouve une fois de plus sur codes-Sources mais cette fois-ci en C++ pour avoir quelque conseil.

Cela fait maintenant plus de 4 ans que je me consacre à la programmation WEB (PHP,JavaScript,etc..) pour mon travail. Il me faudra donc un peu de temps pour renouer avec les automatismes C++. J'ai donc plusieurs petites questions qui concerne le développement d'un serveur en C++.

Le but:
Le but est de réaliser un serveur qui récupère des informations sur plusieurs sources de données (MySql,Logiciel métier, etc...) afin de les redistribuer à plusieurs clients (c++/java/javascript/...)

Les questions:

* Pour le moment mes class de "récupération de données" me retourne un bon vieux tableau associatif, ou devrais-je dire un vector<map<string,string> > (Automatisme PHP) mais est-ce vraiment une bonne solution?

* Je voulais aussi utiliser des thread pour pouvoir interroger mes sources d'informations simultanément, mais surtout pour ne pas bloquer le programme principale. Mais comme le but et de redistribuer les informations à des clients j'aurai déjà des thread au niveau des clients. (La question est: quelles sont les questions à ce poser pour valider l'utilisation de thread?)

* Je me suis rendu compte que l'utilisation du "Json" n'était pas pris en compte nativement en C++ pour l'échange des données entre clients et serveur.
Pensez-vous que ce choix est judicieux pour échanger des données?

Je pense que les réponses à ces questions m'aideront déjà à avancer plus sereinement.

Merci d'avance!

3 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
6 mars 2012 à 11:40
Bonjour et bienvenue sur le forum C++.

Le but est de réaliser un serveur

Ce n'est pas une tâche aisée, surtout si tu reprends tout juste le C++.

* Pour le moment mes class de "récupération de données" me retourne un bon vieux tableau associatif, ou devrais-je dire un vector<map<string,string> > (Automatisme PHP) mais est-ce vraiment une bonne solution?

Au vu de la "tête" de ton type de donné, je te donne le conseil que je donne à tous: Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace

Ta structure est un peu grosse. Ce n'est pas forcément choquant, le seul danger étant de faire des copies (très coûteuse avec la structure que tu as choisi). De plus, celle-ci ne se passera pas facilement en réseau (tu seras obligé de la découper, ou de la sérialiser vu qu'on passe généralement du binaire).

Donc, c'est une bonne solution uniquement si ce sont des données que tu conserves au niveau de serveur. Cette structure est en revanche inadaptée pour un envoi réseau. Je reviendrais sur ce point après.

* Je voulais aussi utiliser des thread pour pouvoir interroger mes sources d'informations simultanément, mais surtout pour ne pas bloquer le programme principale. Mais comme le but et de redistribuer les informations à des clients j'aurai déjà des thread au niveau des clients. (La question est: quelles sont les questions à ce poser pour valider l'utilisation de thread?)

Si tu fais un serveur, tu es quasiment obligé de faire des threads. Je te conseil fortement d'utiliser C++ et Boost (notamment Boost::thread et Boost::mutex), ou alors du C++0x (il y a nativement thread et mutex), si tu y es autorisé. (C++0x est la dernière version du C++, qui n'est pas encore entièrement implémenté).
Ton serveur doit être "multi-threadé" pour servir l'ensemble des clients. En revanche, les clients peuvent être "monothreadés".

* Je me suis rendu compte que l'utilisation du "Json" n'était pas pris en compte nativement en C++ pour l'échange des données entre clients et serveur.
Pensez-vous que ce choix est judicieux pour échanger des données?

Oui et non.
Si tu recherches des échanges performants et compacts, alors il te faut envoyer du binaire.
En revanche, si tu communiques avec d'autre langages, qui gèrent difficilement le binaire, alors oui tu peux partir sur des envoi Json (à toi alors de faire la conversion). Ça sera bien évidemment au détriment de la performance (mais si tu n'as pas de contrainte de performance drastique, comme pour des applications temps réels, normalement ça devrait être largement suffisant).

Difficile sans plus de détails de te conseiller au mieux. Est-ce que le serveur tourne sur un Unix ou du Windows ? Potentiellement les deux ? Quelles sont les contraintes de performance attendues ? Quelle volume de données vas-tu traité ?
Possederas-tu un ou plusieurs serveurs ? Communiquerons-t-il ensemble ? Map/Reduce (en gros, distribution de calcul) ? Y aura-t-il du sharding ?

Je te conseil la chose suivante:
- Échange json (plus facile, plus souple) ou binaire (tout dépend du volume de donné pour chaque requête).
- Pour sérialiser tes objets, utilise Google protobuf.
- Pour transformer du json en objet C++ ou inversement, c'est à toi de le coder. (Il existe déjà des solutions de lecture/écriture Json en C++, mais je ne les trouve pas extraordinaire).
- Boost::thread ou C++0x, pour gérer le multithreading.
- À toi de voir si tu veux faire du RPC, ou de simple envoi client-serveur plus classique.

Autre chose. Une solution déjà faite ne peut-elle pas être utilisé ? Genre du MongoDB ? Si tu me donnes plus de détails sur ce que tu cherches à réaliser, je peux peut être te conseiller une solution existante (open source) adapté à tes besoins.

Ps: Mon travail est de programmer des serveurs avec des échanges de données vers différentes solutions, notamment en binaire ou en json via du rpc + map/reduce, sur des systèmes Unix. Tu as de la chance, je vais pouvoir t'aider :p

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
alexflex25 Messages postés 106 Date d'inscription vendredi 29 septembre 2006 Statut Membre Dernière intervention 6 mars 2012
6 mars 2012 à 15:49
Bien... Voilà ce que l'on appel une réponse...

Après la lecture de ta réponse, j'ai paradoxalement encore plus de question, même si ta réponse m'a déjà beaucoup aidé.

Bref, pour être plus sérieux, comme je ne sais pas par ou commencer dans la rédaction de ce post je vais commencer par faire une petite présentation du projet puis je vais apporter des réponses à tes remarques. Pour finir je vais essayer de donner plus de détail sur le résultat attendu pour déterminer une solution adapté. (Pour que tu m'aides à trouver cette solution...)

Le serveur que je veux réaliser est un serveur de GRTD (Graphic RealTime Display)
- Le système fonctionnera avec un serveur unique (UN SEUL serveur et des clients)
- Le programme sera installé uniquement sur Ubuntu
- L'utilisation serra limité au réseau LAN.
Le but étant, par la suite, de développer des clients permettant d'exploiter les informations issues du serveur.

Voici les contraintes non-négociables...

Au vu de la "tête" de ton type de donné, je te donne le conseil que je donne à tous: Évite les "using namespace"


J'en suis conscient c'était juste un raccourci...

Donc, c'est une bonne solution uniquement si ce sont des données que tu conserves au niveau de serveur. Cette structure est en revanche inadaptée pour un envoi réseau.


Cette structure est en effet destiné à rester au niveau serveur, après je ne sais pas si il est préférable d'utiliser ce type de structure ou par exemple créer une class Response et faire un Vector<Response>...

Si tu fais un serveur, tu es quasiment obligé de faire des threads. Je te conseil fortement d'utiliser C++ et Boost (notamment Boost::thread et Boost::mutex), ou alors du C++0x (il y a nativement thread et mutex), si tu y es autorisé. (C++0x est la dernière version du C++, qui n'est pas encore entièrement implémenté).

C++ et Boost ou C++0x je ne sais pas... Je dirais C++ et Boost pour une contrainte de stabilité... Pour le moment j'utilisais la bibliothèque C Pthread...

Est-ce que le serveur tourne sur un Unix ou du Windows ?

Ubuntu 10.04

Quelles sont les contraintes de performance attendues ?

Très bonne question... Je ne sais pas vraiment à quoi je peux m'attendre, je n'ai même pas d'ordre d'idée... Idéalement j'aimerais que tout ce passe en 1 à 5 secondes (En partant de la récupération de données, jusqu'à la fin de la transmission au client sur un réseau LAN) . Je dis ça arbitrairement, je ne sais pas si cela est possible...

Quelle volume de données vas-tu traité ?

Les données que je vais utiliser vont provenir majoritairement d'un logiciel métier que je vais interroger via une socket à un instant t, d'après les tests que j'ai pu effectuer les réponses me parviennent en quelques millisecondes.
Ensuite la quantité de donnée que je veux transmettre à mes clients va probablement se situer entre 50 et 60 lignes du type nom=valeur.

Possederas-tu un ou plusieurs serveurs ? Communiquerons-t-il ensemble ? Map/Reduce (en gros, distribution de calcul) ? Y aura-t-il du sharding ?

Un seul serveur

Échange json (plus facile, plus souple) ou binaire (tout dépend du volume de donné pour chaque requête).

Rien ne m’empêche de donner le droit au client de demander un type de réponse particulier. binaire / Json / XML / ...

À toi de voir si tu veux faire du RPC, ou de simple envoi client-serveur plus classique.

RPC! (non non je cherche pas à faire quelque chose de compliqué...)

Voilà j'espère que c'est assez clair..
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
6 mars 2012 à 16:17
Voilà ce que l'on appel une réponse

Quand la question est bien posée, propre et soignée, je me permet une réponse de qualité :p (Crois moi ça arrive pas souvent, regarde les 10 dernières question sur ce forum).

J'en suis conscient c'était juste un raccourci...

Simple automatisme de ma part.

Cette structure est en effet destiné à rester au niveau serveur, après je ne sais pas si il est préférable d'utiliser ce type de structure ou par exemple créer une class Response et faire un Vector<Response>...

Idéalement, tu as ta structure "normale" en interne, et tu convertis les données récupérées en protobuf, prêt pour envoi (pour du binaire) ou en texte brut (pour du Json).

C++ et Boost ou C++0x je ne sais pas... Je dirais C++ et Boost pour une contrainte de stabilité... Pour le moment j'utilisais la bibliothèque C Pthread...

Boost te change la vie, vraiment. C'est 1000 fois plus confortable d'utiliser boost::thread que du pthread "à la main" (en plus de la portabilité automatique).
Attention, C++0x est certe jeune (quelques années tout de même), mais est stable. Je l'utilise dans mon entreprise, tous les jours depuis presque 2 ans maintenant (mes serveurs tournent depuis 2 ans en haute disponibilité, avec des contraintes de performances élévées). Je n'ai jamais eu de problème. Ça te permettrait de te passer de boost (puisque tu as std::mutex et std::thread nativement dans le langage). Néanmoins, je reconnais que les entreprises sont encore frileuses à ce sujet (à tord).

Ubuntu 10.04

Il me sera plus aisé de t'aider, alors. Je ne suis pas très à l'aise sous Windows :)

Idéalement j'aimerais que tout ce passe en 1 à 5 secondes

entre 50 et 60 lignes du type nom=valeur.

Une requête de 50 à 60 lignes, à moins d'avoir des calculs extrêmement couteux derrières, tu ne dépasses pas la seconde. (Pour info, exemple pris au hasard, lorsque je remonte 12 919 lignes, il me faut 696ms sachant que chaque lignes possède 20 colonnes).
Il n'est pas dit que ce cas soit représentatif de ta solution, mais il est tout à fait possible d'avoir des temps inférieurs à la seconde (encore une fois, si tu n'as pas de calculs couteux en interne, ce qui est parfois inévitable).

Rien ne m’empêche de donner le droit au client de demander un type de réponse particulier. binaire / Json / XML / ...

Pas tout à fait. "L'emballage" va être drastiquement différent si tu utilises du binaire, du protobuf, ou du texte (json). C'est une étape de la conception qui se prévoit, et je te conseille de fixer une méthode (sinon ça va être la pagaille pour une fonctionnalité à mon sens, peu utile).

RPC! (non non je cherche pas à faire quelque chose de compliqué...)

Le plus simple serait peut être de tout faire en Json, via des webservices. C'est ce qui est le plus souple. (Ça veut dire que les clients interroge le serveur, mais que le serveur ne "voit" personne, il ne peut pas donner d'ordre, juste répondre).

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
Rejoignez-nous