JMS - 在 WebSphere Application Server 7 上使用主题

JMS - Using Topics on WebSphere Application Server 7

我有特定主题的发送者和接收者。我是 运行 作为 WAS 7.0 上的 servlet 的发送者和接收者。 TopicTopic Connection Factory 正在 WAS 上设置。但是我无法收到发送的消息。当我尝试使用 Queue 而不是 Topic 时它工作正常。

下面是我使用的代码。

public class CommonServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;
    private static boolean initialized = false;
    private static InitialContext initialContext = null;
    private ConnectionFactory connectionFactory = null;
    private Destination destination = null;

    protected final void initialize(){
        try{
            if( initialized == false ){
                // Get JNDI initial context
                initialContext = new InitialContext();

                // Flag as initialized
                initialized = true;
            }
        }
        catch( Throwable t ){
            System.out.println( t.getMessage() );
        }
    }

    /**
     * @return
     */
    protected final Destination getDestination(){
        if( destination != null ){
            return destination;
        }

        try{
            destination = (Destination) initialContext.lookup("jms/TestTopic" );
        }
        catch( NamingException e ){
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return destination;
    }

    /**
     * @return
     */
    protected final ConnectionFactory getConnectionFactory(){
        try{
            connectionFactory = (ConnectionFactory) initialContext.lookup("jms/TestTopicCF" );
        }
        catch( NamingException e ){
            e.printStackTrace();
        }
        return connectionFactory;
    }
}

发件人 servlet class

public class Sender extends CommonServlet{

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException{
        System.out.println("inside do get of sender");
        doPost( req, resp );
    }

    @Override
    protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException{
        String message = req.getParameter( "message" );
        sendMessage( message );
    }

    private void sendMessage( String messageText ){
        initialize();
        try{
            ConnectionFactory factory = getConnectionFactory();

            Destination destination = getDestination();

            Connection connection = factory.createConnection();
            connection.start();

            Session session = connection.createSession( false, Session.AUTO_ACKNOWLEDGE );

            MessageProducer sender = session.createProducer( destination );

            TextMessage txtMsg = session.createTextMessage( messageText );

            sender.send( txtMsg );
        }
        catch( Exception ex ){
            ex.printStackTrace();
        }
    }
}

接收器 servlet class

public class Receiver extends CommonServlet{

    private static final long serialVersionUID = 1L;


    @Override
    protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException{
        doPost( req, resp );
    }

    @Override
    protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException{
        getMessage();
    }

    private void getMessage(){
        initialize();
        ConnectionFactory factory = getConnectionFactory();

        Destination destination = getDestination();

        try{
            Connection connection = factory.createConnection();

            connection.start();

            Session session = connection.createSession( false, Session.AUTO_ACKNOWLEDGE );

            MessageConsumer receiver = session.createConsumer( destination );

            Message message = receiver.receive( 4000 );

            System.out.println( message );//COMING AS NULL
        }
        catch( JMSException e ){
            e.printStackTrace();
        }

    }

}

TestTopicTestTopicCF 都在 Resources > JMS > Topic Connection FactoryTopics[= 下的 WAS 管理控制台中配置29=] 部分。 运行申请时无一例外。 如果我使用创建的队列和队列连接工厂,它工作正常。 有什么我需要专门做的事情才能使主题正常工作吗?

主题与队列的目的地不同,默认情况下它们不会持久化消息,并且当发布者发送消息时必须连接订阅者。查看一些细节here

Publishers and subscribers have a timing dependency. A client that subscribes to a topic can consume only messages published after the client has created a subscription, and the subscriber must continue to be active in order for it to consume messages.

简而言之:

  • 您当前的主题设计不正确,您必须首先调用接收方 servlet,接收超时很长,然后 window 尝试发送方 servlet,因为您现在的消息只是丢了。
  • 更好的方法是使用 MDB 作为消息接收器而不是 servlet
  • 如果您需要在订阅者处于非活动状态时接收发送到主题的消息,则需要在 WAS 中配置持久订阅者并将主题配置为持久。