Java : lenteur avec Objet envoyer par Socket avec KeyEvent

cs_nemata Messages postés 12 Date d'inscription vendredi 4 mars 2005 Statut Membre Dernière intervention 27 mars 2009 - 8 mars 2009 à 22:58
cs_nemata Messages postés 12 Date d'inscription vendredi 4 mars 2005 Statut Membre Dernière intervention 27 mars 2009 - 11 mars 2009 à 20:40
Bonsoir, je développe actuellement un Bomberman en java et en réseau 2 joueur, je peut actuellement envoyer un objet léger avec simplement la position x et y en getter and setter de mon joueur a l'autre pc qui la reçois et fait de même lorsque il bouge.
Mon problème est que l'objet est envoyer a chaque pression de keyPressed de KeyEvent et lorsque je reste appuyer mon pc bloque pendant plusieur seconde le temps d'envoyer l'objet et que je le recupere en le castant de l'autre coté

Pour le moment j'essais simplement de faire bouger un fillOval();

coté client c'est simplement :


    public void keyPressed(KeyEvent e) {

       //Provoque le changement de coordonné x ou y en fonction de la touche pressé


        this.draw.moveCircle(e);


        repaint();


        sendToClient();


    }


    public void sendToClient(){

        try

        {

            socket = new Socket(ip, port);

            OutputStream output = socket.getOutputStream();

            InputStream input = socket.getInputStream();

           

            ObjectOutputStream out = new ObjectOutputStream(output);           

            ObjectInputStream in = new ObjectInputStream(input);


            out.writeObject(this.draw);

           

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

et coté serveur :
                clientSocket = serverSocket.accept();
                try
                {
                    InputStream in = clientSocket.getInputStream();
                    OutputStream out = clientSocket.getOutputStream();
   
                    ObjectInputStream input = new ObjectInputStream(in);
                    ObjectOutputStream output = new ObjectOutputStream(out);                   
                   
                    try {
                        Drawing draw = (Drawing)input.readObject();
                    } catch (ClassNotFoundException e1) {
                        e1.printStackTrace();
                    }

je ne pense pas que mettre un timer soit la solution, ou sinon peut être d'envoyer plutot un tableau d'int xy, mais cela ne me plait pas beaucoup, j'aurais aimé faire un systeme tres souple pour pouvoir rajouter d'autre paramettre.

Merci

5 réponses

cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 mars 2009 à 08:59
Salut,

"je ne pense pas que mettre un timer soit la solution", et pourtant ! Entre envoyer un objet toute les secondes et envoyée 1000 objets par seconde, je pense que le choix est vite fait...

Le principe est de bufferiser les événements : tu déclenche le timer sur la première touche appuyée, mais tu n'envoie pas automatiquement les données, tu attends x ms, et pendant ce temps, si l'utilisateur appuie sur une autre touche, tu la bufferise (tu la stocke), enfin, lorsque le timer se déclenche, au lieu d'envoyer x objets, tu n'en envoie qu'un seul qui stocke les x événements. Du coup, tu vas limiter le nombre de connexion à faire et la taille des données à envoyer !

Rien qu'avec cà déjà ca devrait limiter de beaucoup les blocages !
______________________________________
DarK Sidious
0
cs_nemata Messages postés 12 Date d'inscription vendredi 4 mars 2005 Statut Membre Dernière intervention 27 mars 2009
9 mars 2009 à 11:23
Merci beaucoup de cette solution, je pense effectivement que cela devrait aider j'espère juste que le jeu restera fluide.
J'ai une autre question les jeux qui se jouent en réseaux style cs, wow, lineage etc, le processus se passe comme cela? des qu'un evenement ce passe l'image est envoyé au client? Faut t'il donc que des port soit ouvert chez le client pour laisser passé les requetes du serveur?
0
cs_nemata Messages postés 12 Date d'inscription vendredi 4 mars 2005 Statut Membre Dernière intervention 27 mars 2009
9 mars 2009 à 21:28
J'ai fais des tests et le problemes est lors du casting de l'objet quand le client le recois :

          clientSocket = serverSocket.accept();
                try
                {
                    InputStream in = clientSocket.getInputStream();
                    OutputStream out = clientSocket.getOutputStream();
   
                    ObjectInputStream input = new ObjectInputStream(in);
                    ObjectOutputStream output = new ObjectOutputStream(out);                   
                   
                    try {
                        Drawing draw = (Drawing)input.readObject();
                    } catch (ClassNotFoundException e1) {
                        e1.printStackTrace();
                    }

Lorsque cette ligne est effectuer Drawing draw = (Drawing)input.readObject(); tout ralentit n'y a pas une autre maniere de recuperer l'objet et peut etre de ne pas le crée a chaque fois mais de le mettre a jour, le probleme est que j'ai voulu récuperer les variable tel que :

int x = (Drawing)input.readObject().getX;

mais cela ne marche apparament pas sauf si je le crée avec Drawing draw.

Si vous avez une solution je suis prenneur merci

PS : pour ma question sur comment sont gerer les jeux en réseaux pour envoyer les deplacement en général tiens toujours ^^
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
10 mars 2009 à 07:54
Salut,

Ce n'est pas le cast qui est lent (ca c'est relativement rapide), mais le readObject : java est rapide, mais pour ce qui est des input/output, il est très lent (c'est le cas de la grande majorité des langages interprêtés). C'est pour cela qu'il faut éviter de trop utiliser les envois/réceptions de données ! Il vaut mieux sérialiser un gros objet qui contiendras un max d'informations (cela économisera la bande passante : une seule frame pour tout envoyer plutôt que des miliers de frames si plusieurs envois), et optimisera la lecture (un seul objet lu au lieu d'un milier de lecture dans le stream). Il n'y a pas de solutions miracle

Sinon, pour ta culture personnelle, ce n'est pas :
int x = (Drawing)input.readObject().getX;

Mais :
int x = ((Drawing)input.readObject()).getX;

Mais je te déconseille cette approche : c'est aussi couteux (lecture de l'objet complet, puis cast vers un objet de type Drawing, avant de récupèrer la valeur x), et si tu as plusieurs champs à récupèrer, il va devoir créer n fois l'objet à partir du stream !

Concernant les jeux en réseaux en général, je ne sais pas comment ils font au juste, mais ca doit pas être loin de la même chose, mais avec un thread histoire de ne pas bloquer le jeu lors d'une lecture...
______________________________________
DarK Sidious
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_nemata Messages postés 12 Date d'inscription vendredi 4 mars 2005 Statut Membre Dernière intervention 27 mars 2009
11 mars 2009 à 20:40
Oui je m'en suis sorti avec 3 thread,
- un thread qui permet de faire tournée le serveur en boucle sans bloquer le jeux,
- un thread qui envois les données au client toutes les 10ms,
- et un double buffer qui comporte un buffered image et un thread pour "repain()" le jeux toutes les 10ms

Avec ceci mes deplacements sont tres fluides des deux coté du joueurs ainsi et de ne pas avoir de grosse latence entre les deux pc qui seraient injouable.

Merci pour tes réponses
0
Rejoignez-nous