何百または何千ものクライアント コンピューターがサーバーに対して WCP を実行している場合、データを受信してデータベースに正常に保存したことを示す「200 OK」タイプのメッセージで応答する必要がありますか?
これは既に WCF に組み込まれていますか?
何百または何千ものクライアント コンピューターがサーバーに対して WCP を実行している場合、データを受信してデータベースに正常に保存したことを示す「200 OK」タイプのメッセージで応答する必要がありますか?
これは既に WCF に組み込まれていますか?
ここで言及されているメッセージングパターンは3つあります。
3つすべてが異なるメッセージング動作を表示し、使用するパターンはニーズに基づいて選択する必要があります。
データがデータベースに永続化されたときにクライアントに成功を返すという要件には、オプション1または3が適切です。
これがデフォルトの構成です。
これにより、サービスがすべてのタスクを完了すると、同じhttp接続で200応答が返されます。これは、応答を待っている間、サービスへの呼び出しがブロックされることを意味します。サービスがデータベースに書き込み、その他の必要な処理を行うまで、クライアントはハングします。
トランスポート層とメッセージングインフラストラクチャ層が成功する限り、202応答を返します。返された202は、メッセージが受け入れられたことを示します。http rfcから:
リクエストは処理のために受け入れられましたが、処理は完了していません。(...)202の応答は、意図的に非コミットです。
これは、サービスインフラストラクチャがサービスを正常に開始するとすぐにクライアントが実行を継続し、データベース呼び出しが成功したかどうかに関する情報を受け取らないことを意味します。
オプション2と同様に、応答は200ではなくhttp 202ですが、クライアントからサービスを呼び出すときにInstanceContext
、コールバックを処理するオブジェクトを指定するオブジェクトを提供します。クライアントは制御を取り戻し、新しいスレッドは、成功または失敗を通知するサービス応答を非同期的に待機します。
以下は、WCFでのこれらのパターンの実装に関する詳細情報です。それを書いた後、それはかなり長いですが、コードと同様にいくつかの有用なコメントがあります。
Whiskが述べたように、Juval Lowyには、この詳細(およびそれ以上!)を多くカバーする記事があります。
これはWCFのデフォルトの動作であるため、何もする必要はありません。wsHttpBindingやbasicHttpBindingなどのさまざまなバインディングで機能します。
注意すべき点の1つは、次のような無効な操作がある場合でも、クライアントが200応答の発生を待機している状態で説明されている動作です。
[ServiceContract]
interface IMyServiceContract
{
[OperationContract]
void DoSomeThing(InputMessage Message);
}
操作を一方向として設定するには、次のように装飾するだけです。
[ServiceContract]
interface IMyServiceContract
{
[OperationContract(IsOneWay = true)]
void DoSomeThing(InputMessage Message);
}
このように装飾されたメソッドは、returnタイプのvoidのみを持つ必要があります。1つの落とし穴は、サービスが正常にビルドされ、接続するまでサービス構成が無効であるという例外が発生しないことです。
デュプレックスコールバックサービスを作成するためのインターフェイスコードは次のとおりです。
[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
interface IMyContract
{
[OperationContract(IsOneWay=true)]
void DoSomeThing(InputMessage Message);
}
public interface IMyContractCallback
{
[OperationContract(IsOneWay = true)]
void ServiceResponse(string result);
}
そして、クライアント側では、コールバックを設定するためにそのようなものが必要です。
public class CallbackHandler : IMyContractCallback
{
#region IEchoContractCallback Members
public void ServiceResponse(string result)
{
//Do something with the response
}
#endregion
}
// And in the client when you set up the service call:
InstanceContext instanceContext = new InstanceContext(new CallbackHandler());
MyContractClient client = new MyContractClient(instanceContext);
InputMessage msg = new InputMessage();
client.DoSomething(msg);
このサービスでは、おそらく次のようなコードがあります。
class MyContractImplementation : IMyContract
{
public void DoSomeThing(MyMessage Message)
{
string responseMessage;
try
{
//Write to the database
responseMessage = "The database call was good!";
}
catch (Exception ex)
{
responseMessage = ex.Message;
}
Callback.ServiceResponse(responseMessage);
}
}
最初に気付いた重要な点の1つは、例外に注意することです。もし、あんたが:
例外を消費すると、エラーの警告は表示されません(ただし、コールバックは発生します)
未処理の例外をスローすると、サービスは終了し、クライアントはコールバックさえも取得しません。
これは、オプション1と比較した場合のこのメソッドの大きな欠点の1つです。オプション1は、未処理の例外がスローされたときに例外を返します。
デフォルトでは、例外がスローされない限り、(サービス メソッドで void 戻り値の型が指定されていても) サービスはクライアントに "OK" メッセージを返します。クライアントは、このメッセージを受信するまで待機してから、自分の人生を続けます。
したがって、質問に基づいて、デフォルトで必要な動作が得られます。
あなたがそれを望まないのであれば、私はウィスクに同意し、あなたの操作を一方向としてマークします (あなたの操作契約の設定)。
幸運を!
これを行う方法は 2 つあります。wcf 呼び出しから成功または失敗を示す値を返すか、成功を想定してコールバックを使用してクライアントに問題があるかどうかを伝えます。
私の好みは、双方向サービスで一方向のサービス呼び出しを使用し、サービスのコールバック コントラクトを使用してクライアントに障害を通知することです。こことここにコールバック コントラクトの適切な説明があります。
2 番目のパスに従うと、より優れた非同期アーキテクチャが得られると思いますが、単純なアプリケーションの場合は、成功または失敗を返すだけの方が簡単な場合があります。
正しく答えるには、質問をもう少し詳しく説明する必要があると思います。主に、現在使用しているバインディングのタイプは何ですか?
信頼性をサポートするバインディングを使用していて、クライアント側から、そのサーバーが実際にメッセージを受信したことを確認したい場合は、信頼性をオンにするだけで問題ありません。これをオンにすると、WCF は内部で自動的に、会話の両側に「わかりましたか?」と言うようにします。「わかった。わかった?」"わかった。"