Hello Worldの例

Hello Worldアプリケーションは、「Hello Wold」メッセージをトピックにパブリッシュするパブリッシャアプリケーションで構成されます。このメッセージは、メッセージがパブリッシュされたトピックに接続しているすべてのトピックサブスクライバにより受信されます。つまり、メッセージは、すべてのリスナにブロードキャストされます。

このアプリケーションには、次の3つのサンプルプログラムがあります。

トピックパブリッシャ

同期トピックサブスクライバ

非同期トピックサブスクライバ

P2Pの例と同じように、ここで示すソースコードでは例外を処理しません。この結果、サンプルコードは読みやすくなりますが、アプリケーションプログラマの方は、JMSプロバイダに障害が発生した場合、JMS APIのほとんどすべてのメソッドで、JMSExceptionが発生する可能性があることに注意してください。

1 トピックパブリッシャ

トピックパブリッシャは、次に示す通常の手順を実行して初期化してから、メッセージを送信する必要があります。
  1. JMSサーバのInitialContextオブジェクトを取得します。
  2. コンテキストオブジェクトを使用して、特定のトピック(この場合「topic0」)を参照します。
  3. コンテキストオブジェクトを使用して、トピック接続ファクトリを参照します。ルックアップで「topic/connectionFactory」を指定することのみが必要となります。これは、このサンプルの実行元であるバッチファイルにより、システム名前空間の該当するルートコンテキストを参照するようにシステムプロパティが設定されているためです。 Novell eXtend Application ServerでJMSサーバを使用している場合、ルックアップを次のように指定する必要があります。
    	TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx.
    lookup("iiop://localhost:3506/topic/connectionFactory");
    	
  4. TopicConnectionFactoryを使用して、TopicConnectionを作成します。このTopicConnectionは、JMSサーバとの物理的な接続を示します。
  5. トピックセッションを作成します。createTopicSessionメソッドの最初のパラメータは、セッションが処理されるかどうかを決めます。ここでは、処理されないセッションを使用します。2番目のパラメータは、配信モードを決めます。これは、送信側アプリケーションでは使用されません。
  6. topic0のトピックパブリッシャを作成し、メッセージを作成します。
  7. 「Hello World」メッセージをtopic0にパブリッシュします。
  8. 最後に、トピック接続を閉じます。これにより、セッションとTopicPublisherの両方が閉じます。
Publisherクラスのソースコードは、次のとおりです。
package pubSub;
                                                                           
import javax.naming.InitialContext;
                                                                           
import javax.jms.Topic;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicPublisher;
import javax.jms.DeliveryMode;
import javax.jms.TopicSession;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
                                                                           
public class Publisher
{
    public static void main(String[] args) throws Exception
    {
    |   // get the initial context
    |   InitialContext ctx = new InitialContext();
    |                                                                      
    |   // lookup the topic object
    |   Topic topic = (Topic) ctx.lookup("topic/topic0");
    |                                                                      
    |   // lookup the topic connection factory
    |   TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx.
    |       lookup("topic/connectionFactory");
    |                                                                      
    |   // create a topic connection
    |   TopicConnection topicConn = connFactory.createTopicConnection();
    |                                                                      
    |   // create a topic session
    |   TopicSession topicSession = topicConn.createTopicSession(false,
    |       Session.AUTO_ACKNOWLEDGE);
    |                                                                      
    |   // create a topic publisher
    |   TopicPublisher topicPublisher = topicSession.createPublisher(topic);
    |   topicPublisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    |                                                                      
    |   // create the "Hello World" message
    |   TextMessage message = topicSession.createTextMessage();
    |   message.setText("Hello World");
    |                                                                      
    |   // publish the messages
    |   topicPublisher.publish(message);
    |                                                                      
    |   // print what we did
    |   System.out.println("published: " + message.getText());
    |                                                                      
    |   // close the topic connection
    |   topicConn.close();
    }
}
メッセージは、PERSISTENTに設定されたデフォルトの配信モードで送信されますが、JMSサーバは、トピックに永続的サブスクライバがある場合にのみ、トピックメッセージを保持します。pub/subメッセージングでは、サーバまたはサブスクライバがクラッシュした場合、一時サブスクライバは失われるため、持続メッセージは、永続的サブスクライバがある場合にのみ適切です。

2 同期トピックサブスクライバ

P2P Helloの例で説明されているように、同期受信者は、receiveメソッドのいずれかを使用して、明示的にメッセージを受信する必要があります。受信メソッドは、接続が開始され、メッセージがトピックで使用できるようになるまで、ブロックされます。

トピックサブスクライバは、前に説明したトピックパブリッシャと同じ初期手順を実行して、セッションを取得します。次に、トピック受信者を作成して、接続を開始します。最後に、メッセージは、トピックから使用され、その後接続が閉じられます。

package pubSub;
                                                                           
import javax.naming.InitialContext;
                                                                           
import javax.jms.Topic;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
                                                                           
public class Subscriber
{
    public static void main(String[] args) throws Exception
    {
    |   // get the initial context
    |   InitialContext ctx = new InitialContext();
    |                                                                      
    |   // lookup the topic object
    |   Topic topic = (Topic) ctx.lookup("topic/topic0");
    |                                                                      
    |   // lookup the topic connection factory
    |   TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx.
    |       lookup("topic/connectionFactory");
    |                                                                      
    |   // create a topic connection
    |   TopicConnection topicConn = connFactory.createTopicConnection();
    |                                                                      
    |   // create a topic session
    |   TopicSession topicSession = topicConn.createTopicSession(false,
    |       Session.AUTO_ACKNOWLEDGE);
    |                                                                      
    |   // create a topic subscriber
    |   TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
    |                                                                      
    |   // start the connection
    |   topicConn.start();
    |                                                                      
    |   // receive the message
    |   TextMessage message = (TextMessage) topicSubscriber.receive();
    |                                                                      
    |   // print the message
    |   System.out.println("received: " + message.getText());
    |                                                                      
    |   // close the topic connection
    |   topicConn.close();
    }
}
パブリッシャアプリケーションを実行した後でサブスクライバアプリケーションを実行すると、サブスクライバは、メッセージを受信できないので注意してください。これは、トピックサブスクライバは、サブスクライブの実行後にトピックに送信されたメッセージのみを受信するからです。

3 非同期トピックサブスクライバ

非同期トピックサブスクライバは、非同期キュー受信者と非常に似ています。非同期トピックサブスクライバは、メッセージがサブスクライブされるトピックに送信された際に、JMSプロバイダにより自動的および非同期に呼び出されるメッセージリスナを登録します。

また、前に説明したとおり、非同期メッセージリスナは、例外リスナを接続に登録します。これは、JMSでのメッセージの処理中に例外が発生した場合、通知を受け取るためです。この例の例外リスナは、例外を出力するだけです。

package pubSub;
                                                                           
import javax.naming.InitialContext;
                                                                           
import javax.jms.Topic;
import javax.jms.Session;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.MessageListener;
import javax.jms.JMSException;
import javax.jms.ExceptionListener;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
                                                                           
public class AsyncSubscriber implements MessageListener, ExceptionListener
{
    public static void main(String[] args) throws Exception
    {
    |   // get the initial context
    |   InitialContext ctx = new InitialContext();
    |                                                                      
    |   // lookup the topic object
    |   Topic topic = (Topic) ctx.lookup("topic/topic0");
    |                                                                      
    |   // lookup the topic connection factory
    |   TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx.
    |       lookup("topic/connectionFactory");
    |                                                                      
    |   // create a topic connection
    |   TopicConnection topicConn = connFactory.createTopicConnection();
    |                                                                      
    |   // create a topic session
    |   TopicSession topicSession = topicConn.createTopicSession(false,
    |       Session.AUTO_ACKNOWLEDGE);
    |                                                                      
    |   // create a topic subscriber
    |   TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
    |                                                                      
    |   // set an asynchronous message listener
    |   AsyncSubscriber asyncSubscriber = new AsyncSubscriber();
    |   topicSubscriber.setMessageListener(asyncSubscriber);
    |                                                                      
    |   // set an asynchronous exception listener on the connection
    |   topicConn.setExceptionListener(asyncSubscriber);
    |                                                                      
    |   // start the connection
    |   topicConn.start();
    |                                                                      
    |   // wait for messages
    |   System.out.print("waiting for messages");
    |   for (int i=0; i < 10; i++) {
    |   |   Thread.sleep(1000);
    |   |   System.out.print(".");
    |   }
    |   System.out.println();
    |                                                                      
    |   // close the topic connection
    |   topicConn.close();
    }
                                                                           
    /**
       This method is called asynchronously by JMS when a message arrives
       at the topic.Client applications must not throw any exceptions in
       the onMessage method.
       @param message A JMS message.
     */
    public void onMessage(Message message)
    {
    |   TextMessage msg = (TextMessage) message;
    |   try {
    |   |   System.out.println("received: " + msg.getText());
    |   } catch (JMSException ex) {
    |   |   ex.printStackTrace();
    |   }
    }
                                                                           
    /**
       This method is called asynchronously by JMS when some error occurs.
       When using an asynchronous message listener it is recommended to use
       an exception listener also since JMS have no way to report errors
       otherwise.
       @param exception A JMS exception.
     */
    public void onException(JMSException exception)
    {
    |   System.err.println("something bad happended:" + exception);
    }
}
この例では、自動確認を使用しています。つまり、JMSは、onMessageが正常に返された直後にメッセージを自動的に確認します。 サブスクライバが、CLIENT_ACKNOWLEDGEを使用する場合、onMessageメソッド中にメッセージを手動で確認する必要があります。

onMessageがCLIENT_ACKNOWLEDGEで呼び出されるたびに、メッセージを確認する必要はありませんが、多くの未確認メッセージがクライアントに残らないように、アプリケーションで、できるだけ迅速にメッセージを確認することをお勧めします。

トップに戻る


Copyright © 2000-2003, Novell, Inc.All rights reserved.