Socket - Structurer des données
Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

Socket - Structurer des données



  1. #1
    sandrecarpe

    Socket - Structurer des données


    ------

    Bonjour à tous,
    Voici un problème dont je cherche une réponse depuis quelques temps déjà.

    Je développe depuis quelques temps déjà une application en c++ sur Raspberry qui se charge d'envoyer des données issues de divers capteurs. Rien de volumineux, mais je commence à avoir à mon goût beaucoup trop de requêtes différentes. Je me retrouve alors avec un énorme switch case dans la fonction qui se charge d'envoyer la réponse au client, et ça sera peut-être contraignant le jour où je voudrais rajouter 50 autres commandes différentes

    Y a t-il une façon plus propre d'organiser tout ça ?

    Un autre exemple. Dans une application tel qu'un MMORPG qui doit effectuer, je pense, un certain nombre de requêtes sur le réseau : comment le serveur gère la multitude de requêtes ? C'est quand même mieux fait qu'un énorme switch case qui traite chaque requête au cas par cas ?


    En espérant avoir été clair. Merci pour vos réponses

    -----

  2. #2
    Bluedeep

    Re : Socket - Structurer des données

    Bonjour

    Absolument rien compris à ton histoire de switch case.
    Envoyer des données sur une socket, cela revient à sérialiser l'objet et à envoyer sur le socket les données sérialisées.
    A la réception, on fait un automate qui écoute sur le socket et fait le traitement correspondant au type d'objet reçu.

    Bref, merci d'être plus précis.

  3. #3
    Manou34

    Re : Socket - Structurer des données

    Bonjour,
    vous pourriez développer un petit module qui vous offrirez des services comme l'enregistrement d'un couple callback/code attendue.
    C'est à dire, que, à réception d'une nouvelle requête, votre module cherche dans sa liste de callback enregistré, si une corespond au code reçu.

  4. #4
    sandrecarpe

    Re : Socket - Structurer des données

    Bonjour,
    Voici un bout de code pour illustrer le problème

    Code:
    void threadInternet()
    {
    	//je lis les données sur le socket et place le contenu dans reponseClient (string)
    
    
    	//je découpe la chaine pour récupérer les différentes commandes envoyées par le client
    	std::vector<string> commandes = split(reponseClient, '@');
    
    	for(unsigned char i = 0; i < commandes.size(); i++)
    	{
    		if(commandes == COMMANDE_1)
    		{
    			//action n°1
    		}	
    		else if(commandes == COMMANDE_2)
    		{
    			//action n°2
    		}
    		else if(commandes == COMMANDE_3)
    		{
    			//action n°3
    		}
    		.
    		.
    		.
    		else if(commandes == COMMANDE_4656)
    		{
    			//action n°4656
    		}
    	}
    }
    Vous voyez que si on a plusieurs dizaines de commandes ça commence à être le bordel et poserais des problèmes d'organisation.
    C'est pourquoi je me demandais comment était gérée cette situation dans un programme conséquent et est-ce fais de la même façon que ci-dessus ?

    J'espère que c'est plus clair

  5. A voir en vidéo sur Futura
  6. #5
    Manou34

    Re : Socket - Structurer des données

    Bonjour sandrecarpe,

    il faut penser modularité !

    votre module doit avoir pour rôle de lire sur la socket et d'aiguiller ensuite le commande reçu chez d'autre module qui gère une spécifique.

    Imaginé que votre module "receptionSocket" fournisse un service "registerCommand" afin que les autre modules, "manageCommandX", puissent s'enregistrer auprès de module "receptionSocket", en fournissant une callback et à quel numéro de commande il souscrit.

    Le module "receptionSocket" maintient une liste de tout les modules "manageCommandX" enregistrés, et lors de la réception d'une commande sur le socket, recherche dans la liste de souscripteur, si quelqu'un est abonné à ce code commande.

    Si il trouve un souscripteur, il le reveille gràce à la callback fourni.

    C'est le principe du pattern "observer", vous trouverez plein de ressources bien mieux expliqué sur le net

  7. #6
    pm42

    Re : Socket - Structurer des données

    Citation Envoyé par Manou34 Voir le message
    Imaginé que votre module "receptionSocket" fournisse un service "registerCommand" afin que les autre modules, "manageCommandX", puissent s'enregistrer auprès de module "receptionSocket", en fournissant une callback et à quel numéro de commande il souscrit.
    C'est plus flexible s'il écrit gros programme. Dans son cas, il va remplacer un code d'aiguillage par un code d'initialisation.
    Si ses messages étaient codés via des entiers, je recommanderais plutôt l'instruction switch et pour chaque "case", l'appel d'une fonction.
    Dans le cas présent, une std::map<string, xxx> avec xxx la classe abstraite de traitement de chaque cas ou un pointeur de fonction me semble le mieux.

    Citation Envoyé par Manou34 Voir le message
    Si il trouve un souscripteur, il le reveille gràce à la callback fourni.
    Vu qu'on est en objet, on n'utilise pas des callbacks mais une interface donc chaque implémentation va surcharger la méthode charger de traiter le message.

    Citation Envoyé par Manou34 Voir le message
    C'est le principe du pattern "observer", vous trouverez plein de ressources bien mieux expliqué sur le net
    Non, le pattern Observer sert à ce qu'on objet puisse en prévenir d'autres quand il est modifié. Ici, on est dans le pattern Stratégie : https://fr.wikipedia.org/wiki/Straté...de_conception)

  8. #7
    sandrecarpe

    Re : Socket - Structurer des données

    Merci pour vos réponse.
    J'avais d'abord pensé à faire du pattern observer (même si je ne sais jamais qui observe qui ). Avec les "callback" (apparemment c'est pas le bon terme) qui sont appelés PAR la classe ThreadInternet et exécuté DANS la classe Terrarium car c'est dans cette dernière que j'ai besoin de modifier des attributs.
    En gros quelque chose comme ça :

    Code:
    //ObserverThreadInternet.h
    class ObserverThreadInternet
    {
    	public:
    		ObserverThreadInternet();
    		~ObserverThreadInternet();
    		virtual void onCommande1() = 0;
    		virtual void onCommande2() = 0; 
    	
    };
    
    
    //ThreadInternet.h
    class ThreadInternet
    {
    	public:
    		ThreadInternet(ObserverThreadInternet *obs);
    		~ThreadInternet();
    		void run(); //fonction lancée dans un thread
    
    	private:
    		ObserverThreadInternet *_obs;
    		
    };
    
    //ThreadInternet.cpp
    void ThreadInternet::run()
    {
    	//je lis les données sur le socket et place le contenu dans reponseClient (string)
    
    
    	//je découpe la chaine pour récupérer les différentes commandes envoyées par le client
    	std::vector<string> commandes = split(reponseClient, '@');
    
    	for(unsigned char i = 0; i < commandes.size(); i++)
    	{
    		if(commandes == COMMANDE_1)
    		{
    			_obs->onCommande1();
    		}	
    		else if(commandes == COMMANDE_2)
    		{
    			_obs->onCommande2();	
    		}
    		else if(commandes == COMMANDE_3)
    		{
    			_obs->onCommande3();	
    		}
    		else if(commandes == COMMANDE_4656)
    		{
    			_obs->onCommande4();	
    		}
    	}
    }
    
    
    
    //Terrarium.h
    class Terrarium : public ObserverThreadInternet 
    {
    	public:
    		Terrarium();
    		~Terrarium();
    
    		//méthodes surchargées de ObserverThreadInternet
    		void onCommande1();
    		void onCommande2();
    
    	private:
    		ThreadInternet *_threadInternet;
    	
    };
    
    
    //Terrarium.cpp
    Terrarium::Terrarium()
    {
    
    	_threadInternet = new ThreadInternet(this);
    
    }
    
    void Terrarium::onCommande1()
    {
    	//commande 1
    }
    
    void Terrarium::onCommande2()
    {
    	//commande 2
    }
    Je viens de faire ça à l'improviste, j'espère que j'ai pas fais d'erreur.
    A vrai dire au moment d'ouvrir ce post, le thread internet tournais dans la classe Terrarium donc j'avais pas de "soucis" pour accéder aux attributs, ça prenait seulement trop de place
    Du coup j'ai fais une classe ThreadInternet qui s'occupe de lancer le thread et la classe Terrarium s'occupe d'en lancer une instance.
    Mais maintenant je me retrouve soit à mettre des getters dans la classe Terrarium pour accéder à ses attributs et dans ce cas je dois passer un pointeur de Terrarium à ThreadInternet, ou alors, je mets en place un pattern observer (comme le code ci-dessus).

    Par contre, je ne comprends pas bien comment mettre en place du pattern stratégie dans ce cas, ni l'histoire avec le std::map<string, xxx>
    Mais ça m'intéresse, je veux bien avoir quelques explications supplémentaires

  9. #8
    Logoosse

    Re : Socket - Structurer des données

    Bonjour,
    Non, le pattern Observer sert à ce qu'on objet puisse en prévenir d'autres quand il est modifié. Ici, on est dans le pattern Stratégie : https://fr.wikipedia.org/wiki/Straté...de_conception)
    Je confirme on est dans le cas d'un patter stratégie, pour être plus précis tu es dans le cas d'un router (très utilisé en programmation client/server et essentiellement en web). Vous pouvez vous inspirer des router utilisés en web, et souvent utilisés en Node.js.

    Par contre, je ne comprends pas bien comment mettre en place du pattern stratégie dans ce cas, ni l'histoire avec le std::map<string, xxx>
    En gros, l'idée est d'utiliser une map pour stocker la fonction à appeler en fonction de la commande (la clé = le nom de la commande, xxx = le point d'entrée de la fonction.

    Je ne peux pas te donner rapidement une réponse C++, car je n'utilise pas assez le langage mais vous vous retrouvereriez avec quelque chose comme ça.
    Module Controller :
    Code:
    map<Comand,function> mesCommandes;
    function ReadRequest( request){
    mesCommandes.get(request->commande)(request->params)
    }
    A faire varier selon le langage et le type passage de paramètres autorisé par le langage.

    Vous pouvez également recréer une structure de le système des map, mais personnalisée à vos besoins.

Discussions similaires

  1. Structurer un programme en C avec SDL
    Par AmigaOS dans le forum Programmation et langages, Algorithmique
    Réponses: 10
    Dernier message: 02/03/2011, 19h59
  2. besoin d'aide pour structurer le domaine médical - différentes branches?
    Par invite88caebb7 dans le forum TPE / TIPE et autres travaux
    Réponses: 0
    Dernier message: 29/11/2008, 10h45
  3. socket 775
    Par inviteba61ab7d dans le forum Matériel - Hardware
    Réponses: 2
    Dernier message: 31/05/2008, 18h24
  4. qu'est ce qu'un socket?
    Par invite73653775 dans le forum Internet - Réseau - Sécurité générale
    Réponses: 4
    Dernier message: 03/04/2007, 17h31
  5. socket ??????
    Par invitea0d2edea dans le forum Électronique
    Réponses: 0
    Dernier message: 31/01/2007, 16h39