-
1. Re: JMS and session scoped Seam component
asookazian Nov 7, 2009 12:04 AM (in response to lopsch)post your code for all relevant classes...
-
2. Re: JMS and session scoped Seam component
lvdberg Nov 7, 2009 12:12 AM (in response to lopsch)Hi Daniel,
Search this forum for JMS solutions, because we had different discussion about this subject. It's not very difficult as long as you configure evrything corect (SeamInterceptor and the JNDI-Name annotations or otherwise configured) At the moment Seam interacts with the MDB you can inject the Events comonent and send whatever event to the rest of your application.
I've included a simple example:
@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/events") }) @Name("SeamMDBEventListener") @JndiName("SeamMDBEventListener") public class EventMDB implements MessageListener { private Log log = LogFactory.getLog(EventMDB.class); @PersistenceContext EntityManager em; /** This is the event link to SEAM, whatever you receive will be notified. */ @In Events events; @Override public void onMessage(Message message) { String type; try { type = message.getStringProperty("eventType"); log.info("Received an event message: " + type); if (events != null) { events.raiseEvent(type); log.info("We will notify SEAM of an event."); } else log.error("Impossible to transmit something events is very NULL"); } catch (JMSException e) { log.error("Error while receiving an event"); } } }
I use it to relay specific events over JMS back the different sessions, because you can't send events across different user-session.
Leo
-
3. Re: JMS and session scoped Seam component
lvdberg Nov 7, 2009 12:16 AM (in response to lopsch)Hi,
saved to fast forgot some cleaning up.
Replace the Logger with an injected one @Logger and get rid of the entityManager. Furthermore you can add additional messagefiltering in the JMS configuration.
For instance:
@ActivationConfigProperty(propertyName="messageSelector",propertyValue="YourType = 'yourValue'"
-
4. Re: JMS and session scoped Seam component
lvdberg Nov 7, 2009 12:21 AM (in response to lopsch)Hi,
I looked it up.
This was the best thrad about the subject, thanks to Dan Allen !!
http://seamframework.org/Community/JMSMessageListenerInAWebApplication
Leo
-
5. Re: JMS and session scoped Seam component
lopsch Nov 7, 2009 12:39 AM (in response to lopsch)Thx for the replies,
mhm ok the SFSB is in session scope and instantiated when the user logs in (pretty normal) and observes an event. The MDB raised event instantiates a new SFSB instead of using the already existing one. I would to transport the message from the MDB to an already existing SFSB in session scope. Maybe i don't understand your hint :(.
-
6. Re: JMS and session scoped Seam component
kapitanpetko Nov 7, 2009 6:44 AM (in response to lopsch)
Daniel Lopes wrote on Nov 07, 2009 00:39:
mhm ok the SFSB is in session scope and instantiated when the user logs in (pretty normal) and observes an event. The MDB raised event instantiates a new SFSB instead of using the already existing one. I would to transport the message from the MDB to an already existing SFSB in session scope. Maybe i don't understand your hint :(.Your MDB does not have access to the Session, to there is no way to use your existing SFSB, that's why a new one gets created.
-
7. Re: JMS and session scoped Seam component
kapitanpetko Nov 7, 2009 6:47 AM (in response to lopsch)
Leo van den Berg wrote on Nov 07, 2009 00:12:
I use it to relay specific events over JMS back the different sessions, because you can't send events across different user-session.How exactly do you accomplish this? Do you mean all sessions receive the event if you send it from your MDB?
-
8. Re: JMS and session scoped Seam component
lopsch Nov 7, 2009 12:46 PM (in response to lopsch)
Nikolay Elenkov wrote on Nov 07, 2009 06:47:
Leo van den Berg wrote on Nov 07, 2009 00:12:
I use it to relay specific events over JMS back the different sessions, because you can't send events across different user-session.
How exactly do you accomplish this? Do you mean all sessions receive the event if you send it from your MDB?That's what I would like to know to, as it would solve my problem ;).
-
9. Re: JMS and session scoped Seam component
lvdberg Nov 7, 2009 7:46 PM (in response to lopsch)Hi,
You can't send events between sessions, but you can receive it in a application-scoped bean whic relays it further.
Another option I used (look in previous threads) is to wait for messages in a speciic session bean (make it a listener). Its a bit difficult with a POJO because you need to make direct calls to JMS to receive messages, but it can be done.
There is also the JMS client receiver as a sort of web remote functionality, but i don't use it because of the restrictions of JavaScript and the need to capture whatever happens within the client because the client will hang if not failure proof.
I personally prefer the JMS-listener per session.
Leo
-
10. Re: JMS and session scoped Seam component
kapitanpetko Nov 9, 2009 3:43 AM (in response to lopsch)
Leo van den Berg wrote on Nov 07, 2009 19:46:
You can't send events between sessions, but you can receive it in a application-scoped bean whic relays it further.So your app-scoped bean has a list of sessions then? Do you switch sessions to send an event? Or you use some other notification mechanism?
Another option I used (look in previous threads) is to wait for messages in a speciic session bean (make it a listener). Its a bit difficult with a POJO because you need to make direct calls to JMS to receive messages, but it can be done.I tried searching, but couldn't find it (forum search could use a few improvements...). Do you mean registering it as a listener by using MessageConsumer.setMessageListener? I tried something similar a while back, but JMS failover (in JBoss 4.2) didn't work. Could you show some code?
-
11. Re: JMS and session scoped Seam component
kapitanpetko Nov 9, 2009 9:07 AM (in response to lopsch)So I've been playing with the idea of inter-session events, and here's what I've come up with. Quite hackish, but it works. If Seam gave you easy access to the actual HttpSession, could be implemented with ServletLifecycle.beginSession() instead of the reflection hack.
The idea is:
- create a session-scoped JMS listener, subscribe to a topic
- in the @Create method save a reference to the session Context (this works because @Create is called when the first HTTP request is made)
- to send an event to all sessions, send a JMS message to the topic
- in the onMessage method, replace the empty session context created by Lifecycle.beginCall() with the one saved in 2.
- raise the event
- replace the session Context with the original one to avoid self-destruction :)
Something like:
@Name("sessionListener") @Scope(ScopeType.SESSION) @AutoCreate @Startup public class SessionListener implements MessageListener, HttpSessionListener { @Logger private Log log; //.... private Context sessionContext; private Context oldSessionContext; @Create public void create() throws JMSException, NamingException { log.info("SessionListener created"); sessionContext = Contexts.getSessionContext(); connectionFactory = lookupConnectionFactory(); connection = connectionFactory.createConnection(); session = createSession(connection); destination = lookupDestination(); createConsumer(); connection.start(); log.debug("started connection"); } public void onMessage(Message msg) { try { TextMessage txtMsg = (TextMessage) msg; Field sessionCtx = Reflections.getField( org.jboss.seam.contexts.Contexts.class, "sessionContext"); sessionCtx.setAccessible(true); ThreadLocal<Context> sessionContextTl = (ThreadLocal<Context>) Reflections .getAndWrap(sessionCtx, null); try { Lifecycle.beginCall(); oldSessionContext = sessionContextTl.get(); sessionContextTl.set(sessionContext); log.info("SessionListener " + this); String txt = txtMsg.getText(); Events.instance().raiseEvent("foo", txt); } finally { sessionContextTl.set(oldSessionContext); Lifecycle.endCall(); } } catch (JMSException e) { throw new RuntimeException(e); } } }
Any better ideas?
-
12. Re: JMS and session scoped Seam component
lopsch Nov 9, 2009 12:20 PM (in response to lopsch)I had a similar idea.
Instead of sending messages to a queue I will use a topic. Per session then there will be a component that subscribes to the topic and periodically checks for updates. Checking would be triggered through remoting and the help of the periodicalexecuter of the prototype library. -
13. Re: JMS and session scoped Seam component
lvdberg Nov 10, 2009 9:23 AM (in response to lopsch)Hi,
this is the original thread I mentioned:
http://seamframework.org/Community/JMSMessageListenerInAWebApplication#comment80113
Leo
-
14. Re: JMS and session scoped Seam component
kapitanpetko Nov 10, 2009 10:14 AM (in response to lopsch)
Leo van den Berg wrote on Nov 10, 2009 09:23:
this is the original thread I mentioned:http://seamframework.org/Community/JMSMessageListenerInAWebApplication#comment80113
Thanks. That one has a repeating job that polls for JMS messages. I was more interested in how you implemented the 'relay specific events over JMS back the different sessions' part. Could you shed a bit more light about this?