【问题标题】:JMS - Using Topics on WebSphere Application Server 7JMS - 在 WebSphere Application Server 7 上使用主题
【发布时间】:2016-01-08 05:36:58
【问题描述】:

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

下面是我使用的代码。

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 类

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 类

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 均在 WAS 管理控制台中的 Resources > JMS > Topic Connection FactoryTopics 部分下进行配置。运行应用程序时没有例外。 如果我使用创建的队列和队列连接工厂,它工作正常。 我需要专门做些什么来使主题正常工作吗?

【问题讨论】:

    标签: websphere-7 jms-topic


    【解决方案1】:

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

    发布者和订阅者具有时间依赖性。一个客户 订阅一个主题只能消费之后发布的消息 客户端已创建订阅,订阅者必须继续 处于活动状态以便它使用消息。

    简而言之:

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

    【讨论】:

      最近更新 更多