[SOLVED] Push between multiple webapps?

UI Components for JSF
smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

19 May 2014, 15:29

FkJ wrote:Got it working with JMS: ActiveMQ + a simple web listener to read messages from the topic.
Can you share code?
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

FkJ
Posts: 183
Joined: 08 Jan 2010, 19:16

19 May 2014, 15:56

Code: Select all

import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.naming.InitialContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.primefaces.push.PushContext;
import org.primefaces.push.PushContextFactory;

@WebListener
public class JmsMessageListener implements ServletContextListener
{
	private TopicConnection connection;
	private TopicSession    session;
	private TopicSubscriber subscriber;

	@Override
	public void contextInitialized(ServletContextEvent sce)
	{
		try
		{
			InitialContext initCtx = new InitialContext();
			TopicConnectionFactory connectionFactory = (TopicConnectionFactory) initCtx.lookup("java:comp/env/jms/ConnectionFactory");
			connection = connectionFactory.createTopicConnection();
			session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
			Topic topic = (Topic) initCtx.lookup("java:comp/env/jms/AtmosphereTopic");
			subscriber = session.createSubscriber(topic);
			subscriber.setMessageListener(new MessageListener()
			{
				@Override
				public void onMessage(Message message)
				{
					try
					{
						ObjectMessage objectMessage = (ObjectMessage) message;
						PushMessage pushMessage = (PushMessage) objectMessage.getObject();
						
						PushContext pushContext = PushContextFactory.getDefault().getPushContext();
						pushContext.push(pushMessage.getChannel(), pushMessage.getData());
					}
					catch(JMSException e)
					{
						throw new RuntimeException(e);
					}
				}
			});
			connection.start();
		}
		catch(Exception e)
		{
			throw new RuntimeException(e);
		}
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce)
	{
		try
		{
			if(subscriber != null)
			{
				subscriber.close();
			}

			if(session != null)
			{
				session.close();
			}

			if(connection != null)
			{
				connection.close();
			}
		}
		catch(Exception e)
		{
			throw new RuntimeException(e);
		}
	}
}
I didn't wrote the final version of the message publisher yet, I'm waiting to see if I'm going to use the Atmosphere JMSBroadcaster or not to continue the implementation. PushMesage is a serializable java bean with the properties String channel and Object data.

I configured ActiveMQ in the Tomcat context.xml file.

Code: Select all

	<Resource
		auth="Container"
		name="jms/ConnectionFactory"
		type="org.apache.activemq.ActiveMQConnectionFactory"
		description="JMS Connection Factory"
		factory="org.apache.activemq.jndi.JNDIReferenceFactory"
		brokerURL="tcp://localhost:61616?daemon=true"
		useEmbeddedBroker="false"
		brokerName="localhost" 
        />

	<Resource
		auth="Container"
		name="jms/AtmosphereTopic"
		type="org.apache.activemq.command.ActiveMQTopic"
		description="JMS Topic"
		factory="org.apache.activemq.jndi.JNDIReferenceFactory"
		physicalName="ATMOSPHERE.TOPIC" 
        />
Tomcat was hanging on shutdown, adding daemon=true solved it.

pom.xml

Code: Select all

		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-client</artifactId>
			<version>5.9.1</version>
		</dependency>

		<dependency>
			<groupId>javax.jms</groupId>
			<artifactId>jms</artifactId>
			<version>1.1</version>
		</dependency>

		<dependency>
			<groupId>javax.management.j2ee</groupId>
			<artifactId>javax.management.j2ee-api</artifactId>
			<version>1.1.1</version>
		</dependency>

smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

19 May 2014, 17:13

Very good. Thanks. :-)
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

marc.bouvier.agipi
Posts: 4
Joined: 25 May 2016, 17:03

18 Oct 2016, 16:17

Here is how I did it.

I actually used Spring to instanciate Jms Topic...

