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

Servlets/JSP Java Discussion :

Problème de thread et socket : Affichage variables


Sujet :

Servlets/JSP Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Alternant Services informatique
    Inscrit en
    Janvier 2020
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Alternant Services informatique

    Informations forums :
    Inscription : Janvier 2020
    Messages : 40
    Par défaut Problème de thread et socket : Affichage variables
    Bonjour à tous, meilleurs vœux à la communautés.

    Actuellement en alternance dans un entreprise pour valider ma deuxième années de BTS, je développe une application web java de supervision pour un site de production.

    N'ayant aucune connaissances dans le langage java EE, je m'amuse pour le moment à comprendre le principe d'une application web (servlets, jsp, beans, jstl..).

    L'application communique avec un IPX 800 V3 qui est un automate contrôlable. Donc le but de l'appli est de pouvoir afficher les résultat d'une requête M2M ainsi que la réponse de l'ipx.

    Donc j'arrive à me connecter à mon "Serveur" qui est l'ipx, j'arrive à lui envoyer une requête et je reçois bien la réponse mais le soucis c'est lorsque je souhaite renvoyer requête la réponse ne s'affiche plus.

    J'utilise un socket pour la connexion ainsi que deux thread pour écrire et pour lire. (Je me doute que le soucis provient d'ici, mais je trouve pas après pas mal de recherches.)

    Pour l'affichage j'ai utilisé un <c:if test="${ !empty ..... }, comme je vous l'ai dit plus haut lorsque je fais plusieurs requête je n'ai pas l'affichage de la réponse alors que dans la console de Eclipse il apparaît.

    Voici mon code :

    Page.jsp

    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
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="ISO-8859-1">
    <title>Application Web Simoldes Plasticos</title>
    </head>
    <body>
    	<h1>Simoldes Plasticos France</h1>
    	<h2>Application web de supervision</h2>
     
    	<form method="post" action="bonjour">
    	<p>
    		<label for="commande">Afficher état des entrées : </label>
    		<input type="text" id="commande" name="commande"/>
    	</p>
     
     
    	<input type="submit"/>
    	</form>
    	<c:if test="${ !empty form.resultat }"><p><c:out value="${ form.resultat }" /></p></c:if>
    	<c:if test="${ !empty form.resultat2 }"><p><c:out value="${ form.resultat2 }" /></p></c:if>
     
    </body>
    </html>
    Connection.java

    Code Java : 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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    package org.cochet.web.forms;
     
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;
     
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    public class ConnectionForm {
    	private String resultat;
    	private String resultat2;
    	static final int port = 9870;
     
    	public void connection( HttpServletRequest request) throws IOException {
    		String commande = request.getParameter("commande");
     
    		if(commande.equals(commande = "test")) {
    			final Socket clientSocket;
    		      final BufferedReader in;
    		      final PrintWriter out;
    		      final Scanner sc = new Scanner(System.in);//pour lire à partir du clavier
     
    		      try {
    		         /*
    		         * les informations du serveur ( port et adresse IP ou nom d'hote
    		         * 127.0.0.1 est l'adresse local de la machine
    		         */
    		         clientSocket = new Socket("***********" ,9870);
     
    		         //flux pour envoyer
    		         out = new PrintWriter(clientSocket.getOutputStream());
    		         //flux pour recevoir
    		         in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
     
     
     
    		         Thread envoyer = new Thread(new Runnable() {
    		             String msg = "GetInputs";
    		              @Override
    		              public void run() {
    		                while(true){
    		                 // msg = sc.nextLine();
    		                  out.println(msg);
    		                  out.flush();
    		                  resultat = "commande envoyée : "+msg;
    		                }
    		             }
    		         });
    		         envoyer.start();
     
    		        Thread recevoir = new Thread(new Runnable() {
    		            String msg;
    		            @Override
     
    		            public void run() {
    		               try {
    		                 msg = in.readLine();
     
    		                 //while(msg!=null){
    		                 resultat2 = "Reponse : "+msg;
    		                    System.out.println("Serveur : "+msg);
     
    		                    msg = in.readLine();
     
    		                // }
     
    		                 System.out.println("Serveur déconnecté");
     
    		                 out.close();
    		                 clientSocket.close();
     
    		               } catch (IOException e) {
    		                   e.printStackTrace();
    		               }
    		            }
    		        });
    		        recevoir.start();
     
    		      } catch (IOException e) {
    		           e.printStackTrace();
    		      }
     
     
     
    		}else
    			resultat = "Commande incorrect !";
    	}
     
    	public String getResultat() {
    		return resultat;
    	}
     
    	public void setResultat(String resultat) {
    		this.resultat = resultat;
    	}
     
    	public String getResultat2() {
    		return resultat2;
    	}
     
    	public void setResultat2(String resultat2) {
    		this.resultat2 = resultat2;
    	}
    }

    Et la servlet :

    Code Java : 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
    package org.cochet.web.servlet;
     
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    import org.cochet.web.beans.Auteur;
    import org.cochet.web.forms.ConnectionForm;
     
     
    @WebServlet("/bonjour")
    public class bonjour extends HttpServlet {
    	private static final long serialVersionUID = 1L;
     
     
        public bonjour() {
            super();
     
        }
     
     
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    				this.getServletContext().getRequestDispatcher("/WEB-INF/bonjour.jsp").forward(request, response);
    	}
     
     
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		ConnectionForm form = new ConnectionForm();
    		form.connection(request);
     
     
    		request.setAttribute("form", form);
     
    		this.getServletContext().getRequestDispatcher("/WEB-INF/bonjour.jsp").forward(request, response);
    	}
     
     
    }

    Voici le résultat attendu :

    Nom : Capture.PNG
