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"> "Фабрика соединений тем и разделы ". Нет никаких исключений при запуске приложения. Он работает нормально, если я использую созданную фабрику очередей и соединений с очередями. Есть ли что-то, что мне нужно сделать специально, чтобы тема работала?
1 ответ
Темы являются адресатами, отличными от очередей, по умолчанию они не сохраняются в сообщениях, и подписчик должен быть подключен, когда издатель отправляет сообщение. Смотрите некоторые детали здесь
Издатели и подписчики имеют временную зависимость. Клиент, подписывающийся на тему, может использовать только сообщения, опубликованные после того, как клиент создал подписку, и подписчик должен оставаться активным, чтобы он мог принимать сообщения.
Итак, вкратце:
- Ваш текущий дизайн не подходит для тем, вам придется сначала вызвать сервлет получателя, там очень большой тайм-аут приема, а во втором окне попробовать сервлет отправителя, так как ваше сообщение сейчас просто потеряно.
- гораздо лучше было бы использовать MDB в качестве приемника сообщений вместо сервлета
- если вам нужно получать сообщения, отправляемые в тему, пока подписчик неактивен, вам необходимо настроить надежного подписчика и настроить тему для обеспечения ее устойчивости в WAS.