メッセージング アクティビティを使用すると、ワークフローで WCF メッセージを送受信できます。 メッセージング アクティビティをワークフローに追加することで、任意に複雑なメッセージ交換パターン (MEP) をモデル化できます。
メッセージ交換パターン
次の 3 つの基本的なメッセージ交換パターンがあります。
データグラム - データグラム MEP を使用すると、クライアントはサービスにメッセージを送信しますが、サービスは応答しません。 これは「発射して忘れる」と呼ばれることもあります。 このような交換では、配信の成否について帯域外での確認が必要になります。 メッセージが転送中に失われ、サービスに到達しない可能性があります。 クライアントがメッセージを正常に送信した場合、サービスがメッセージを受信したという保証はありません。 データグラムは、独自の MEP をその上に構築できるため、メッセージングの基本的な構成要素です。
要求-応答 - 要求-応答 MEP を使用すると、クライアントはサービスにメッセージを送信し、必要な処理を行い、応答をクライアントに返します。 このパターンは、要求と応答のペアで構成されます。 要求応答呼び出しの例としては、リモート プロシージャ コール (RPC) とブラウザーの GET 要求があります。 このパターンは半二重とも呼ばれます。
双方向 - 双方向 MEP を使用する場合、クライアントとサービスは任意の順序でメッセージを相互に送信できます。 双方向 MEP は電話での会話のようなもので、話されている各単語はメッセージです。
メッセージング アクティビティを使用すると、これらの基本的な 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 つの関連アクティビティも使用されます。 これら 2 つのアクティビティは、 Request プロパティによって関連付けられます。 このプロパティは、元のメッセージを受信した Receive アクティビティに設定されます。
ReceiveReplyやSendReplyなどのSendおよびReceiveアクティビティを使用すると、Message インスタンスまたはメッセージ コントラクトの種類を送信できます。
ワークフローの実行時間が長いため、通信の双方向パターンでも実行時間の長い会話をサポートすることが重要です。 実行時間の長い会話をサポートするには、会話を開始するクライアントは、データが使用可能になったときに後で呼び出す機会をサービスに提供する必要があります。 たとえば、発注書要求はマネージャーの承認のために送信されますが、1 日、1 週間、または 1 年間処理されない場合があります。発注書の承認を管理するワークフローは、承認が与えられた後に再開することを認識している必要があります。 この双方向通信パターンは、相関関係を使用したワークフローでサポートされています。 双方向パターンを実装するには、 Send および Receive アクティビティを使用します。 Receive アクティビティで、CorrelationHandleを使用して相関関係を初期化します。 Send アクティビティセットで関連付けハンドルをCorrelatesWith プロパティ値として設定してください。 詳細については、「 Durable Duplex」を参照してください。
注
ワークフローにコールバック相関関係を使用する二重 ("永続的な二重") を実装するのは、長時間のメッセージ交換のためです。 これは、コールバック コントラクトを使用する WCF の二重と同じではありません。WCF の二重では、メッセージ交換が短時間 (チャネルの有効期間) で処理されます。
メッセージの書式設定とメッセージング アクティビティ
ReceiveアクティビティとReceiveReply アクティビティには、Content
という名前のプロパティがあります。 このプロパティは ReceiveContent 型であり、 Receive または ReceiveReply アクティビティが受け取るデータを表します。 .NET Framework では、ReceiveMessageContent と呼ばれる 2 つの関連クラスが定義され、両方ともReceiveParametersContentから派生ReceiveContent。 ワークフロー サービスにデータを受信するには、 Receive または ReceiveReply アクティビティの Content
プロパティをこれらの型のいずれかのインスタンスに設定します。 使用する型は、アクティビティが受け取るデータの種類によって異なります。 アクティビティが Message
オブジェクトまたはメッセージ コントラクト型を受け取る場合は、 ReceiveMessageContentを使用します。 アクティビティがシリアル化できるデータ コントラクトまたは XML 型のセットを受け取る場合は、 ReceiveParametersContentを使用します。
ReceiveParametersContent では複数のパラメーターを送信できますが、 ReceiveMessageContent ではメッセージ (またはメッセージ コントラクト型) の 1 つのオブジェクトのみを送信できます。
注
ReceiveMessageContent は、シリアル化できる単一のデータ コントラクトまたは XML 型でも使用できます。 1 つのパラメーターで ReceiveParametersContent を使用することと、 ReceiveMessageContent に直接渡すオブジェクトの違いは、ワイヤ形式です。 パラメーターの内容は、操作名に対応する XML 要素にラップされ、シリアル化されたオブジェクトは、パラメーター名 ( <Echo><msg>Hello, World</msg></Echo>
など) を使用して XML 要素にラップされます。 メッセージの内容は、操作名によってラップされません。 代わりに、シリアル化されたオブジェクトは、XML 修飾型名 (たとえば、 <string>Hello, World</string>
) を使用して XML 要素内に配置されます。
SendアクティビティとSendReply アクティビティには、Content
という名前のプロパティもあります。 このプロパティは SendContent 型であり、 Send または SendReply アクティビティが送信するデータを表します。 .NET Framework では、SendMessageContent と呼ばれる 2 つの関連する型と、SendParametersContentから派生したSendContentの両方が定義されています。 ワークフロー サービスからデータを送信するには、 Send または SendReply アクティビティの Content
プロパティをこれらの型のいずれかのインスタンスに設定します。 使用する型は、アクティビティが送信するデータの種類によって異なります。 アクティビティが Message
オブジェクトまたはメッセージ コントラクト型を送信する場合は、 SendMessageContentを使用します。 アクティビティがデータ コントラクト型を送信する場合は、 SendParametersContentを使用します。
SendParametersContent では複数のパラメーターを送信できますが、 SendMessageContent では、メッセージ (またはメッセージ コントラクト型) の 1 つのオブジェクトのみを送信できます。
メッセージング アクティビティを使用して命令的にプログラミングする場合は、汎用 InArgument<T> と OutArgument<T> を使用して、 Send、 SendReply、 Receive、および ReceiveReply アクティビティのメッセージまたはパラメーター プロパティに割り当てるオブジェクトをラップします。
InArgument<T>およびSendアクティビティにはSendReplyを使用し、OutArgument<T>およびReceiveアクティビティにはReceiveReplyを使用します。
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 でクライアント プロジェクトを右クリックし、[ 追加>Service 参照] を選択します。 [アドレス] ボックスにサービスのベース アドレスを入力し、[Go] をクリックします。 使用可能なサービスが [ サービス: ] ボックスに表示されます。 サービス ノードを展開して、サポートされているコントラクトを表示します。 呼び出すコントラクトを選択すると、[ 操作 ] ボックスに使用可能な操作の一覧が表示されます。 その後、生成されたアクティビティの名前空間を指定し、[ 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 の本体の実行の開始から終了まで、アンビエント トランザクションのままです。 コードの本体が実行を完了すると、トランザクションが完了します。 ワークフローとトランザクションの詳細については、「 ワークフロー トランザクション」を参照してください。