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 :

TicTacToe en réseau


Sujet :

Réseau et multijoueurs

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 41
    Points : 19
    Points
    19
    Par défaut TicTacToe en réseau
    Bonjour,

    Suite à mon sujet dans le forum Design patterns, je viens vous exposer mon problème. Je souhaite réaliser un TicTacToe (pour commencer) en réseau.

    En ce qui concerne la partie communication réseau, je vous explique en gros comment j'ai organisé mon programme. Au plus bas niveau, j'ai une classe Endpoint qui est juste une couche au dessus du Socket. Viens ensuite, ma classe Connection.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    public class Connection {
    	protected IEndpoint endpoint;
     
    	public Connection(IEndpoint endpoint) {
    		this.endpoint = endpoint;
    	}
     
    	public Connection(String hostName, Port port) throws IOException {
    		endpoint = new Endpoint(hostName, port);
    	}
     
    	public void sendMessage(Message message) throws IOException {
    		byte[] buffer = Protocol.getBuffer(message);
    		endpoint.send(buffer);
    	}
     
    	public Message getReceivedMessage() throws IOException {
    		byte[] buffer = new byte[Endpoint.RECEIVE_BUFFER_SIZE];
    		endpoint.receive(buffer);
    		return Protocol.getMessage(buffer);
    	}
     
    	public void close() {
    		endpoint.close();
    	}
     
    	public Port getRemotePort() {
    		return endpoint.getRemotePort();
    	}
    }
    Côté serveur, j'ai une classe ListenerPort qui encapsule un ServerSocket et est à l'écoute des clients qui tentent de se connecter. Puis, à chaque port correspond un Service qui contient les connexions, s'occupe de l'identification du client (chacun d'eux ayant un ClientID) et instancie un Dialogue avec celui-ci. Le Dialogue prend dans son constructeur un MessageHandler, assigné en fonction du type de service, pour gérer les messages.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    public abstract class AbstractMessageHandler {
    	private Type type;
    	private AbstractMessageHandler next;
     
    	public AbstractMessageHandler(Type type) {
    		this.type = type;
    	}
     
    	public void handleMessage(Connection connection, Message message) {
    		if (message.getType() == type) {
    			doAction(connection, message);
    		} else if (hasNext()) {
    			next.handleMessage(connection, message);
    		}
    	}
     
    	public void setNext(AbstractMessageHandler next) {
    		this.next = next;
    	}
     
    	public void addHandler(AbstractMessageHandler handler) {
    		if (hasNext()) {
    			next.addHandler(handler);
    		} else {
    			setNext(handler);
    		}
    	}
     
    	protected abstract void doAction(Connection connection, Message message);
     
    	private boolean hasNext() {
    		return (next != null);
    	}
    }
    A chaque type de message, son MessageHandler.

    C'est donc dans le MessageHandler que je fais appel aux différentes méthodes de la couche du domaine (dans ce cas-ci le jeu) en fonction du message reçu.

    Côté client, j'ai une classe Client qui établie les connexions avec le serveur. Et selon le port, j'instancie ou non un Dialogue.

    J'ai finalement, deux principales questions:
    • Comment dans mon cas créer une couche entre l'interface graphique et la communication réseau côté client ? Avec plusieurs facades en fonction des cas d'utilisation ?
    • Comment se fait la gestion d'un jeu qui se jour à tour de rôle ? Notamment, je n'arrive pas à gérer les inputs reçu par message du client ?


    Je sais pas si je me suis bien fait comprendre, dans le cas contraire n'hésitez pas me poser des questions :p

    Merci

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 815
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 815
    Points : 218 179
    Points
    218 179
    Billets dans le blog
    117
    Par défaut
    Bonjour,

    Comment dans mon cas créer une couche entre l'interface graphique et la communication réseau côté client ? Avec plusieurs facades en fonction des cas d'utilisation ?
    Si vous voulez deux modules vraiment séparés, vous pourriez utiliser une queue de message. Ainsi, dans la boucle événementielle de l'UI, elle irait voir si elle a reçu des messages du réseau et appliquerai ce qu'elle doit faire. Ainsi, le module réseau n'aurait absolument pas connaissance de ce qui se passe derrière et ne servirai juste à transformer les messages et gérer les connexions (ce qui est déjà beaucoup).

    Et nous pouvons maintenant étendre le concept à votre deuxième question. En effet, si on dit que chaque Contrôleur est un module indépendant de l'interface, alors eux aussi, pour indiquer les ordres à effectuer sur le jeu, ils utiliseraient la queue de messages. Ainsi l'UI, elle ne ferait que recevoir des messages, provenant du réseau ou du clavier, ou du joystick, ou du client mail sans même sans soucier (elle n'a pas trop besoin de connaitre l'origine).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 41
    Points : 19
    Points
    19
    Par défaut
    Je pense que MessageHandler est en quelque sorte ce que vous proposez. Des deux côtés, il s'occupe de gérer les messages qu'il reçoit (un handler pour chaque type de message) à une exception prêt est qu'il n'utilise pas de queue. D'ailleurs j'ai un doute sur l'utilité d'une queue ? J'ai du mal à voir.

    Un Dialogue est une boucle qui se bloque jusqu'à réception d'un message et qu'il le passe ensuite au MessageHandler. Côté serveur il y en a un pour chaque client connecté. Et côté client, ça dépend. Dans le cas d'un jeu, il pourrait y en avoir un qui scruterait les messages reçus pour actualiser le plateau de jeu si.

    Mais entre ces messages et l'interface graphique il ne faudrait pas une ou plusieurs classes en plus qui s'occuperaient de créer les messages, d'y ajouter les données nécessaires et de les envoyer ? Tout ce processus serait donc caché au client par des appels à des méthodes.

    Maintenant, j'ai peut-être mal compris ce que vous avez voulu dire

    Merci de votre aide

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 815
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 815
    Points : 218 179
    Points
    218 179
    Billets dans le blog
    117
    Par défaut
    Là, votre MessageHandler est comme une liste chainée, il faut toujours une suite, sinon cela s'arrête ?

    L'histoire d'une queue de messages (qui est un design pattern, je crois) c'est que vous pouvez avoir autant d'écouteur que vous voulez sur la queue, qui traiterons les messages ou pas (suivant ce que vous voulez). Les messages peuvent être prit ou juste lu (en les laissant).

    La queue de messages ne provoquent normalement pas de blocage.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 41
    Points : 19
    Points
    19
    Par défaut
    En effet, s'il n'y a pas MessageHandler associé à un type de messages, ceux-ci ne seront pas traités.

    Les écouteurs appartiendraient à l'interface graphique pour le client et à la couche du domaine pour le serveur ?

    Je n'arrive pas à bien cerner ce que vous me proposez. Par exemple côté serveur, une instance de la classe Game (une certaine partie de jeu) pourrait écouter la queue et s'occuper uniquement des messages qui concernent cette partie et traiter les messages, voir y répondre par d'autres messages au client ?

    Merci

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 815
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 815
    Points : 218 179
    Points
    218 179
    Billets dans le blog
    117
    Par défaut
    L'implémentation de la queue n'est pas pour une communication sur le réseau (chose que vous sembliez avoir fait et résolu). L'implémentation de la queue permet une communication à l'intérieur même de votre application, entre les différent module (réseau client qui communique les messages au module client GUI).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 41
    Points : 19
    Points
    19
    Par défaut
    J'ai essayé de faire un petit exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    public class Receiver {
    	public static interface {
    		public void messageReceived(Receiver receiver);
    	}
    	private static Receiver instance;
    	private BlockingQueue<Message> queue = new ArrayBlockingQueue<Message>();
    	private List<Listener> listeners = new ArrayList<Listener>();
     
    	private Receiver() {}
     
    	public static Receiver getInstance() {
    		if (instance == null) {
    			instance = new Receiver();
    		}
    		return instance;
    	}
     
    	public void addListener(Listener listener) {
    		listeners.add(listener);
    	}
     
    	public void removeListener(Listener listener) {
    		listeners.remove(listener);
    	}
     
    	public void putMessage(Message message) {
    		queue.put(message);
    		fireMessageReceived();
    	}
     
    	public Message examineMessage() {
    		return queue.element();
    	}
     
    	public Message takeMessage() {
    		return queue.take();
    	}
     
    	private void fireMessageReceived() {
    		for (Listener listener : listeners) {
    			listener.messageReceived(this);
    		}
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    public class GUI extends JFrame {
    	private JLabel score = new JLabel();
     
    	public GUI() {
    		super("My score");
    		buildComponents();
    	}
     
    	private buildComponents() {
    		Receiver.getInstance().addListener(new Listener() {
     
    			public void messageReceived(Receiver receiver) {
    				Message message = receiver.examineMessage();
    				if (message.getType() == Type.SCORE) {
    					receiver.takeMessage();
    					score.setText((String) message.getData("score"));
    				}
    			}
    		});
    	}
    }
    La méthode putMessage() serait utilisée par le thread qui écoute un port si un message a été envoyé par le serveur et le mettra dans la queue.

    Et lorsque le client souhaite envoyer une requête au serveur, il crée un message selon ce qu'il veut, et l'envoie au serveur où un handler s'en occupe.

    On pourrait également créer une série de messages qui héritent de la classe Message et y ajouter des setters/getters propre à ce type de message, qui en soi se serveront de getData().

Discussions similaires

  1. [Réseau] Créer une connexion Internet
    Par Tranber dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 17/10/2002, 18h01
  2. Réseau Win/Linux
    Par ben91 dans le forum Développement
    Réponses: 2
    Dernier message: 08/09/2002, 23h59
  3. Comment subsituer un chemin par un autre dans un réseau ?
    Par Baillard dans le forum Développement
    Réponses: 3
    Dernier message: 11/08/2002, 15h01
  4. Redimensionnement des Paquets IP sur un Réseau Local
    Par Bonoboo dans le forum Développement
    Réponses: 2
    Dernier message: 12/07/2002, 16h40

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