Jboss client send message to remote hornetq in Jboss

此生再无相见时 提交于 2019-12-23 01:13:02

问题


I have a client run in JBoss (JB_Client) and it needs to send messages to a remote Jboss server (JB_Server) HornetQ. And Remote jboss server (JB_server) needs to send the response message back to it's HornetQ. So JB_Client MDB is listening to remote HorentQ for the responses.

I am using Jboss AS6 for my client and server. This system works perfectly in local environment which is client and server both in same Jboss. But now I need to separate client and server in to two machines.

here is my test client configuration.

        Properties prop = new Properties();
        prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
        prop.put(Context.PROVIDER_URL, "jnp://localhost:1099");

        ictx = new InitialContext(prop);
        conFactory = (ConnectionFactory)ictx.lookup("/ConnectionFactory");
        qcon  = (QueueConnection)conFactory.createConnection();
        qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

Server does not have special settings except queues defined.

What configuration I need to do in server and client side to make this work?


回答1:


I was able to connect to remote server and get the response from the remote queue. Both my client and server running in two separate computers, JBossAS [6.1.0.Final "Neo"]. My client is a simple web app ( a war file)

Client side queue sender class.

private static void prepareContext() {
        logger.debug("Loading Context");
        try {
        Properties prop = new Properties();
        prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
        prop.put(Context.PROVIDER_URL, "jnp://10.1.4.48:1099");
        ictx = new InitialContext(prop);
        conFactory = (ConnectionFactory)ictx.lookup("/ConnectionFactory");
        qcon  = (QueueConnection)conFactory.createConnection();
        qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        }
        catch (NamingException er) {
          logger.fatal("Error ", er);
        }
        catch (JMSException er) {
            logger.fatal("Error ", er);
        }
    }



public static boolean sendToQueue(String xml, String sendQ) {
        logger.warn("Sending to queue: " + xml);
        try {
            prepareContext();
            Queue queue =  getQueue(sendQ);
            if (null == queue) {
                throw new JMSException("Queue not defined at the end point");
            }
            qcon.start();
            QueueSender qsender = qsession.createSender(queue);
            TextMessage tmsg = qsession.createTextMessage();
            tmsg.setText(xml);
            qsender.send(tmsg);
            return true;
        }
        catch (JMSException er) {
            logger.fatal("Error ", er);
        }
        finally {
           try { qsession.close(); } catch (Exception er) {/**/}
            try { qcon.close(); } catch (Exception er) {/**/}
        }
        return false;
    }

Above is client side sender code.

Now let's see how client side message receiver. I used MDB to listen remote server queue.

public class MessageReceiverBean implements MessageListener {

public void onMessage(Message message) {
          try {
            if (message instanceof TextMessage) {
                TextMessage textMsg = (TextMessage) message;
                logger.info("Inside onMessage of client app MessageReceiverBean : " + textMsg.getText());
     }
  }
          catch (Exception er) {
            logger.error("Error while retrieving message from Service provider", er);
        }
}
}

MDB configuration is in ejb-jar.xml in the META-INF folder of my war file.

<message-driven>
  <ejb-name>User1</ejb-name>
  <ejb-class>com.my.MessageReceiverBean</ejb-class>
  <messaging-type>javax.jms.MessageListener</messaging-type>
  <transaction-type>Container</transaction-type>
  <activation-config>
  <activation-config-property>
  <activation-config-property-name>destinationType</activation-config-property-name>
  <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
  </activation-config-property>
  <activation-config-property>
  <activation-config-property-name>destination</activation-config-property-name>
  <activation-config-property-value>queue/User4</activation-config-property-value>
  </activation-config-property>
  <activation-config-property>
  <activation-config-property-name>ConnectorClassName</activation-config-property-name>
  <activation-config-property-value>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</activation-config-property-value>
  </activation-config-property>
  <activation-config-property>
  <activation-config-property-name>ConnectionParameters</activation-config-property-name>
  <activation-config-property-value>host=10.1.4.48;port=5445</activation-config-property-value>
  </activation-config-property>
  </activation-config>
</message-driven>

Above last two activation-config-properties is additionally added to connect to the remote server. So client java coding is over now.

Bonus !!!. Above is just call it through JNDI in a simple java class. But you might interest to do it through EJB CDI injection without using context properties etc. For that you need to modify below settings in client jboss side.

There are two settings I changed in the client Jboss node.

  1. hornetq-configuration.xml in client Jboss node.

<connector name="netty"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="${MY_IP:10.1.4.48}"/> <!-- For MY_IP you can put any word. Doesn't matter. --> <param key="port" value="${hornetq.remoting.netty.port:5445}"/> </connector>

  1. ra.xml file in jms-ra.rar (deploy folder) in client Jboss node. Comment the below settings like this.

    <!--<config-property> <description>The transport configuration. These values must be in the form of key=val;key=val;, if multiple connectors are used then each set must be separated by a comma i.e. host=host1;port=5445,host=host2;port=5446. Each set of params maps to the connector classname specified. </description> <config-property-name>ConnectionParameters</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>server-id=0</config-property-value> </config-property>-->

Ok. Jboss settings are over. Now let's see EJB bean. We need to inject the above connection through annotation.

@Resource(mappedName = "/ConnectionFactory")
private QueueConnectionFactory qConnectionFactory;

If you check your hornetq-jms.xml you can see under <connection-factory name="NettyConnectionFactory"> above mappedName is defined ( <entry name="/ConnectionFactory"/> ). This is the JNDI name you should look in your EJB, to find the connectionFactory in the remote HornetQ server. That's it if you need to use EJB CDI injection rather than JNDI lookup.

Restart the client jboss then you should be able to send the messages from client to Server. (No special settings in starting the jboss)

You can verify where is it connecting, if you go to jmx-console of the client and go to org.hornetq then click on module=JMS,name="NettyConnectionFactory",type=ConnectionFactory. In StaticConnectors you see where this NettyConnector is connecting.

Now server side Jboss HornetQ settings.

Edit the hornetq-configuration.xml in Server Jboss and change the section.

<acceptor name="netty">
         <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
         <param key="host"  value="${jboss.esb.bind.address:10.1.4.48}"/> <!-- Here I add the server IP and esb. May be you can remove the esb and use "jboss.bind.address:10.1.4.48" -->
         <param key="port"  value="${hornetq.remoting.netty.port:5445}"/>
      </acceptor>

So this is server Jboss settings. And I start the server with run.bat -b 10.1.4.48 option.

Hope this helps.



来源:https://stackoverflow.com/questions/25397138/jboss-client-send-message-to-remote-hornetq-in-jboss

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!