Message Bus
ご覧のページは、お客様の利便性のために一部機械翻訳されています。また、ドキュメントは頻繁に更新が加えられており、翻訳は未完成の部分が含まれることをご了承ください。最新情報は都度公開されておりますため、必ず英語版をご参照ください。翻訳に問題がある場合は、 こちら までご連絡ください。

以前のバージョンにおける直接同期メッセージングの使用

Liferay DXP 7.4 U48/Portal GA49 以前 サポート対象外

重要

このチュートリアルで説明するメッセージングAPIは、Liferay DXP 7.4 U48/Portal GA49以降では利用できません。

直接同期メッセージングは、すべてのリスナーがメッセージを受信するまで処理をブロックする最も簡単な方法です。 SynchronousMessageSendersend(String, Message) メソッドを呼び出し、宛先名とメッセージインスタンスを渡します。 SynchronousMessageSender は、現在のスレッドを使用して、宛先の登録済みメッセージリスナーのそれぞれでメッセージ受信を直接処理します。 リスナー処理が完了すると、 send(String, Message) メソッドを呼び出したクラスで実行が続行されます。 この例は、直接同期メッセージングを使用する方法を示しています。

ダイレクト同期メッセージを送信する

サンプルプロジェクトでは、 SynchronousMessageSender を使用して、メッセージを 2 つのリスナーに直接送信します。

Liferay の新しいインスタンスを起動するには、次のコマンドを実行します。

docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.48-ga48

http://localhost:8080 で Liferay にサインインしてください。 メールアドレス test@liferay.com とパスワード test を使用してください。 プロンプトが表示されたら、パスワードを learn に変更してください。

次に、以下の手順に従ってください。

  1. サンプルをダウンロードして解凍してください。

    curl https://resources.learn.liferay.com/examples/liferay-x6n5.zip -O
    
    unzip liferay-x6n5.zip
    
  2. サンプルプロジェクトのモジュールをビルドしてデプロイします。

    cd liferay-x6n5
    
    ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    
    注記

    このコマンドは、モジュール JAR を Docker コンテナ上の /opt/liferay/osgi/modules にコピーすることと同じです。

  3. Dockerコンテナのコンソールには、モジュールが起動したことが表示されます。

    com.acme.x6n5.able.impl_1.0.0 が起動しました
    com.acme.x6n5.baker.impl_1.0.0 が起動しました
    com.acme.x6n5.charlie.impl_1.0.0 が起動しました
    com.acme.x6n5.dog.impl_1.0.0 が起動しました
    
  4. ブラウザで http://localhost:8080 にアクセスして Liferay インスタンスを開き、認証情報を使用してサインインしてください。

  5. Gogo Shell を開きます。

  6. Gogo Shell コマンドフィールドに、 x6n5:sendMessage と入力し、続けてメッセージを入力します。 例えば、

    x6n5:sendMessage foo
    
  7. 出力が以下のようになっていることを確認してください。

    INFO [pipe-x6n5:sendMessage foo][X6N5DogMessageListener:21] メッセージペイロード foo を受信しました
    INFO [pipe-x6n5:sendMessage foo][X6N5CharlieMessageListener:21] メッセージペイロード foo を受信しました
    INFO [pipe-x6n5:sendMessage foo][X6N5BakerOSGiCommands:28] レスポンス: X6N5CharlieMessageListener
    

メッセージを送信すると、スレッドはメッセージ送信元 (つまり、 X6N5BakerOSGiCommands) でブロックされます。 X6N5CharlieMessageListener および X6N5DogMessageListenerでメッセージを処理した後、スレッドはメッセージ送信側で続行されます。

プロジェクト概要

4つのサンプルモジュールには、それぞれ1つのクラスが含まれています。 あるクラスは宛先を管理し、別のクラスはメッセージを送信し、残りの2つのクラスは宛先に送信されたメッセージをリッスンします。

サンプルクラス:

クラスモジュール説明
X6N5AbleMessagingConfiguratorx6n5-able-implacme/x6n5_ableという名前のメッセージ宛先を作成し、メッセージバスに登録します。
X6N5BakerOSGiCommandsx6n5-baker-implacme/x6n5_able宛先にメッセージを送信し、応答をログに記録します。
X6N5CharlieMessageListenerx6n5-charlie-implacme/x6n5_able宛先に送信されたメッセージをリッスンします。 メッセージペイロードをログに記録し、メッセージに応答を設定します。
X6N5DogMessageListenerx6n5-dog-implacme/x6n5_able宛先に送信されたメッセージをリッスンします。 メッセージペイロードをログに記録し、メッセージに応答を設定します。