Affichages : 529
Taille : 28,5 Ko

    Lorsque je re-clique sur soumettre le requête voici le résultat (la réponse ne s'affiche pas)

    Nom : Capture2.PNG
Affichages : 495
Taille : 25,6 Ko

    Lorsque je continue de cliquer :

    Nom : Capture3.PNG
Affichages : 482
Taille : 21,6 Ko

    Merci d'avance de me lire.
    Cordialement
    Un novice

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Globalement, tu dois aborder la problématique comme des processus asynchrones.

    1. Tu ne peux pas procéder comme ça, lancer 2 threads dans le thread d'exécution de la servlet.
      Le principe des threads c'est qu'ils s'exécutent en parallèle. Le thread de la servlet continue de s'exécuter pendant que les deux autres s'exécutent. Le forward s'effectue alors que les threads d'échange avec l'automate tournent. Par chance, les deux threads peuvent modifier les variables de l'attribut "form" avant que le résultat de la jsp se génère, donc tu peux voir les valeurs de resultat et resultat2. Par chance, parce que cette génération prend à priori un peu plus de temps que le temps d'exécution de l'échange avec l'automate. De toute façon, tu n'auras qu'un seul "résultat".

      Appelons S le thread de la servlet, E le thread d'envoi, R le thread de réception.
      Il faut que S attende que R ait reçu son message avant de retourner un résultat. On pourrait procéder par join (pour attendre que l'échange avec l'automate soit effectué), mais le plus adapté est d'utiliser un AsyncServlet. C'est R qui sera exécuté via l'AsyncServlet, et qui lancera E, puis attend le résulat et "renvoie" le résultat comme résultat d'exécution de servlet.
    2. Pourquoi envoyer en boucle une commande à l'automate si c'est pour fermer la socket dès la réception d'une réponse. Tu envoies une commande et tu reçois une réponse. Si le but est de pouvoir envoyer plusieurs commandes et pouvoir afficher chaque résultat, il faut que tu procèdes commande par commande. Fait une classe, mettons Automate qui a trois méthodes : une pour établir une connexion (connect() par exemple), une pour envoyer une commande (String send(String, PrintWriter)) par exemple), une méthode pour terminer la connexion (disconnect() par exemple).
      Lors d'invocation de la servlet, tu crées un attribut de session automate pour une instance de Automate, seulement s'il n'y en a pas déjà un. Dans ce cas, tu le récupères et tu l'utilises : ainsi à chaque invocation, tu utilises la même instance.
    3. Utilises un ExecutorService, pour pouvoir envoyer plusieurs commandes l'une après l'autre, à chaque invocation de la servlet.
    4. Pour le résultat, plutôt que d'utiliser un attribut, j'écrirais un json (avec la commande et son résultat, en données) dans le flux de la réponse et je ferais l'invocation en ajax dans la page, en asynchrone (le principe est le même que pour l'AsyncServlet). Tu pourras lancer plusieurs commandes dans la page, à ton rythme, et chaque résultat pourra être affiché, sans que la page entière ne soit rechargée.

    Si j'ai le temps, j'essayerais de te faire un petit POC.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre averti
    Homme Profil pro
    Alternant Services informatique
    Inscrit en
    Janvier 2020
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Alternant Services informatique

    Informations forums :
    Inscription : Janvier 2020
    Messages : 40
    Par défaut
    Salut a toi

    D'abord merci beaucoup pour ta réponse construite, cela va beaucoup m'aider.

    Aurais-tu une doc pour la AsyncServlets ?

    Cela fait un petit moment que je suis bloqué, que je n'arrive pas a comprendre tous le fonctionnement. Je regarde tout ce que tu m'as donné, je vais sans doute revenir vers toi.

    Je suis preneur pour un POC si tu as le temps.

    Encore merci a toi.

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Ça me parait un peu compliqué les n threads...

    Une servlet étant multi-thread par nature, n requêtes s'exécutent dans n thread, du coup, on peut très bien imaginer de faire l'envoi de la commande et la lecture du résultat séquentiellement.
    Je ferais un appel ajax pour le cas où tu aurais besoin de passer plusieurs commandes sans attendre le résultat précédent.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Je pense que les threads sont nécessités par la communication asynchrone avec l'automate, comme cela se passerait avec un programme externe (cf ProcessBuilder). Exécuter n requêtes à la servlet ne garantit pas l'ordre d'exécution, et cela pourrait être nécessaire pour la communication avec un automate. Egalement si l'automate est monoprocess : séquentialiser les échanges permet d'éviter d'avoir à gérer le cas où l'automate refuse la connexion pendant qu'un échange est en cours. Maintenant, si on établit une connexion et une déconnexion à chaque échange, et l'automate répond directement une requête, et est capable de traiter plusieurs requêtes simultanées, oui on n'a ni besoin de threads, ni besoin de séquentialiser les différents échanges avec la servlet.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Membre averti
    Homme Profil pro
    Alternant Services informatique
    Inscrit en
    Janvier 2020
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Alternant Services informatique

    Informations forums :
    Inscription : Janvier 2020
    Messages : 40
    Par défaut
    Bonjour,

    Cela me parait compliqué, surtout le manque de doc sur l'asyncServlet.

    J'ai 26 automates et 26 ANDON(c'est un outil industriel et visuel qui permet de révéler d'un simple coup d'œil qu'un poste de travail rencontre une anomalie), j'aimerais lorsque je me connecte sur l'application que je puisse voir l'état de tout mes automates (Etat de led : Blanc / Vert / Rouge / Orange / Bleu).


    L'automate répond directement après la requête. Donc il serait possible de ne pas utiliser les thread ?

    Je suis totalement perdu et je ne sais plus sur quoi me pencher x)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Python 3.X] Problème récupération de données socket via Thread
    Par Zakche dans le forum Général Python
    Réponses: 4
    Dernier message: 20/10/2019, 16h25
  2. Problème de conception Thread et Socket
    Par NeqO55 dans le forum Concurrence et multi-thread
    Réponses: 6
    Dernier message: 15/10/2009, 09h57
  3. [Kylix] Problème de thread
    Par A&Nexus dans le forum EDI
    Réponses: 1
    Dernier message: 03/05/2005, 21h48
  4. problème de compil devc++ socket
    Par stefdem dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 11/12/2003, 11h33
  5. [VC++6][DX9] Problème de thread lors d'un blit ...
    Par grandjouff dans le forum DirectX
    Réponses: 2
    Dernier message: 12/06/2003, 22h22

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