メッセージング アクティビティ
アクティビティを管理することで、ワークフローが WCF メッセージを送受信できるようになります。 メッセージング アクティビティをワークフローに追加することで、任意に複雑なメッセージ交換パターン (MEP) をモデル化できます。
メッセージ交換パターン
基本的なメッセージ交換パターンは、次の 3 種類です。
データグラム - データグラム MEP を使用する場合は、クライアントがメッセージをサービスに送信しても、サービスは応答しません。 これは、"ファイア アンド フォーゲット (撃ち放し)" と呼ばれる場合があります。 このような交換では、配信の成否について帯域外での確認が必要になります。 メッセージが移動中に失われて、サービスに到達しない可能性があります。 クライアントが正常にメッセージを送信した場合でも、サービスがメッセージを受信したとは限りません。 サービスは、メッセージングの不可欠な構成要素であり、これを基盤として独自の MEP を構築できます。
要求 - 応答 - 要求 - 応答 MEP を使用する場合は、クライアントがメッセージをサービスに送信し、サービスは必要な処理を実行して、応答をクライアントに返します。 パターンは、要求 - 応答のペアで構成されます。 要求 - 応答呼び出しの例として、リモート プロシージャ コール (RPC) やブラウザー GET 要求などがあります。 このパターンは、半二重とも呼ばれます。
二重 - 二重 MEP を使用する場合は、クライアントとサービスが、任意の順番でメッセージを相互に送信できます。 二重 MEP は、話される語の 1 つずつがメッセージである電話の会話に似ています。
メッセージング アクティビティを使用すると、これらの基本の MEP のほかに、任意の複雑な MEP を実装できます。
メッセージング アクティビティ
.NET Framework 4.6.1 では、次のメッセージング アクティビティが定義されています。
SendReply - 受信したメッセージに対する応答の送信には、SendReply アクティビティを使用します。 このアクティビティは、要求/応答 MEP を実装した場合に、ワークフロー サービスによって使用されます。
ReceiveReply - 応答メッセージの受信には ReceiveReply アクティビティを使用します。 このアクティビティは、要求/応答 MEP を実装した場合に、ワークフロー サービス クライアントによって使用されます。
メッセージング アクティビティとメッセージ交換パターン
データグラム MEP には、メッセージを送信するクライアントとメッセージを受信するサービスが必要です。 クライアントがワークフローの場合は、Send アクティビティを使用してメッセージを送信します。 そのメッセージをワークフローで受信するには、Receive アクティビティを使用します。 Send アクティビティと Receive アクティビティのどちらにも、Content
という名前のプロパティがあります。 このプロパティには、送信または受信されるデータが保持されます。 要求 - 応答 MEP を実装する場合は、クライアントとサービスの両方で、アクティビティの組を使用します。 クライアントは、Send アクティビティを使用してメッセージを送信し、ReceiveReply アクティビティを使用してサービスからの応答を受信します。 これらの 2 つのアクティビティは、Request プロパティによって互いに関連付けられています。 このプロパティは、元のメッセージを送信した Send アクティビティに設定されます。 サービスも、相互に関連付けられた、Receive および SendReply というアクティビティのペアを使用します。 これらの 2 つのアクティビティは、Request プロパティによって関連付けられています。 このプロパティは、元のメッセージを受信した Receive アクティビティに設定されます。 ReceiveReply アクティビティおよび SendReply アクティビティを使用すると、Send アクティビティおよび Receive アクティビティと同様に、Message インスタンスまたはメッセージ コントラクト型を送信できます。
ワークフローは長時間にわたって実行されることが多いため、通信の二重パターンでは、長時間のメッセージ交換をサポートすることも重要です。 長時間のメッセージ交換をサポートするには、メッセージ交換を開始するクライアントが、後でデータが利用可能になった時点でクライアントにコールバックする機会をサービスに提供する必要があります。 たとえば、マネージャーの承認を受けるために発注書の要求が送信された場合に、この要求が、1 日、1 週間、または 1 年間処理されない可能性があるとします。この場合、マネージャーが発注書を承認するワークフローは、承認を受けた後に再開することを認識している必要があります。 この二重通信のパターンは、相関関係を使用するワークフローでサポートされています。 二重パターンを実装するには、Send アクティビティと Receive アクティビティを使用します。 Receive アクティビティで、CorrelationHandle を使用して、相関関係を初期化します。 Send アクティビティで、その関連付けハンドルを CorrelatesWith プロパティの値として設定します。 詳細については、永続的な二重に関するページを参照してください。
Note
ワークフローにコールバック相関関係を使用する二重 ("永続的な二重") を実装するのは、長時間のメッセージ交換のためです。 これは、コールバック コントラクトを使用する WCF の二重と同じではありません。WCF の二重では、メッセージ交換が短時間 (チャネルの有効期間) で処理されます。
メッセージの書式設定とメッセージング アクティビティ
Receive アクティビティと ReceiveReply アクティビティには、Content
という名前のプロパティがあります。 このプロパティは ReceiveContent 型で、Receive アクティビティまたは ReceiveReply アクティビティが受信するデータを表します。 .NET Framework では、ReceiveMessageContent および ReceiveParametersContent という 2 つの関連クラスが定義されています。どちらも、ReceiveContent から派生しています。 ワークフロー サービスでデータを受信するには、Receive アクティビティまたは ReceiveReply アクティビティの Content
プロパティを、これらの型のいずれかのインスタンスに設定します。 どの型を使用するかは、アクティビティが受信するデータの型によって異なります。 アクティビティが Message
オブジェクト型またはメッセージ コントラクト型を受信する場合は、ReceiveMessageContent を使用します。 シリアル化できるデータ コントラクトまたは XML 型をアクティビティが受信した場合には、ReceiveParametersContent を使用します。 ReceiveParametersContent では複数のパラメーターを送信できますが、ReceiveMessageContent で送信できるのは、1 つのオブジェクト、つまり、メッセージ (またはメッセージ コントラクト型) のみです。
Note
ReceiveMessageContent は、シリアル化できるデータ コントラクトまたは XML 型が 1 つだけの場合も使用できます。 パラメーターが 1 つだけの ReceiveParametersContent を使用する場合と、ReceiveMessageContent に直接渡されるオブジェクトとの違いは、ワイヤ形式です。 パラメーターのコンテンツは、操作名に対応する XML 要素でラップされ、シリアル化されたオブジェクトは、パラメーター名を使用した XML 要素でラップされます (例: <Echo><msg>Hello, World</msg></Echo>
)。 メッセージの内容は、操作名によってラップされません。 代わりに、シリアル化されたオブジェクトが、XML 修飾型の名前を使用して XML 要素内に格納されます (例: <string>Hello, World</string>
)。
Send アクティビティと SendReply アクティビティにも、Content
という名前のプロパティがあります。 このプロパティは SendContent 型で、Send アクティビティまたは SendReply アクティビティが送信するデータを表します。 .NET Framework では、SendMessageContent および SendParametersContent という 2 つの関連型が定義されています。どちらも、SendContent から派生しています。 ワークフロー サービスからデータを送信するには、Send アクティビティまたは SendReply アクティビティの Content
プロパティを、これらの型のいずれかのインスタンスに設定します。 どの型を使用するかは、アクティビティが送信するデータの型によって異なります。 アクティビティが Message
オブジェクト型またはメッセージ コントラクト型を送信する場合は、SendMessageContent を使用します。 アクティビティがデータ コントラクト型を送信する場合は、SendParametersContent を使用します。 SendParametersContent では複数のパラメーターを送信できますが、SendMessageContent で送信できるのは、1 つのオブジェクト、つまり、メッセージ (またはメッセージ コントラクト型) のみです。
強制的にメッセージング アクティビティを使用してプログラミングを行う場合は、汎用の InArgument<T> および OutArgument<T> を使用して、メッセージまたは Send、SendReply、Receive、および ReceiveReply アクティビティのパラメーター プロパティに割り当てるオブジェクトをラップします。 Send アクティビティと SendReply アクティビティには InArgument<T> を、Receive アクティビティと ReceiveReply アクティビティには OutArgument<T> を使用します。 In
引数は、データがアクティビティに渡されるため、送信アクティビティで使用されます。 Out
引数は、データがアクティビティから渡されるため、受信アクティビティで使用されます。この例を次に示します。
Receive reserveSeat = new Receive
{
...
Content = new ReceiveParametersContent
{
Parameters =
{
{ "ReservationInfo", new OutArgument<ReservationRequest>(reservationInfo) }
}
}
};
SendReply reserveSeat = new SendReply
{
...
Request = reserveSeat,
Content = new SendParametersContent
{
Parameters =
{
{ "ReservationId", new InArgument<string>(reservationId) }
}
},
};
void を返す要求/応答操作を定義するワークフロー サービスを実装する場合は、SendReply アクティビティをインスタンス化して、Content プロパティをコンテンツの種類 (SendMessageContent または SendParametersContent) のいずれかのインスタンスに設定します。この例を次に示します。
Receive rcv = new Receive()
{
ServiceContractName = "IService",
OperationName = "NullReturningContract",
Content = new ReceiveParametersContent( new Dictionary<string, OutArgument>() { { "message", new OutArgument<string>() } } )
};
SendReply sr = new SendReply()
{
Request = rcv
Content = new SendParametersContent();
};
サービス参照の追加
ワークフロー アプリケーションからワークフロー サービスを呼び出すと、Visual Studio 2012 では、要求/応答 MEP で使用される通常の Send と ReceiveReply アクティビティをカプセル化したカスタムのメッセージング アクティビティが生成されます。 この機能を使用するには、Visual Studio でクライアント プロジェクトを右クリックして、 [追加]>[サービス参照] をクリックします。 アドレス ボックスにサービスのベース アドレスを入力し、[移動] をクリックします。 使用可能なサービスが、 [サービス] ボックスに表示されます。 サービス ノードを展開して、サポートされるコントラクトを表示します。 呼び出すコントラクトを選択すると、使用可能な操作の一覧が [操作] ボックスに表示されます。 生成されたアクティビティの名前空間を指定し、 [OK] をクリックします。 操作が正常に完了したことを示すダイアログが表示され、プロジェクトを再度ビルドすると、生成されたカスタム アクティビティがツールボックスに表示されます。 サービス コントラクトに定義されている操作ごとに 1 つのアクティビティがあります。 プロジェクトを再度ビルドしたら、カスタム アクティビティをワークフローにドラッグ アンド ドロップして、必要なプロパティをプロパティ ウィンドウで設定できます。
メッセージング アクティビティ テンプレート
クライアントとサービスでの要求または応答 MEP の設定を簡単にするため、Visual Studio 2012 には、2 種類のメッセージング アクティビティ テンプレートが用意されています。 System.ServiceModel.Activities.Design.ReceiveAndSendReply
はサービスで、System.ServiceModel.Activities.Design.SendAndReceiveReply
はクライアントで使用されます。 どちらの場合も、テンプレートによって、適切なメッセージング アクティビティがワークフローに追加されます。 サービスの場合、System.ServiceModel.Activities.Design.ReceiveAndSendReply
は Receive アクティビティを追加し、次に SendReply アクティビティを追加します。 Request プロパティは自動的に Receive アクティビティに設定されます。 クライアントの場合、System.ServiceModel.Activities.Design.SendAndReceiveReply
は Send アクティビティを追加し、次に ReceiveReply アクティビティを追加します。 Request プロパティは自動的に Send アクティビティに設定されます。 これらのテンプレートは、適切なテンプレートをワークフローにドラッグ アンド ドロップするだけで使用できます。
メッセージング アクティビティとトランザクション
ワークフロー サービスが呼び出されるときに、サービス操作にトランザクションをフローする必要がある場合があります。 それには、Receive アクティビティを TransactedReceiveScope アクティビティ内に配置します。 TransactedReceiveScope アクティビティには、Receive
アクティビティと本体が含まれます。 サービスにフローされるトランザクションは、TransactedReceiveScope の本体の実行の開始から終了まで、アンビエント トランザクションのままです。 トランザクションは、本体の実行が終了した時点で完了します。 ワークフローとトランザクションの詳細については、「ワークフロー トランザクション」を参照してください。