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

Autres Java Discussion :

Serveur WEB "Vivant"


Sujet :

Autres Java

  1. #1
    Membre confirmé

    Inscrit en
    Novembre 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 46
    Par défaut Serveur WEB "Vivant"
    Bonjour,

    Je voudrai réaliser un serveur WEB "vivant", c'est à dire un serveur qui peut faire des calculs en interne à intervalles donné et renvoyer des pages web contenant les résultats de ces calculs.

    Pour expliquer ce que je veux, voici un exemple simple : Je part du petit programme simple qui calcule la somme de deux nombres et je veux lui ajouter un compteur de temps d'exécution du serveur. Ceci est fait pour illustrer ma demande qui fait un calcul en tâche de fond et je sais bien qu'il existe d'autres méthodes pour afficher ce résultat sans le calcul en tâche de fond.

    Programme simple de calcul d'une somme :
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    Hello world
    <form action = "add">
    enter 1 number : <input type = "text" name = "num1"><br>
    enter 2 number : <input type = "text" name = "num2"><br>
    <input type = "submit">
    </form>
    </body>
    </html>

    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
    package com.demo;
    import java.io.IOException;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
     
    public class AddServlet extends HttpServlet {
     
    	private static final long serialVersionUID = 1L;
     
    	public void service(HttpServletRequest req , HttpServletResponse res) throws IOException {
    		int i = Integer.parseInt( req.getParameter("num1"));
    		int j = Integer.parseInt( req.getParameter("num2"));
    		int k = i+j;		
    		res.getWriter().println("result " + k);		
    	}
    }
    Cette partie fonctionne parfaitement.
    Maintenant, je vais ajouter mon compteur de temps en utilisant une variable statique contenant le temps et aussi une méthode vit() qui va incrémenter cette variable. La méthode vit() sera exécutée par un Runnable qui sera initialisé dans la méthode init() de la servlet.
    Voici le code :
    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
    package com.demo;
     
    import java.io.IOException;
     
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
     
    import jakarta.servlet.ServletException;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
     
    public class AddServlet extends HttpServlet {
    	private static int temps = 0;
     
    	@Override
    	public void init() throws ServletException {
    		super.init();
    		Runnable pulseVie = new Runnable() {
    			public void run() {
    				vit();
    			}
    		};
    		ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
    		exec.scheduleAtFixedRate(pulseVie, 0, 1, TimeUnit.SECONDS);
    	}
     
    	private static final long serialVersionUID = 1L;
     
    	public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
    		int i = Integer.parseInt(req.getParameter("num1"));
    		int j = Integer.parseInt(req.getParameter("num2"));
    		int k = i + j;
    		res.getWriter().println("result " + k);
    		res.getWriter().println("Temps serveur " + temps);
    	}
     
    	public void vit() {
    		System.out.println("Temps de vie :" + temps);
    		temps = temps + 1;
    	}
    }
    Premier problème : (qui n'est pas si gênant que cela)
    Au démarrage du serveur, il ne "vit" pas.
    En effet, je n'ai aucune trace d'exécution et la ligne suivant ne s'exécute pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println("Temps de vie :" + temps);
    Si je remplis le formulaire de l'addition et que je demande le calcul (ex 1 + 2), je constate que mon serveur commence à "vivre" et j'obtiens le résultat suivant dans le navigateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    result 3
    Temps serveur 0
    Dans la console d'éclipse, je peux bien voir les traces d'exécution de la méthode vie()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Temps de vie :0
    Temps de vie :1
    Temps de vie :2
    Temps de vie :3
    ...
    Si je refais un calcul, je constaterai que la réponse indique le temps serveur en cours dans le navigateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    result 3
    Temps serveur 9
    A ce moment, je suis quand même assez content puisque j'ai le résultat désiré. Je peux arrêter le serveur et le relancer, cela fonctionne bien.

    Par contre si je fais une modification du code source et que je l'enregistre, eclipse relance automatiquement le serveur.
    Je constate alors que l'ancien compteur continue de défiler, et qu'un nouveau compteur se met en place quand j'effectue le premier calcul.
    La trace d'exécution deviens :

    Code x : 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
    (bla bla bla : 1er lancement du serveur)
    INFO: Le démarrage du serveur a pris [1172] millisecondes
    Temps de vie :0
    Temps de vie :1
    Temps de vie :2
    Temps de vie :3
    Temps de vie :4
    Temps de vie :5
    Temps de vie :6
    Temps de vie :7
    Temps de vie :8
    (modification du source, eclipse relance le serveur :)
    (bla bla bla)
    INFO: Le rechargement de ce contexte est terminé
    Temps de vie :9
    Temps de vie :10
    Temps de vie :11
    Temps de vie :12
    Temps de vie :13
    Temps de vie :14
    (je constate que l'ancienne version tourne toujours et partir d'ici je lance le second calcul qui va relancer l'initialisation et la création du Runnable, et je me retrouve avec deux processus qui tournent)
    Temps de vie :0
    Temps de vie :15
    Temps de vie :1
    Temps de vie :16
    Temps de vie :2
    Temps de vie :17
    Temps de vie :3
    Temps de vie :18
    Temps de vie :4
    Temps de vie :19
    Temps de vie :5
    Temps de vie :20


    Ma question : Comment faire une version propre de cela.
    Ou bien si un serveur Tomcat fait tourner ce programme, est-ce que j'ai des risques d'obtenir des exécutions en double, ou bien est-ce que je ne verrai que le problème dans eclipse pendant le développement (ce qui ne serai pas si grave après tout).

    Merci pour vos réponses, suggestions et idées.

  2. #2
    Membre chevronné
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mai 2020
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mai 2020
    Messages : 338
    Par défaut
    Le problème est que vous lancez un Thread qui ne s'arrête pas. Si votre servlet est de nouveau initialisée (comme c'est le cas quand eclipse relance) l'ancien thread tourne toujours et vous en lancez un second (ajoutez "Thread.currentThread().name()" dans vos "System.out" pour le constater).

    Pour éviter le problème, vous pouvez garder une référence au thread afin de l'arrêter lorsque la servlet est détruite: https://docs.oracle.com/javaee/7/api...html#destroy--

    Une autre solution serait de créer un service dédie que vous appelez depuis vos servlet. De cette façon vous pourriez garantir le fait qu'il n'y à qu'un seul compteur. Et vous pourriez aussi le lancer au démarrage de l'application et non pas à l'initialisation de votre servlet.

  3. #3
    Membre confirmé

    Inscrit en
    Novembre 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 46
    Par défaut
    Merci cela fonctionne bien avec la méthode destroy.

    Le code deviens celui-ci :

    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
     
    package com.demo;
     
    import java.io.IOException;
     
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
     
    import jakarta.servlet.ServletException;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
     
    public class AddServlet extends HttpServlet {
    	private static int temps = 0;
    	private static ScheduledExecutorService exec;
    	@Override
    	public void init() throws ServletException {
    		super.init();
    		Runnable pulseVie = new Runnable() {
    			public void run() {
    				vit();
    			}
    		};
    		exec = Executors.newScheduledThreadPool(1);
    		exec.scheduleAtFixedRate(pulseVie, 0, 1, TimeUnit.SECONDS);
    	}
     
    	@Override
    	public void destroy() {
    		super.destroy();
    		exec.shutdown();		
    	}
     
    	private static final long serialVersionUID = 1L;
     
    	public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
    		int i = Integer.parseInt(req.getParameter("num1"));
    		int j = Integer.parseInt(req.getParameter("num2"));
    		int k = i + j;
    		res.getWriter().println("result " + k);
    		res.getWriter().println("Temps serveur " + temps);
    	}
     
    	public void vit() {
    		System.out.println("Temps de vie :" + temps);
    		temps = temps + 1;		
    	}
    }
    Je n'ai pas d'intérêt spécial à ce que le serveur tourne avant la première requête donc je n'ai pas vraiment besoin d'un service. Pour le moment j'ignore tout des services, je découvrirais peut-être ca plus tard.
    Merci pour votre aide.

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

Discussions similaires

  1. Wine et serveur Web
    Par GLDavid dans le forum Applications et environnements graphiques
    Réponses: 6
    Dernier message: 26/06/2004, 00h19
  2. CORBA sur serveur web en local
    Par barberot dans le forum CORBA
    Réponses: 8
    Dernier message: 31/03/2004, 08h28
  3. Exploitation de base sur un serveur Web
    Par Oz-WereWolf dans le forum Installation
    Réponses: 10
    Dernier message: 07/03/2004, 22h52
  4. mise en place serveur web intranet
    Par gui4593 dans le forum Installation
    Réponses: 7
    Dernier message: 01/01/2004, 18h18

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