JMS - 在 WebSphere Application Server 7 上使用主题
JMS - Using Topics on WebSphere Application Server 7
我有特定主题的发送者和接收者。我是 运行 作为 WAS 7.0 上的 servlet 的发送者和接收者。
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;
}
}
发件人 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();
}
}
}
TestTopic
和 TestTopicCF
都在 Resources > JMS > Topic Connection Factory 和 Topics[= 下的 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 中配置持久订阅者并将主题配置为持久。
我有特定主题的发送者和接收者。我是 运行 作为 WAS 7.0 上的 servlet 的发送者和接收者。
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;
}
}
发件人 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();
}
}
}
TestTopic
和 TestTopicCF
都在 Resources > JMS > Topic Connection Factory 和 Topics[= 下的 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 中配置持久订阅者并将主题配置为持久。