Code: Select all

    <!-- Connection to Tibco EMS -->
    <bean id="tibjmsConnectionFactory" class="com.tibco.tibjms.TibjmsConnectionFactory">
        <property name="serverUrl" value="${instance.jms.server}" />
        <property name="userName" value="${instance.jms.login}"/>
        <property name="userPassword" value="${instance.jms.password}"/>
    </bean>
    
    <bean id="jmsTemplateEms" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="tibjmsConnectionFactory" />
        <property name="explicitQosEnabled" value="true" />
        <property name="deliveryMode" value="2" />
        <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" />
        <property name="sessionTransacted" value="false" />
        <property name="receiveTimeout" value="${instance.wait.timeout}" />
    </bean>
    
    <bean id="pushJmsMessageListener" class="com.agipi.g2a.tiana.web.utils.PushJmsMessageListener" />
    
    <bean id="atmosphereTopic" class="com.tibco.tibjms.TibjmsTopic">
        <!-- nom du topic-->
        <constructor-arg index="0" value="${instance.jms.atmosphere.topic.name}" />
    </bean>
    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="tibjmsConnectionFactory"/>
        <property name="destination" ref="atmosphereTopic"/>
        <property name="messageListener" ref="pushJmsMessageListener" />
    </bean>
... and created a MessageListener which listen to atmosphere topic and publish received message to Push event bus ...

Code: Select all

    class PushJmsMessageListener implements MessageListener {
        private static final Logger LOGGER = LoggerFactory.getLogger(PushJmsMessageListener.class);
    
        private static final String PROPERTY_PUSH_CHANNEL = "pushChannel";
    
        @Override
        public void onMessage(Message message) {
    
            try {
                EventBus eventBus = EventBusFactory.getDefault().eventBus();
                TextMessage testMessage = (TextMessage) message;
                LOGGER.info("Reception d'un message du topic atmosphere : {}", testMessage);
    
                String canal = testMessage.getStringProperty(PROPERTY_PUSH_CHANNEL);
                Object decodedObject = new JSONDecoder().decode(testMessage.getText());
                LOGGER.info("Envoi du message sur le endpoint push [canal={},objet={}]", canal, decodedObject);
                eventBus.publish(canal, decodedObject);
            } catch (JMSException e) {
                LOGGER.error("error.receiving.jms.message", e);
    
            }
        }
    }
... and created a Spring service to publish my message to the topic instead of push ...

Code: Select all

    @Service
    @Scope(value = "singleton")
    public class JmsAtmosphereServiceImpl implements JmsAtmosphereService {
    
        @Autowired
        @Qualifier("jmsTemplateEms")
        private JmsTemplate jmsTemplate;
    
        @Autowired
        @Qualifier("atmosphereTopic")
        private Topic atmosphereTopic;
    
    
        @Override
        public void sendMessage(String pushChannel, String jsonContent) {
            jmsTemplate.send(atmosphereTopic, session -> {
                TextMessage textMessage = session.createTextMessage(jsonContent);
                textMessage.setStringProperty("pushChannel", pushChannel);
                return textMessage;
            });
    
        }
    
    }

... some utility to abstract ...

Code: Select all

    @Service
    public class PushJmsUtils {
    
        private static final String PUSH_DEFAULT_CHANNEL = "atmosphere";
    
        @Autowired
        private JmsAtmosphereService jmsAtmosphereService;
    
        /**
         * Propagate message JMS as JSON to JMS Atmosphere topic.
         *
         * @param channel push channel
         * @param message object to send via push
         */
        public void propagateMessage(String channel, Object message) {
            String id = channel;
            if (id.startsWith("/*")) {
                id = PUSH_DEFAULT_CHANNEL;
            }
            jmsAtmosphereService.sendMessage(id, new JSONEncoder().encode(message));
        }
    
    }
.. and then, I publish my message to several instances of my application listening to the same atmosphere topic (including the application sending the message).

Code: Select all

     pushJmsUtils.propagateMessage(canal,pushMessage);

soekris
Posts: 76
Joined: 29 Apr 2013, 16:54
Location: Barcelona

19 Oct 2016, 10:36

Thanks to post one solution
Primefaces 5.3.X / 6.X
NetBeans 8.1
WildFly 10
Linux Mint & freeBSD

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 27 guests