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

API standards et tierces Java Discussion :

Compiler du java en natif & Optimisation serveur socket


Sujet :

API standards et tierces Java

  1. #21
    Membre expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Points : 3 675
    Points
    3 675
    Par défaut
    ajoute une instruction du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    try {Thread.sleep(20);} catch(Throwable t){}
    en fin de boucle

    d'après moi c'est le thread qui s'affole

    en fait lorsque tu enregistres un channel, il ne faut pas l'enregistrer en lecture/écriture, mais en lecture seule. Il faut ajouter l'intérêt pour l'écriture à la selectionkey uniquement lorsque tu as besoin d'écrire

    Sinon, tous les canaux seront sélectionnés instantanément à chaque fois, puisqu'ils seront probablement tous prêt à l'écriture

  2. #22
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    Super !
    ça marche impec, merci encore Pill_S !

    Maintenant je vais tester avec plus de 50 users pour voir si ça tient ^^

  3. #23
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    Bon alors ça marche bien, mais le serveur plante 2 fois par jour....
    Je pense que c'est à cause de mon système mysql...
    Maintenant je n'utilise pas de Pool de connexions, mais une seule connexion mysql qui se reconnecte toutes les 2 minutes, et les Statement et ResultSet sont fermés après chaque requète.
    S'il y a une erreur mysql, le Statement et le ResultSet sont fermés et je lance une Exception pour l"user, et si la connexion mysql est perdue, elle est relancée (avec à chaque fois une boucle d'attente si une requète est demandée par un user).

    En gros dans ma classe ConnexionMysql, j'ai fait une fonction query(String requete) qui retourne un ResultSet, un fonction flush() pour clore le Statement et le ResultSet et définir la connexion ocmme libre (variable inuse), et une fonction update(String requete) pour les DELETE, INSERT INTO et UPDATE, elle renvoi ce que renvoi stmt.executeUpdate() et ferme tout seul le Statement (pas besoin de flush pour update()).

    Donc tout ceci marche très bien pendant quelques heures, mais ça finit par planter : la connexion est définie comme occupée, et si je libère ou relance la connexion mysql (par une commande de mon serveur, avec la classe Commandes), j'obtient une erreur Java qui me cite tous les noms de fonctions de ma classe principale.
    Pourtant j'ai mis des try partout, et j'ai bien libéré la connexion après chaque utilisation, je comprend vraiment pas.

    Merci à ceux qui ont eu le courage de lire tout ça, et ça serait super sympa de m'aider ;-)

  4. #24
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Quel est la trace complète de l'exception que tu obtiens ?
    Sinon pourquoi est-ce que tu utilises une seule connection ? Il serait plus propre de la fermer après chaque utilisation... non ?
    Enfin est-ce que tu fermes bien tout tes éléments dans un bloc finally ?

    a++

  5. #25
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    Non je ne ferme pas la connexion mysql à chaque fois car elle est très souvent utilisée (il y a en moyenne dans les 70 connectés au serveur xmlsocket, donc 4 requètes à l'identification, plus quelques requètes de temps en temps pour certaines actions).

    J'ai au total 5 classes, dont la principale (MurtiesServ) et une en threads.
    Le thread est la classe Commandes qui n'est jamais stoppée.
    Donc je ne vois pas à quoi servirais un finally

    L'erreur que j'obtiens termine par ça : (je n'ai pas le début car ça prend toute la place dans la fenètre de commandes)
    at MurtiesServ.sendAll(MurtiesServ.java:367)
    at MurtiesServ.delClient(MurtiesServ.java:511)
    at MurtiesServ.sendMessage(MurtiesServ.java:192)
    at MurtiesServ.sendAll(MurtiesServ.java:357)
    at MurtiesServ.sendAll(MurtiesServ.java:367)
    at MurtiesServ.delClient(MurtiesServ.java:511)
    at MurtiesServ.sendMessage(MurtiesServ.java:192)
    at MurtiesServ.sendAll(MurtiesServ.java:357)
    at MurtiesServ.sendAll(MurtiesServ.java:367)
    at MurtiesServ.delClient(MurtiesServ.java:511)
    at MurtiesServ.sendMessage(MurtiesServ.java:192)
    at MurtiesServ.sendAll(MurtiesServ.java:357)
    at MurtiesServ.sendAll(MurtiesServ.java:367)

    Cette erreur me signale donc des erreurs dans les fonctiosn d'envoi de messages au users connectés (par SocketChannel), mais la connexion mysql semble également bloquée.
    Je n'arrive pas à faire le rapprochement ^^'''

  6. #26
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Skreo
    Donc je ne vois pas à quoi servirais un finally
    A être sûr que tu fermes bien ton ResultSet et ton Statement dans tous les cas...
    Si tu te retrouves dans un cas particulier où tu ne fermes pas correctement ton Statement/ResulSet, cela peut finir par te poser des problèmes...

    Citation Envoyé par Skreo
    L'erreur que j'obtiens termine par ça : (je n'ai pas le début car ça prend toute la place dans la fenètre de commandes)
    Il faudrait au moins le début avec la description de l'exception... et eventuellement le code de la méthode sendAll() avec les numéro de ligne...

    a++

  7. #27
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    En fait je ne comprend pas très bien l'interêt du finally.
    J'ai trouvé ça sur internet :

    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
    public class WithFinally {
      static Switch sw = new Switch();
      public static void main(String[] args) {
        try {
          sw.on();
          // Code that can throw exceptions...
          OnOffSwitch.f();
        } catch(OnOffException1 e) {
          System.err.println("OnOffException1");
        } catch(OnOffException2 e) {
          System.err.println("OnOffException2");
        } finally {
          sw.off();
        }
      }
    }
    pourquoi ne pas faire tout simplement :

    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
    public class WithFinally {
      static Switch sw = new Switch();
      public static void main(String[] args) {
        try {
          sw.on();
          // Code that can throw exceptions...
          OnOffSwitch.f();
        } catch(OnOffException1 e) {
          System.err.println("OnOffException1");
        } catch(OnOffException2 e) {
          System.err.println("OnOffException2");
        }
        sw.off();
      }
    }
    Qu'est ce que ça change ?

  8. #28
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    A partir du moment où tu rentres dans le try, le bloc finally sera toujours exécuté quoi qu'il arrive dans le bloc try ou les blocs catch, même s'il y a une instruction return ou une exception de propager...


    Dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try {
    	sw.on();
    	// Code that can throw exceptions...
    	OnOffSwitch.f();
    } catch(OnOffException1 e) {
    	System.err.println("OnOffException1");
    } catch(OnOffException2 e) {
    	System.err.println("OnOffException2");
    }
    sw.off();
    Si l'instruction OnOffSwitch.f() renvoit une exception différente de OnOffException1 et OnOffException2 (ce qui est possible si la méthode déclare renvoyer une exception, ou bien s'il s'agit d'une RuntimeException), elle ne sera pas attrapée par les catch, et donc remonté à la méthode appellante...

    Du coup ton instruction sw.off() n'est pas appellé... alors qu'elle le serait avec un bloc finally...

    Bien sûr dans certain cas cela n'est pas bien grave... mais lorsqu'il s'agit d'une connection réseau ou d'un fichier cela peut poser des problèmes (on peut atteindre des limites du systèmes, en particulier dans le cas d'un serveur).

    Je ne sais pas si je suis bien clair ?


    a++

    PS : quel est le message de ton exception au fait ?

  9. #29
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    Merci pour ta réponse maintenant j'ai compris ^^
    Alala vous êtes sympa ici :p

    Si après chaque requète mysql, je fais ça, ça va ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    result.close();
    stmt.close();
    Est-ce que ça libère bien la mémoire ?
    Et faut-il utiliser stmt.cancel() si je veux interrompre une requète par un autre thread ?

    Et de même pour les SocketChannel des utilisateurs, avec un simple socketchannel.close(); ça va ?

  10. #30
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Oui l'appel à close() suffit pour libérer les resources (c'est fait pour ca d'ailleurs!).
    Mais il faut le faire dans tous les cas...

    Le meiux c'est que tu nous montre un bout de code de ce que tu fais

    a++

  11. #31
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    Merci ^^
    J'ai fait des simulations avec un client qui ouvrait des centaines de connexions avec des dizaines de requètes à la seconde, et il n'y a eu aucun problème. Le bug survenait par contre à la déconnexion du client.
    J'avais mal géré mes fonctions de déconnexion et les exception.
    Ca marche maintenant parfaitement bien ! (entout cas pour le moment ^^)

  12. #32
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    Bonjour

    Je relance le sujet, car mon serveur fonctionne très bien, sauf qu'un problème de déconnexion mal gérée du client survient parfois.
    Je ne sait pas si on peut réparer ça, mais parfois (en général quand la connexion internet du client plante), la connexion est coupée, sauf que ni le client, ni le serveur ne détecte la déconnexion.

    Bon j'ai un peu épuré, mais voici la fonction principale du serveur :

    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    public static void startServer(){
    	logErreur("Démarrage serveur");
    	try {
    		// Create the server socket channel
    		server = ServerSocketChannel.open();
    		// nonblocking I/O
    		server.configureBlocking(false);
    		server.socket().bind(new java.net.InetSocketAddress(port));
    		// Create the selector
    		Selector selector = Selector.open();
    		SelectionKey acceptKey = server.register(selector, SelectionKey.OP_ACCEPT);
     
    		// Attente des connexions...
    		while (true) {
    			Set readyKeys;
    			Iterator it;
    			try {
    				// Wait for an event
    				selector.select();
    				// Get keys
    				readyKeys = selector.selectedKeys();
    				// iterate over the set of selected keys:
    				it = readyKeys.iterator();
    			} catch (Exception ee) {
    				// Handle error with selector
    				continue;
    			}
    			try {
    				// Look at each key in the selected set:
    				while (it.hasNext()) {
    					SelectionKey key = (SelectionKey) it.next();
    					it.remove();
    					if (key.isAcceptable()) {
    						try {
    							SocketChannel client = server.accept();// get client socket channel
    							client.configureBlocking(false); // Non Blocking I/O
    							client.register(selector, SelectionKey.OP_READ); // recording to the selector (reading & writing)
    							String ip = client.socket().getInetAddress().getHostAddress();
    							// Ajout du client
    							addClient(client, ip);
    						}catch(Exception eee){
    							// Connexion échouée
    							logErreur("!! Erreur : startServer() key.isAcceptable()  !!" + eee.getMessage());
    						}
    						continue;
    					}
     
    					try {
    						if (key.isReadable()) {
    							SocketChannel client = (SocketChannel) key.channel();
    							ServerThread thread = selectThread(); // Sélection d'un thread libre de traitement des données reçues
    							thread.client = client;
    							thread.busy = true;
    						}
    					}catch(Exception eee){
    						logErreur("!! Erreur : startServer() key.isReadable()  !!" + eee.getMessage());
    					}
    				}
    				}catch(Exception ee){}
    				try {Thread.sleep(50);} catch(Throwable t){}
    			}
    	} catch (Exception e) {
    		logErreur("!! Erreur : startServer() démarrage  !!" + e.getMessage());
    		exitServer();
    		System.exit(-1);
    	}
    }

  13. #33
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 46
    Points : 24
    Points
    24
    Par défaut
    Personne ne saurait svp ?

Discussions similaires

  1. [Compilation]Compilateur Java
    Par gurv4n dans le forum Général Java
    Réponses: 4
    Dernier message: 09/01/2008, 21h31
  2. compiler java en natif
    Par darkbob dans le forum API standards et tierces
    Réponses: 8
    Dernier message: 01/10/2007, 11h59
  3. Réponses: 2
    Dernier message: 31/10/2005, 18h30
  4. [Java] Communication entre client et serveur
    Par danje dans le forum CORBA
    Réponses: 1
    Dernier message: 14/12/2004, 18h08

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