Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Candidat au titre de Membre du Club
    Inscrit en
    octobre 2008
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : octobre 2008
    Messages : 75
    Points : 13
    Points
    13

    Par défaut synchronisation de client

    bonjour, je développe actuellement un programme dans lequel un client doit attendre qu'un autre fasse une action pour mettre à jour ses données.
    En java j'utiliserai une méthode synchronized avec un wait et un notify pour le realiser mais en java ee je sèche.

    en gros pour donner un exemple simple je pourrais avoir:

    un client(1) pose des sous sur la table et attend qu'un autre les prenne
    un client(2) prend les sous et prévient l'autre que c'est fait
    1 rafraîchi son affichage

    je suis dans un singleton déployé sur glassfish mais je ne pense pas que ça change grand chose (glassfish).

    en attendant vos idées, moi je suis à cours d'idées après avoir regardé du cotés des lock (les synchronized étant interdit dans les ejb)

  2. #2
    Membre Expert Avatar de fxrobin
    Homme Profil pro
    Formateur JAVA / XML
    Inscrit en
    novembre 2007
    Messages
    866
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Formateur JAVA / XML
    Secteur : Service public

    Informations forums :
    Inscription : novembre 2007
    Messages : 866
    Points : 1 188
    Points
    1 188

    Par défaut

    Alors 2 solutions :

    1 - soit du JMS et Message Driven Bean pur (pas simple)
    2 - soit @Asynchronous avec Future<V> sur un Session Bean En gros des méthodes EJB asynchrones : http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html

    Perso, je ferai la solution 2.

    Si tu n'es pas en mode "EJB", tu peux toujours faire avec "Callable" et "Future" du framework Executor apparu avec Java 5.
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

  3. #3
    Candidat au titre de Membre du Club
    Inscrit en
    octobre 2008
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : octobre 2008
    Messages : 75
    Points : 13
    Points
    13

    Par défaut

    j'avais pensé à JMS mais ça me parait trop gros pour ce que je veux faire, asynchronous me parait bien mais... Comment je fais vu que la fonction que j'utilise est courte mais doit être bloquante?


    si je comprends bien asynchronous c'est pour pouvoir continuer cotes client à faire des opérations en attendant la réponse du serveur, or moi je cherche à ce que le serveur bloque tant qu'un évènement n'a pas eu lieu (un commit sur une bd en fait).
    donc je dois faire une méthode dans laquelle je bloque en attendant qu'une autre méthode soit appelé par un autre client. je regarde asynchronous quand même, je suis peut être passé à cotes d'un truc.

    merci en tout cas pour ta réponse

  4. #4
    Membre Expert Avatar de fxrobin
    Homme Profil pro
    Formateur JAVA / XML
    Inscrit en
    novembre 2007
    Messages
    866
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Formateur JAVA / XML
    Secteur : Service public

    Informations forums :
    Inscription : novembre 2007
    Messages : 866
    Points : 1 188
    Points
    1 188

    Par défaut

    ah j'avais pas bien compris.

    Alors oui, un Singleton me parait pas mal.
    Bloquant en Lock Write par défaut.

    Ou alors les Interceptor ... à creuser.
    Je vais continuer d'y réfléchir.

    Tu peux me donner un cas d'utilisation pour que j'ai les même "entrées" que toi ?
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

  5. #5
    Membre Expert Avatar de fxrobin
    Homme Profil pro
    Formateur JAVA / XML
    Inscrit en
    novembre 2007
    Messages
    866
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Formateur JAVA / XML
    Secteur : Service public

    Informations forums :
    Inscription : novembre 2007
    Messages : 866
    Points : 1 188
    Points
    1 188

    Par défaut

    Regarde dans l'API Concurrency, y'a peut-être ce qu'il te faut.
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

  6. #6
    Candidat au titre de Membre du Club
    Inscrit en
    octobre 2008
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : octobre 2008
    Messages : 75
    Points : 13
    Points
    13

    Par défaut

    client A:
    fait appel à objetReponse methodeA();
    cette methode modifie des valeurs et attend la validation des changements => commit dans une bd. elle attend en retour les nouvelles valeurs contenu dans la bd apres changement.

    client B:
    fait appel à void methodeB();
    cette méthode valide les modification et lance le commit. Elle est aussi sensé débloquer le client A.


    le @lock ne m'a pas paru pertinent (d'ou mon post) vu qu'il ne permet que de limiter les accès à une ressource, dans mon cas le client B peut intervenir 2 minutes plus tard (asynchronous va donc me servir dans tous les cas), je n'ai donc pas d’accès concurrent.
    je vais regarder concurrency (et continuer asynchronous), merci pour ton aide

  7. #7
    Candidat au titre de Membre du Club
    Inscrit en
    octobre 2008
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : octobre 2008
    Messages : 75
    Points : 13
    Points
    13

    Par défaut

    je me suis finalement tourné vers jms...
    j'ai ecris une mini classe qui encapsule le peu d'utilisation que je veux en faire mais j'obtient une erreur à l'execution:
    Code :
    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
    Grave: MQJMSRA_DS4001: JMSServiceException on send message:sendMessage: Sending message failed. Connection ID: 2829732807136585216
    Grave: javax.jms.JMSException: MQJMSRA_DS4001: JMSServiceException on send message:sendMessage: Sending message failed. Connection ID: 2829732807136585216
    	at com.sun.messaging.jms.ra.DirectSession._sendMessage(DirectSession.java:1844)
    	at com.sun.messaging.jms.ra.DirectProducer._send(DirectProducer.java:1085)
    	at com.sun.messaging.jms.ra.DirectProducer.send(DirectProducer.java:453)
    	at utils.JmsUtils.send(JmsUtils.java:55)
    	at ejb.facade.FacadeUser.move(FacadeUser.java:122)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:601)
    	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
    	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
    	at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
    	at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
    	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
    	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
    	at sun.reflect.GeneratedMethodAccessor166.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:601)
    	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
    	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    	at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
    	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
    	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
    	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
    	at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
    	at $Proxy272.move(Unknown Source)
    	at ejb.facade.__EJB31_Generated__FacadeUser__Intf____Bean__.move(Unknown Source)
    	at ejb.SessionBean.move(SessionBean.java:174)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:601)
    	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
    	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
    	at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:4180)
    	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5368)
    	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
    	at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:206)
    	at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:79)
    	at $Proxy282.move(Unknown Source)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:601)
    	at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie.dispatchToMethod(ReflectiveTie.java:144)
    	at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:174)
    	at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:528)
    	at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:199)
    	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1624)
    	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1486)
    	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:990)
    	at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:214)
    	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:742)
    	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:539)
    	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2324)
    	at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
    	at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
    Caused by: com.sun.messaging.jmq.jmsservice.JMSServiceException: sendMessage: Sending message failed. Connection ID: 2829732807136585216
    	at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.sendMessage(IMQDirectService.java:1955)
    	at com.sun.messaging.jms.ra.DirectSession._sendMessage(DirectSession.java:1839)
    	... 58 more
    Caused by: com.sun.messaging.jmq.jmsserver.util.BrokerException: transaction failed: [B4391]: Received message 93-192.168.56.1(ac:d7:ca:77:9d:a1)-1-1352895533654 with unknown transaction id 2829732807146002944
    	at com.sun.messaging.jmq.jmsserver.data.handlers.DataHandler.routeMessage(DataHandler.java:467)
    	at com.sun.messaging.jmq.jmsserver.data.protocol.ProtocolImpl.processMessage(ProtocolImpl.java:941)
    	at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.sendMessage(IMQDirectService.java:1948)
    	... 59 more

    j'ai créé la factory ainsi que la queue dans glassfish et je l'obtient par lookup:

    Code :
    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
    public class JmsUtils {
        private static ConnectionFactory connectionFactory;
        private static Queue queue;
        
        private MessageProducer producer;
        private MessageConsumer consumer;
        private Session session;
        
        
        public JmsUtils(String id){
            try {
                Context ctx = new InitialContext();
                connectionFactory = (ConnectionFactory)ctx.lookup("jms/ConnectionFactory");
                queue = (Queue)ctx.lookup("jms/Queue");
                
                
                
                Connection connection = connectionFactory.createConnection(); 
                connection.start();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                producer = session.createProducer(queue);
                if(id != null)
                    consumer = session.createConsumer(queue, "client = " + id);
                else
                    consumer = session.createConsumer(queue);
                
            } catch (JMSException | NamingException ex) {
                Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        public void send(Serializable mess, String dest){
            try {
                ObjectMessage message = session.createObjectMessage(mess);
                message.setStringProperty("client", dest);
                producer.send(message);
                session.commit();
            } catch (JMSException ex) {
                Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        public Serializable receive(){
            try {
                
                ObjectMessage om = (ObjectMessage) consumer.receive();
                return om.getObject();
                
            } catch (JMSException ex) {
                Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
            return null;
        }
        
    }
    en rouge la ligne qui retourne l'erreur.

    je continue à chercher sur le net mais j'ai encore beaucoup de lacune en jms donc beaucoup de lecture à faire.

    ps: pour la logique du mon code, seul le serveur va envoyer des messages, il donne le client à qui il envoie le message lors du send.

  8. #8
    Candidat au titre de Membre du Club
    Inscrit en
    octobre 2008
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : octobre 2008
    Messages : 75
    Points : 13
    Points
    13

    Par défaut

    apres un peu de doc j'ai modifié ma classe jms comme suit:

    Code :
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package utils;
     
    import java.io.Serializable;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.annotation.Resource;
    import javax.jms.*;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
     
    /**
     *
     * @author jerome
     */
    public class JmsUtils {
        private static QueueConnectionFactory connectionFactory;
        private static Queue queue;
     
        private QueueSender producer;
        private QueueReceiver consumer;
        private QueueSession session;
        private QueueConnection connection;
     
        public JmsUtils(String id){
            try {
                Context ctx = new InitialContext();
                connectionFactory = (QueueConnectionFactory) ctx.lookup("jms/ConnectionFactory");
                queue = (Queue)ctx.lookup("jms/Queue");
     
     
     
                connection = connectionFactory.createQueueConnection();
                connection.start();
                session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
                producer = session.createSender(queue);
     
                if(id != null)
                    consumer = session.createReceiver(queue, "client = " + id);
                else
                    consumer = session.createReceiver(queue);
     
            } catch (JMSException | NamingException ex) {
                Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
     
        public void send(Serializable mess, String dest){
            try {
                System.out.println("jms.send> "+dest);
                ObjectMessage message = session.createObjectMessage(mess);
                message.setStringProperty("client", dest);
                producer.send(message);
            } catch (JMSException ex) {
                Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
     
        public Serializable receive(){
            try {
                System.out.println("jms.rcv> "+consumer.getMessageSelector());
                ObjectMessage om = (ObjectMessage) consumer.receive();
                return om.getObject();
     
            } catch (JMSException ex) {
                Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
            return null;
        }
     
    }
    je n'obtiens plus la moindre erreur mais mes clients ne reçoivent pas les messages, un problème sur le selector peut être? je vérifie ça mais si quelqu'un voit une erreur je suis open


    ah bah j'ai juste fais une pause café et en revenant ça tourne :/
    merci pour tes conseils fxrobin

  9. #9
    Membre Expert Avatar de fxrobin
    Homme Profil pro
    Formateur JAVA / XML
    Inscrit en
    novembre 2007
    Messages
    866
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Formateur JAVA / XML
    Secteur : Service public

    Informations forums :
    Inscription : novembre 2007
    Messages : 866
    Points : 1 188
    Points
    1 188

    Par défaut



    Joli.
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •