8.5. サーバーへの接続
クライアントをサーバーに接続する場合は、適切なコネクターが必要です。これには 2 つの方法があります。サーバーに設定され、JNDI ルックアップから取得できる ConnectionFactory を使用することができます。または、ActiveMQ Artemis コア API を使用して、クライアント側で ConnectionFactory
全体を設定することもできます。
8.5.1. JMS 接続ファクトリー
クライアントでは JNDI を使用して、サーバーへの接続を提供する ConnectionFactory オブジェクトをルックアップできます。接続ファクトリーでは、それぞれ以下の 3 つのタイプのコネクターを公開することができます。
remote-connector
を参照する connection-factory
は、リモートクライアントがサーバーからメッセージを送受信するために使用できます (connection-factory に適切なエクスポートエントリーがあることを前提とします)。remote-connector
は、connection-factory
の使用して接続先をクライアントに指示する socket-binding
と関連付けられます。
in-vm-connector
を参照する connection-factory
は、ローカルクライアントよるローカルサーバーとのメッセージの送受信にに適しています。in-vm-connector
は、複数のメッセージングサーバーを 1 つの JVM で実行できるため、connection-factory
を使用して接続先をクライアントに指示する server-id
と関連付けられます。
http-connector
を参照する connection-factory
は、HTTP ポートに接続してサーバーからメッセージを送受信してからメッセージングプロトコルにアップグレードするにあたり、リモートクライアントで使用するのに適しています。http-connector
は、デフォルトで http
という名前の HTTP ソケットを表す socket-binding
に関連付けられています。
JMS 2.0 以降、デフォルトの JMS 接続ファクトリーは、JNDI 名 java:comp/DefaultJMSConnectionFactory
で Java EE アプリケーションを利用できます。messaging-activemq
サブシステムでは、このデフォルトの接続ファクトリーを提供するために使用される pooled-connection-factory
を定義します。
以下は、JBoss EAP の full
設定プロファイルに含まれるデフォルトのコネクターおよび接続ファクトリーです。
<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0"> <server name="default"> [...] <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor" /> <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput"> <param name="batch-delay" value="50"/> </http-connector> <in-vm-connector name="in-vm" server-id="0"/> [...] <connection-factory name="InVmConnectionFactory" connectors="in-vm" entries="java:/ConnectionFactory" /> <pooled-connection-factory name="activemq-ra" transaction="xa" connectors="in-vm" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory"/> [...] </server> </subsystem>
<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
<server name="default">
[...]
<http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor" />
<http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
<param name="batch-delay" value="50"/>
</http-connector>
<in-vm-connector name="in-vm" server-id="0"/>
[...]
<connection-factory name="InVmConnectionFactory" connectors="in-vm" entries="java:/ConnectionFactory" />
<pooled-connection-factory name="activemq-ra" transaction="xa" connectors="in-vm" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory"/>
[...]
</server>
</subsystem>
ファクトリーの entries
属性では、ファクトリーが公開される JNDI 名を指定します。リモートクライアントに利用できるのは、java:jboss/exported
名前空間にバインドされた JNDI 名のみです。connection-factory
が java:jboss/exported
名前空間にバインドされたエントリーを持っている場合、リモートクライアントは java:jboss/exported
の後のテキストを使用して connection-factory
をルックアップします。たとえば、RemoteConnectionFactory
はデフォルトで java:jboss/exported/jms/RemoteConnectionFactory
にバインドされています。これは、リモートクライアントが jms/RemoteConnectionFactory
を使用してこの connection-factory をルックアップすることを意味します。pooled-connection-factory
はリモートクライアントに適していないため、pooled-connection-factory
では java:jboss/exported
名前空間内にエントリーがバインドされないようにする必要があります。
8.5.2. JNDI を使用したサーバーへの接続
クライアントがサーバーと同じ JVM 内に存在する場合は、InVmConnectionFactory
が提供する in-vm
コネクターを使用できます。以下は、standalone-full.xml
などでみられる InvmConnectionFactory
の典型的な設定方法です。
<connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm" />
<connection-factory
name="InVmConnectionFactory"
entries="java:/ConnectionFactory"
connectors="in-vm" />
entries
属性の値に注意してください。InVmConnectionFactory
を使用するクライアントは、以下の例のように、ルックアップ時に先頭の java:/
を省略します。
InitialContext ctx = new InitialContext(); ConnectionFactory cf = (ConnectionFactory)ctx.lookup("ConnectionFactory"); Connection connection = cf.createConnection();
InitialContext ctx = new InitialContext();
ConnectionFactory cf = (ConnectionFactory)ctx.lookup("ConnectionFactory");
Connection connection = cf.createConnection();
リモートクライアントでは RemoteConnectionFactory
を使用しますが、これは通常以下のような設定になります。
<connection-factory name="RemoteConnectionFactory" scheduled-thread-pool-max-size="10" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>
<connection-factory
name="RemoteConnectionFactory"
scheduled-thread-pool-max-size="10"
entries="java:jboss/exported/jms/RemoteConnectionFactory"
connectors="http-connector"/>
リモートクライアントでは entries
の値の先頭の java:jboss/exported/
を無視し、以下のコードスニペットの例に従います。
final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); env.put(Context.PROVIDER_URL, "http-remoting://remotehost:8080"); InitialContext remotingCtx = new InitialContext(env); ConnectionFactory cf = (ConnectionFactory) remotingCtx.lookup("jms/RemoteConnectionFactory");
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
env.put(Context.PROVIDER_URL, "http-remoting://remotehost:8080");
InitialContext remotingCtx = new InitialContext(env);
ConnectionFactory cf = (ConnectionFactory) remotingCtx.lookup("jms/RemoteConnectionFactory");
PROVIDER_URL
プロパティーの値と、クライアントの JBoss EAP http-remoting プロトコルの使用方法に注意してください。クライアントの org.wildfly.naming.client.WildFlyInitialContextFactory
の使用方法にも注意してください。これはクライアントがこのクラスを持ち、クラスパスのどこかにクライアント JAR を包含するということを意味します。Maven プロジェクトでは、以下の依存関係を含めることで実現できます。
<dependencies> <dependency> <groupId>org.wildfly</groupId> <artifactId>wildfly-jms-client-bom</artifactId> <type>pom</type> </dependency> </dependencies>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-jms-client-bom</artifactId>
<type>pom</type>
</dependency>
</dependencies>
8.5.3. コア API を使用したサーバーへの接続
Core API を使用すると、JNDI ルックアップを使用せずにクライアント接続を行うことができます。Core API を使用するクライアントでは、JNDI ベースのクライアントと同様、クラスパスでクライアント JAR が必要になります。
ServerLocator
クライアントは ServerLocator
インスタンスを使用して ClientSessionFactory
インスタンスを作成します。名前が示すように、ServerLocator
インスタンスはサーバーを検索し、そのサーバーへの接続を作成するために使用されます。
JMS では、JMS Connection Factory と同様に ServerLocator
を考えてみましょう。
ServerLocator
インスタンスは、ActiveMQClient
ファクトリークラスを使用して作成されます。
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(InVMConnectorFactory.class.getName()));
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(InVMConnectorFactory.class.getName()));
ClientSessionFactory
クライアントは ClientSessionFactory
を使用して ClientSession
インスタンスを作成します。これは基本的にサーバーへの接続です。JMS 関係ではこれを JMS 接続と考えます。
ClientSessionFactory
インスタンスは ServerLocator
クラスを使用して作成されます。
ClientSessionFactory factory = locator.createClientSessionFactory();
ClientSessionFactory factory = locator.createClientSessionFactory();
ClientSession
クライアントは ClientSession
を使用してメッセージの消費と生成を行い、トランザクションでメッセージをグループ化します。ClientSession
インスタンスは、トランザクションセマンティクスと非トランザクションセマンティクスの両方をサポートし、JTA トランザクションの一部として、メッセージング操作を実行できるように XAResource インターフェイスも提供できます。
ClientSession
インスタンスは ClientConsumers
と ClientProducers
をグループ化します。
ClientSession session = factory.createSession();
ClientSession session = factory.createSession();
今説明したことを簡単な例で以下に示します。
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA( new TransportConfiguration( InVMConnectorFactory.class.getName())); // In this simple example, we just use one session for both // producing and consuming ClientSessionFactory factory = locator.createClientSessionFactory(); ClientSession session = factory.createSession(); // A producer is associated with an address ... ClientProducer producer = session.createProducer("example"); ClientMessage message = session.createMessage(true); message.getBodyBuffer().writeString("Hello"); // We need a queue attached to the address ... session.createQueue("example", "example", true); // And a consumer attached to the queue ... ClientConsumer consumer = session.createConsumer("example"); // Once we have a queue, we can send the message ... producer.send(message); // We need to start the session before we can -receive- messages ... session.start(); ClientMessage msgReceived = consumer.receive(); System.out.println("message = " + msgReceived.getBodyBuffer().readString()); session.close();
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(
new TransportConfiguration( InVMConnectorFactory.class.getName()));
// In this simple example, we just use one session for both
// producing and consuming
ClientSessionFactory factory = locator.createClientSessionFactory();
ClientSession session = factory.createSession();
// A producer is associated with an address ...
ClientProducer producer = session.createProducer("example");
ClientMessage message = session.createMessage(true);
message.getBodyBuffer().writeString("Hello");
// We need a queue attached to the address ...
session.createQueue("example", "example", true);
// And a consumer attached to the queue ...
ClientConsumer consumer = session.createConsumer("example");
// Once we have a queue, we can send the message ...
producer.send(message);
// We need to start the session before we can -receive- messages ...
session.start();
ClientMessage msgReceived = consumer.receive();
System.out.println("message = " + msgReceived.getBodyBuffer().readString());
session.close();