イベントフローは次のとおりです。

  1. ユーザーが x6n5:sendMessage Gogo シェル コマンドを実行すると、 X6N5BakerOSGiCommands はコマンド引数をメッセージ ペイロードとして acme/x6n5_able 宛先に送信します。

  2. 現在のスレッドは、各リスナー (つまり、 X6N5CharlieMessageListener および X6N5DogMessageListener) のメッセージ受信を順番に処理します。 リスナーはメッセージのペイロードをログに記録し、メッセージに対する応答を設定します。 最新のリスナーからの応答は、以前の応答に優先します。

  3. 処理は 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;

}

このコンフィギュレータは、 コンポーネント クラスです。 @Reference アノテーションを使用して、 DestinationFactory インスタンスを注入します。

_activate(BundleContext) メソッドは、 DestinationFactoryDestinationConfiguration を使用して、 同期 という名前の宛先を作成します。 acme/x6n5_able. 同期宛先は、同期メッセージングに最適化されています。 最後に、このメソッドは DestinationBundleContext を使用して OSGi サービスに登録します。

X6N5AbleMessagingConfigurator が非アクティブ化されると、その _deactivate() メソッドは宛先サービスを登録解除します。

送信者を調べる

x6n5-baker-impl モジュールの X6N5BakerOSGiCommands クラスは、宛先にメッセージを送信する OSGi コマンドを提供します。

@Component(
	property = {"osgi.command.function=sendMessage", "osgi.command.scope=x6n5"},
	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 は、独自のクラスタイプのサービス コンポーネント です。 これは、 @Reference アノテーションを使用して、 SynchronousMessageSender を挿入します。この は direct モードに設定されています (アノテーションの target = "(mode=DIRECT)" 属性で指定)。

注記

ダイレクト モードでは、 SynchronousMessageSender send メソッドは、現在のスレッドがメッセージをすべてのリスナーに配信するまで呼び出し元のクラスをブロックします。

X6N5BakerOSGiCommands@Component プロパティは、 sendMessage という Gogo シェル コマンド関数を定義し、 x6n5 スコープで使用します。 このコマンドは sendMessage(String) メソッドにマッピングされ、入力として String を受け取ります。

sendMessage(String) メソッドは、ペイロードとして Gogo シェル コマンドの 文字列 を含む メッセージ を作成します。 SynchronousMessageSender send(String, Message) メソッドは、現在のスレッドを使用して、メッセージを acme/x6n5_able Destination メッセージリスナーに配信します。 X6N5BakerOSGiCommands クラスの実行は、スレッドがすべての MessageListenerのメッセージを処理するまでブロックされます。 次に、 X6N5BakerOSGiCommands sendMessage(String) メソッドで実行が続行され、そこでメッセージ応答がログに記録されます。

聞き手を調査する

x6n5-charlie-impl モジュールの X6N5CharlieMessageListener クラスと x6n5-dog-impl モジュールの X6N5DogMessageListener クラスは、 acme/x6n5_able に送信されたメッセージをリッスンします。 目的地。 それらは、 メッセージのリッスン で示されているのと同じ方法で登録されます。

X6N5CharlieMessageListener クラス:

@Component(
	property = "destination.name=acme/x6n5_able",
	service = MessageListener.class
)
public class X6N5CharlieMessageListener implements MessageListener {

	@Override
	public void receive(Message message) {
		System.out.println("受信したメッセージペイロード " + message.getPayload());

		message.setResponse("X6N5CharlieMessageListener");
	}

}

X6N5DogMessageListener クラス:

@Component(
	property = "destination.name=acme/x6n5_able",
	service = MessageListener.class
)
public class X6N5DogMessageListener implements MessageListener {

	@Override
	public void receive(Message message) {
		System.out.println("受信したメッセージペイロード " + message.getPayload());

		message.setResponse("X6N5DogMessageListener");
	}

}

各リスナーの receive(Message) メソッドはメッセージ ペイロードをログに記録し、メッセージ応答を自身のクラス名に設定します。

  あなたは直接同期メッセージングの使い方を知っていますね。

次は?

デフォルト モードを使用して同期メッセージングを検証したい場合は、 以前のバージョンでのデフォルトの同期メッセージングの使用 を参照してください。

メッセージ送信後すぐに処理を続行したい場合は、 非同期メッセージングの使用 を参照してください。