旧バージョンでダイレクトシンクロナスメッセージを使用する場合
同期メッセージは削除され、Liferay DXP 7.4 U49/Liferay Portal 7.4 GA49 以降ではサポートされなくなりました。
ダイレクト同期メッセージングは、すべてのリスナーがメッセージを受信するまで処理をブロックする最も簡単な方法です。 SynchronousMessageSender
のsend(String, Message)
メソッドを呼び出し、宛先名とメッセージインスタンスを渡します。 SynchronousMessageSender
は、現在のスレッドを使用して、宛先に登録されている各メッセージリスナーで直接メッセージ受信を処理します。 リスナーの処理が完了すると、send(String, Message)
メソッドを呼び出したクラスで実行が続行されます。 この例は、ダイレクト同期メッセージングの使用をデモしています。
ダイレクト同期メッセージを送信する
サンプルプロジェクトでは、SynchronousMessageSender
を使用して、2つのリスナーに直接メッセージを送信します。
新しいLiferay インスタンスを起動し、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.55-ga55。
http://localhost:8080でLiferayへのサインインします。 メールアドレス[email protected]_とパスワード_test_を使用してください。 プロンプトが表示されたら、パスワードを _learn_に変更します。
その後、以下の手順を実行してください。
サンプルをダウンロードし、解凍してください。
curl https://resources.learn.liferay.com/dxp/latest/ja/building-applications/core-frameworks/message-bus/liferay-x6n5.zip -O
unzip liferay-x6n5.zip
サンプルのプロジェクトモジュールをビルドしてデプロイします。
cd liferay-x6n5
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
noteこのコマンドは、モジュールJARをDockerコンテナの
/opt/liferay/osgi/modules
にコピーするのと同じです。Dockerコンテナコンソールに、モジュールが起動されたことが示されます。
STARTED com.acme.x6n5.able.impl_1.0.0 STARTED com.acme.x6n5.baker.impl_1.0.0 STARTED com.acme.x6n5.charlie.impl_1.0.0 STARTED com.acme.x6n5.dog.impl_1.0.0
ブラウザで
http://localhost:8080
にあるLiferayインスタンスにアクセスし、認証情報を使用してサインインします。Gogo シェルを開きます。
Gogoシェルコマンドフィールドに、
x6n5:sendMessage
と入力し、その後にメッセージを入力します。 例:x6n5:sendMessage foo
出力が次のようになっていることを確認します。
INFO [pipe-x6n5:sendMessage foo][X6N5DogMessageListener:21] Received message payload foo INFO [pipe-x6n5:sendMessage foo][X6N5CharlieMessageListener:21] Received message payload foo INFO [pipe-x6n5:sendMessage foo][X6N5BakerOSGiCommands:28] Response: X6N5CharlieMessageListener
スレッドは、メッセージを送信するときにメッセージ送信者(つまり、X6N5BakerOSGiCommands
)でブロックされます。 X6N5CharlieMessageListener
およびX6N5DogMessageListener
でメッセージを処理した後、スレッドはメッセージ送信者で続行されます。
プロジェクトの概要
4つのサンプルモジュールには1つのクラスがあります。 1つのクラスは宛先を管理し、別のクラスはメッセージを送信し、他の2つは宛先に送信されたメッセージをリッスンします。
クラスの例:
クラス | モジュール | 説明 |
---|---|---|
X6N5AbleMessagingConfigurator |
x6n5-able-impl |
acme/x6n5_able という名前のメッセージ宛先を作成し、メッセージバスに登録します。 |
X6N5BakerOSGiCommands |
x6n5-baker-impl |
acme/x6n5_able 宛先にメッセージを送信し、応答をログに記録します。 |
X6N5CharlieMessageListener |
x6n5-charlie-impl |
acme/x6n5_able 宛先に送信されたメッセージをリッスンします。 メッセージペイロードをログに記録し、メッセージに応答を設定します。 |
X6N5DogMessageListener |
x6n5-dog-impl |
acme/x6n5_able 宛先に送信されたメッセージをリッスンします。 メッセージペイロードをログに記録し、メッセージに応答を設定します。 |
イベントフローは次のとおりです。
- ユーザーが
x6n5:sendMessage
Gogoシェルコマンドを実行すると、X6N5BakerOSGiCommands
はメッセージペイロードのコマンド引数をacme/x6n5_able
宛先に送信します。 - 現在のスレッドは、各リスナー(つまり、
X6N5CharlieMessageListener
とX6N5DogMessageListener
)のメッセージ受信を連続して処理します。 リスナーはメッセージペイロードをログに記録し、メッセージに応答を設定します。 処理された最新のリスナーからの応答は、以前の応答に優先します。 - 処理は
X6N5BakerOSGiCommands
に戻り、メッセージ応答をログに記録します。
これで、宛先コンフィギュレーターから順に、各クラスを調べることができます
宛先コンフィグレーターを調べる
x6n5-able-impl
モジュールのX6N5AbleMessagingConfigurator
クラスは、acme/x6n5_able
という名前の宛先を作成して構成します。 コードは次のとおりです。
@Component
public class X6N5AbleMessagingConfigurator {
@Activate
private void _activate(BundleContext bundleContext) {
Destination destination = _destinationFactory.createDestination(
DestinationConfiguration.createSynchronousDestinationConfiguration(
"acme/x6n5_able"));
_serviceRegistration = bundleContext.registerService(
Destination.class, destination,
MapUtil.singletonDictionary(
"destination.name", destination.getName()));
}
@Deactivate
private void _deactivate() {
if (_serviceRegistration != null) {
_serviceRegistration.unregister();
}
}
@Reference
private DestinationFactory _destinationFactory;
private ServiceRegistration<Destination> _serviceRegistration;
}
このコンフィギュレーターは Component
クラスです。 これは、 @Reference
アノテーションを使用して、DestinationFactory
インスタンスを挿入します。
_activate(BundleContext)
メソッドは、 DestinationFactory
と DestinationConfiguration
を使用して、acme/x6n5_able
という名前の 同期 宛先を作成します。 同期宛先は、同期メッセージング用に最適化されています。 最後に、メソッドはBundleContext
を使用して Destination
をOSGiサービスに登録します。
X6N5AbleMessagingConfigurator
が無効化されると、その_deactivate()
メソッドは宛先サービスの登録を解除します。
送信者を調べる
x6n5-baker-impl
モジュールのX6N5BakerOSGiCommands
クラスは、メッセージを宛先に送信するOSGiコマンドを提供します。
service = X6N5BakerOSGiCommands.class
)
public class X6N5BakerOSGiCommands {
public void sendMessage(String payload) throws MessageBusException {
Message message = new Message();
message.setPayload(payload);
Object response = _synchronousMessageSender.send(
"acme/x6n5_able", message);
System.out.println("Response: " + response);
}
@Reference(target = "(mode=DIRECT)")
private SynchronousMessageSender _synchronousMessageSender;
}
X6N5BakerOSGiCommands
は、独自のクラスタイプのサービスComponent
です。 これは、@Reference
アノテーションを使用して、 ダイレクト モード(アノテーションのtarget = "(mode=DIRECT)"
属性で指定)に設定されたSynchronousMessageSender
を挿入します。
ダイレクトモードでは、SynchronousMessageSender
send
メソッドは、現在のスレッドがすべてのリスナーにメッセージを配信するまで、呼び出し元のクラスをブロックします。
X6N5BakerOSGiCommands
の@Component
プロパティは、sendMessage
と呼ばれるGogoシェルコマンド関数をx6n5
スコープで定義します。 コマンドはsendMessage(String)
メソッドにマッピングされ、入力String
を受け取ります。
sendMessage(String)
メソッドは、GogoシェルコマンドのString
をペイロードとして使用して Message
を作成します。 SynchronousMessageSender
send(String, Message)
メソッドは、現在のスレッドを使用して、acme/x6n5_able
Destination
メッセージリスナーにメッセージを配信します。 スレッドがすべての MessageListener
でメッセージを処理するまで、実行はX6N5BakerOSGiCommands
クラスでブロックされます。 その後、X6N5BakerOSGiCommands
sendMessage(String)
メソッドで実行が続行され、メッセージ応答がログに記録されます。
リスナーを調べる
x6n5-charlie-impl
モジュールのX6N5CharlieMessageListener
クラスとx6n5-dog-impl
モジュールのX6N5DogMessageListener
クラスは、acme/x6n5_able
Destination
に送信されたメッセージをリッスンします。 メッセージを聞く に示されている方法と同じ方法で登録されます。
X6N5CharlieMessageListener
クラス:
service = MessageListener.class
)
public class X6N5CharlieMessageListener implements MessageListener {
@Override
public void receive(Message message) {
System.out.println("Received message payload " + message.getPayload());
message.setResponse("X6N5CharlieMessageListener");
}
}
X6N5DogMessageListener
クラス:
service = MessageListener.class
)
public class X6N5DogMessageListener implements MessageListener {
@Override
public void receive(Message message) {
System.out.println("Received message payload " + message.getPayload());
message.setResponse("X6N5DogMessageListener");
}
}
各リスナーのreceive(Message)
メソッドは、メッセージペイロードをログに記録してから、メッセージ応答を独自のクラス名に設定します。
ダイレクト同期メッセージングの使用方法が分かりました。
次のステップ
デフォルトの モードを使った同期メッセージングについて調べたい場合は、 旧バージョンのデフォルトの同期メッセージングの使用をご覧ください。
メッセージを送信した直後に処理を続行する場合は、 非同期メッセージングの使用 を参照してください。