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

Réseau et multijoueurs Discussion :

Echange des données client/serveur, comment procéder ?


Sujet :

Réseau et multijoueurs

  1. #1
    Membre du Club
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Novembre 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2010
    Messages : 61
    Points : 42
    Points
    42
    Par défaut Echange des données client/serveur, comment procéder ?
    Bonjour,

    Je dois m'occuper de la partie serveur pour un MMORPG.
    J'utilise la SMFL 1.6 comme API.

    Pour le moment, j'ai pensé le faire comme ceci :

    Une classe serveur qui représente mon Serveur, et ce serveur possèdera plusieurs threads qui auront chacun leur tâche propre. Le Serveur possède aussi une liste (vector) de Joueur représentant les joueurs connectés.
    Pour l'instant, j'ai développé le thread de connexion/authentification en utilisant les selectors de la SMFL et le protocol UDP. Dans ce thread je détecte si on m'envoi un paquet, je test les données, j'instancie un Joueur et réécoute sur le port.
    Grace aux selectors, si un client fait une demande d'authentification, alors il est mis en attente le temps que l'autre se termine (je pense que c'est gérable car l'instanciation ce fait assez rapidement (2 requêtes SQL, 1 ajout dans un vector et un instanciation + quelque test et un parcours de vector), qu'en pensez vous ?

    Maintenant, je dois m'occuper de la partie envoie de données et reception de données client/serveur mais je ne sais pas du tout par où commencer et comment m'y prendre... =x

    Dois-je faire 1 thread pour émission et un autre pour réception ?
    Dois-je rassembler les deux ?

    Imaginons que mon thread attend un paquet d'un client (thread d'émission donc), hop, je l'ouvre et regarde ce qu'il y a dedans, je décrypte le message et il faut ensuite que j'envoie les infos au autre clients.
    Mais problème !? Si un autre client envoie un paquet au serveur pendant que celui ci effectue les calculs, comment je dois faire ?

    Faudrait-il que je stocke les paquet reçu dans un vector et mon thread d'émission s'occupe de travailler sur ce vector s'il il contient des paquet ?
    Du coup, mon thread de réception servirai simplement d'écouter et ranger les paquets dans un vector et ainsi il réécouterai plus vite le port pour les futur paquet ?
    Mais toujours le même soucis, si je reçoit un paquet alors que le thread de reception est en train de ranger dans le vector, le paquet sera perdu ? Ou il sera mis en attente et traité tout de suite après ?
    Je ne sais pas si je peux utiliser encore les selectors ou les threads :/


    N'hésitez pas à critiquer si vous trouvez que je dois changer des choses et faire autrement etc... Je prend toute les informations que vous me donnerais !

    Merci beaucoup

  2. #2
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Déjà : quel langage et quel OS ?

    Pour ma part, je ferais tout le réseau en asynchrone (sous Linux, tu as par exemple epoll ; sous Windows, il y a I/O Completion ports).

    Dans un premier temps, tu peux faire toutes les entrées-sorties sur un seul thread. Avec l'asynchrone, tu peux déjà faire tenir pas mal de clients. Pour la communication avec le moteur de jeu, tu peux utiliser une file de messages. Sur le thread réseau, c'est simple : dès que tu reçois un message réseau, tu l'ajoutes dans la file et c'est tout, de manière à ne pas bloquer le thread.

    Côté moteur de jeu, j'imagine qu'il y a une boucle principale. Il suffit de récupérer les messages réseau et de les traiter dans cette boucle.

    Faudrait-il que je stocke les paquet reçu dans un vector et mon thread d'émission s'occupe de travailler sur ce vector s'il il contient des paquet ?
    Dans le thread qui reçoit les messages, tu peux traiter certains messages si tu veux, mais très peu. Tu dois te limiter aux messages que tu peux traiter de façon instantanée (ne faire aucun calcul) et ne pas modifier de variable de ton moteur de jeu (à moins qu'il soit thread-safe, mais ça me semble risqué).

  3. #3
    Membre du Club
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Novembre 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2010
    Messages : 61
    Points : 42
    Points
    42
    Par défaut
    En C++ et le programme devra tourner sous linux (j'utilise windows pour dev' pour l'instant étant donné que j'utilise la SMFL et que c'est portable autant sur linux que windows).

    Quand tu dit asynchrone, tu parles de Selectors donc ?

    Je n'en suis qu'au début, donc pas encore de "moteur de jeu", d'ailleurs, pourrait tu m'expliquer en profondeur ce qu'est un moteur de jeu et ce que celui ci doit faire ?

    Je précise que je suis un novice dans le domaine, techniquement en C++ ca va mais c'est surtout sur le concept/architecture d'un serveur MMORPG que j'ai beaucoup à apprendre...

  4. #4
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Quand tu dit asynchrone, tu parles de Selectors donc ?
    Je viens de vérifier. "Selectors" en SFML, ça correspond à la fonction select. Ça marche, mais ce n'est pas optimal (pour améliorer, tu pourras regarder du côté de ASIO ou libevent). Si tu ne veux pas trop t'embêter, tu peux partir avec ça.

    pourrait tu m'expliquer en profondeur ce qu'est un moteur de jeu et ce que celui ci doit faire ?
    C'est ce qui implémente les règles du jeu, les combats, les déplacements de personnages, l'IA, etc.

  5. #5
    Membre du Club
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Novembre 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2010
    Messages : 61
    Points : 42
    Points
    42
    Par défaut
    C'est ce qui implémente les règles du jeu, les combats, les déplacements de personnages, l'IA, etc.
    Excuse moi de cette question, mais tout ça dans un même thread c'est gérable (gestion de déplacement, IA, combat, etc...) ?

    --------------------------

    Sinon, pour ce qui est de la réception, je stock les paquets "complexe" dans une liste. Ensuite, c'est mon moteur de jeu qui travaille avec cette liste. Mais c'est ce moteur qui envoie aussi les informations ou le moteur stock lui ensuite les paquets à envoyer dans une autre liste et c'est le thread d'émission qui regarde si la liste contient des paquet à envoyer ?

    Schéma : Réception (thread 1) --> stockage liste 1 ---> Moteur de jeu/création paquet d'émission (thread 2) --> stockage liste 2 ---> Emission (thread 3).

    Est-ce une bonne façon de faire ?

  6. #6
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Citation Envoyé par shark59 Voir le message
    Excuse moi de cette question, mais tout ça dans un même thread c'est gérable (gestion de déplacement, IA, combat, etc...) ?
    Je n'ai pas d'expérience en MMORPG, mais je dirais que c'est la façon classique de faire dans un jeu. Maintenant, ça dépend aussi de combien de coeurs aura ton serveur, ça dépend du jeu, du niveau d'optimisation que tu souhaites, du temps que tu es prêt à passer. Il y a beaucoup de possibilités. Par exemple, tu peux faire l'IA sur un thread à part et garder la logique du jeu sur un seul thread.

    Mais tout ça est à voir avec le reste de l'équipe, je ne peux faire que de vagues hypothèses. Faire un MMORPG n'est pas simple, j'ai peur que tu manques d'expérience.

    Citation Envoyé par shark59 Voir le message
    Sinon, pour ce qui est de la réception, je stock les paquets "complexe" dans une liste. Ensuite, c'est mon moteur de jeu qui travaille avec cette liste. Mais c'est ce moteur qui envoie aussi les informations ou le moteur stock lui ensuite les paquets à envoyer dans une autre liste et c'est le thread d'émission qui regarde si la liste contient des paquet à envoyer ?
    Je ne suis pas sûr de voir l'intérêt de distinguer d'avoir un thread d'émission en plus du thread de réception. À part ça, ça a l'air de marcher.

  7. #7
    Membre du Club
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Novembre 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2010
    Messages : 61
    Points : 42
    Points
    42
    Par défaut
    Faire un MMORPG n'est pas simple, j'ai peur que tu manques d'expérience.
    J'en suis conscient que cela est une tâche complexe, mais je souhaite relever le défi. Prendre mon temps pour bien faire les choses. Je ne cherche pas à finir ca au plus vite.

    Je ne suis pas sûr de voir l'intérêt de distinguer d'avoir un thread d'émission en plus du thread de réception. À part ça, ça a l'air de marcher.
    Tout simplement car je ne vois pas comment on peut en même temps attendre des messages et en envoyer en même temps... ^^'
    J'aimerais (si possible) que tu développes un peu quels serait les avantages de mettre ceci dans un thread unique.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 351
    Points : 432
    Points
    432
    Par défaut
    Il doit avoir de nombreux topics sur le forum qui parle de ce sujet.

    Mais en gros tu as un "pool de threads" côté serveur , quand le serveur reçois une requête il attribue le traitement à un thread disponible du pool . En fait le thread principal ne fait qu'attendre et réceptionner les requêtes puis déléguer à un thread du pool.

    Pourquoi un pool car c'est assez coûteux la création d'un thread donc il vaut mieux le libérer quand on a fini de l'utiliser et le remettre dans le pool.

    Et quand tu es dans le thread délégué à la requête tu peux faire les traitements que tu souhaites , par exemple vérifier le déplacement demandé , changer la position du joueur si ça semble cohérent et enfin renvoyer la réponse au client.

    Donc pas besoin de créer un thread pour envoyé une réponse au client ce serait inutile et redondant.

    C'est comme cela que sont conçu tous les serveurs. Mais bon c'est juste la base de ton serveur , pas très long à concevoir.

    Mais le plus dur n'est pas la , c'est qu'après tu es dans un contexte multi-taches ça veux dire gestion de verrous, de méthodes synchronisé et ça c'est l'horreur à débugger, tu seras forcement confronté à de nombreux bugs.

    Par exemple si tu gère pas l'atomicité de tes transactions , un exemple donné par lead de développeur chez sun qui développait un serveur de jeux "généraliste" :

    Project Darkstar is touted as enabling online game developers to deal successfully with client failures, machine-room disasters, and race conditions. Tell us about those.

    I'll address race conditions, which produce dupe bugs, first. The online game community has its own language for describing bugs, which they describe from the perspective of players and not in terms of what causes them. For instance, almost every online game has what's called a dupe bug, which refers to the ability to place an object in a game in two places at once. So, for instance, an object could be both on the ground and in my pocket simultaneously, or on the table and on the floor. So they are called duplication bugs.

    From the point of view of a database programmer, that's a break in referential integrity. We know exactly what causes it: It's because the systems aren't transactional on the back end, so they can temporarily end up in states in which the referential integrity is not preserved. Darkstar is built on a transactional event-processing system that prevents this from happening.

    Give us some details on how dupe bugs occur.

    This is an oversimplified example, but imagine I engage in the act of giving you a dollar.

    You might code it in a way similar to this:

    Add $1 to your wallet. Increase your money variable by one.
    Remove $1 from my wallet. Decrease my money variable by one.
    What happens if the machine does step one and then it crashes? It never finished. So it added a dollar to you but didn't take a dollar from me. We've just duplicated a dollar.

    You might think you could reverse the order, but that doesn't help. If we do it this way:

    Remove $1 from my wallet.
    Add $1 to your wallet
    If we crash between steps one and two, a dollar vanishes to the twilight zone! That's not any better.

    Such a trade is what computer scientists call an atomic action. We can't do just half of it and preserve a sensible situation -- that's what we mean when we talk about referential integrity, that the data is in a sensible state.

    Transactional processing allows you to group multiple actions together and call them atomic, so that either they all happen or none of them do.

    A sudden crash such as I described earlier is rare, but I used it as a simple illustration. Multithreaded code sometimes has what are called race conditions, which are bugs that result from doing two incompatible things at once. I can demonstrate a race condition by breaking the action down and adding a thief in the crowd while I'm giving you a dollar.

    The action looks something like this:

    Get how much money I have as X.
    Get how much money you have as Y.
    If (X < 1) stop. I don't have any money to give.
    Set your money to y + 1.
    Set my money to x - 1.
    Let's say I only have one dollar in my wallet. The thief's pickpocket algorithm looks like this:

    Get how much money I have as TX.
    Get how much money the thief has as TY.
    If (TX < 0), then stop. I don't have any money to steal.
    Set my money as TX - 1.
    Set thief's money as TY + 1.
    Each of these actions works well alone, but if they occur simultaneously, problems can arise. Let me walk through what happens to X,Y, TX, and TY when the two routines race.

    Imagine I have one dollar in my wallet, everyone else has zero, and the following things happen:

    Get how much money I have as X. X now equals 1.
    A. Get how much money I have as TX. TX now equals 1.
    Get how much money you have as Y. Y now equals 0.
    B. Get how much money thief has as TY. TY now equals 0.
    If (X < 1), stop. X is 1, so I go on.
    C. If (TX < 0), then stop. TX is 1, so the thief continues.
    Set your money to y + 1. You now have one dollar.
    D. Set my money as TX - 1, I now have zero dollars.
    Set my money to x-1. X is still 1, so I get set to zero dollars.
    *again*
    E. Set thief's money as TY + 1. Thief now has one dollar.
    At the end, I have zero dollars, but you and the thief each have one dollar, so there are now two dollars in the world. We just duplicated a dollar!

    Transactions enforce isolation. They have rules to make sure races such as these can't happen. Race conditions are the number-one cause of dupe bugs.
    Puis ensuite tu auras toute la partie persistance des données, sans persistance pas de mmorpg qui tue tout ^^

    Donc mon humble conseil abandonne l'idée de tout refaire de a-z car ce que tu sembles vouloir coder, et la même base quelque soit le type de jeux.

    Utilise plutôt un serveur de jeu pour te simplifier la tâche, par exemple reddwarf server, SmartFoxServer, Photon Socket Server ect ...

    @++.

Discussions similaires

  1. Serveur qui attend des données client
    Par Gesthal dans le forum Développement Web en Java
    Réponses: 3
    Dernier message: 18/08/2010, 14h42
  2. Réponses: 7
    Dernier message: 29/05/2009, 21h47
  3. Réponses: 3
    Dernier message: 27/10/2008, 23h31
  4. [Client/Serveur] Comment procéder pour une validation par le Serveur ?
    Par wizad dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 11/09/2008, 09h47
  5. Meilleur protocole pour echange de données client/serveur
    Par melcom_dev dans le forum Développement
    Réponses: 2
    Dernier message: 23/03/2005, 19h28

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