私にはアイデアがありますが、それを実装するための支援が必要です。
WCFは、契約でデリゲートをサポートしていません。代わりに、面倒なコールバックコントラクトメカニズムがあり、この制限を克服する方法を探しています。
IDataContractSurrogateコントラクト内の各デリゲートを、リモートエンドポイントにシリアル化されるトークンに置き換えるためにを使用することを考えました。そこで、トークンは生成されたデリゲートに逆シリアル化されます。この生成されたデリゲートは、(デリゲートが呼び出された)すべての引数をカプセル化する汎用コールバックメッセージを送信します。
ジェネリックコールバックメッセージは最初のエンドポイントに到達し、そこで元のデリゲートが引数を使用して呼び出されます。
目的の(簡略化された)シーケンスは次のとおりです。
- AはB-proxy.Foo(callback)を呼び出します
- コールバックはDelegateSurrogateを介してシリアル化されます。
- DelegateSurrogateは、デリゲートを専用のデリゲートストレージに格納し、トークンに置き換えます
- メッセージはBのエンドポイントに到着します
- トークンはDelegateSurrogateを介して逆シリアル化されます
- DelegateSurrogateは、生成されたデリゲートを構築します
- B.Foo(generatedCallback)が呼び出されます
- 後で、BはgeneratedCallback(args)を呼び出しています
- generateCallback(args)は、Aのエンドポイントで専用のジェネリックコントラクトを呼び出します:CallbackContract-proxy.GenericCallback(args)
- CallbackContract.GenericCallback(args)がAのエンドポイントで呼び出されます
- 元のコールバックがストレージから取得され、呼び出されます:callback(args)
以前にサービスバス(NServiceBus)を使用してこれを実装しましたが、このアイデアをWCFに適合させたいので、苦労しています。手順3、6、9、および11を実装する方法を知っています。WCFのすべて(特に代理部分)を配線する方法はまだわかりません。
それだけです-私の質問が理にかなっていて、ここでの集合的な知恵が私がこれを構築するのを助けることができることを願っています。
これが私の希望するソリューションの使用例です。
// client side
remoteSvc.GetEmployeeById(17, emp =>
{
employees.Add(emp);
logger.log("Result received");
});
// server side
public void GetEmployeeById(int id, Action<Employee> callback)
{
var emp = getEmpFromDb(id);
callback(emp);
}