JMS — Использование тем в WebSphere Application Server 7

У меня есть отправитель и получатель для определенной темы. Я запускаю отправителя и получателя как сервлеты на WAS 7.0. Topic и Topic 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;
    }
}

Класс сервлета отправителя

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();
        }
    }
}

Класс сервлета получателя

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();
        }

    }

}

И TestTopic, и TestTopicCF настраиваются в консоли администрирования WAS в разделе Ресурсы > JMS > Фабрика подключений тем и Темы. Никаких исключений при работе приложения нет. Он отлично работает, если я использую созданную фабрику Queue и Queue Connection. Есть ли что-то, что мне нужно сделать специально, чтобы тема заработала?


person Apps    schedule 10.10.2015    source источник


Ответы (1)


Темы - это разные адресаты, чем очереди, по умолчанию они не сохраняют сообщения, и подписчик должен быть подключен, когда издатель отправляет сообщение. Подробнее см. здесь

Издатели и подписчики имеют временную зависимость. Клиент, который подписывается на тему, может потреблять только сообщения, опубликованные после того, как клиент создал подписку, и подписчик должен оставаться активным, чтобы он мог потреблять сообщения.

Итак, вкратце:

  • ваш текущий дизайн не подходит для тем, вам нужно сначала вызвать сервлет-получатель, иметь очень длинный тайм-аут приема, а во втором окне попробовать сервлет-отправитель, так как ваше сообщение сейчас просто потеряно.
  • гораздо лучшим подходом было бы использование MDB в качестве получателя сообщений вместо сервлета.
  • если вам нужно получать сообщения, отправляемые в тему, когда подписчик неактивен, вам нужно будет настроить устойчивую подписку и настроить устойчивую тему в WAS.
person Gas    schedule 12.10.2015