2012-03-29 69 views
2

コールバックを使用してWCFサービスを設計していますが、コールバック関数の実装が呼び出されることはありません。私は生成されたサービスプロキシについて混乱しています。だから助けてください。WCFコールバック実装関数が呼び出されない

ここでは、サーバー側でサービスインターフェイスIMyServiceとコールバックインターフェイスIMyServiceCallbackを定義し、サーバープロジェクトでIMyServiceも実装しました。サーバープロジェクトのほかに、確かに別のクライアントプロジェクトがあります。これにVSのサービスリファレンスを追加しました。そして私はクライアント側でIMyServiceCallbackインターフェイスを実装しました。ここで問題が発生します:私はそれをデバッグしているときに、関数はIMyServiceCallbackの実装に入ることはありません。もちろん、望む結果は決して出てこないのです。

これは私が混乱しているところです。クライアント側でサービス参照を追加すると、実際にはIMyService、IMyServiceCallback、IMyServiceChannelとクライアントプロキシクラスの3つのインタフェースがローカルで生成されました。 IMyServiceCallbackのローカル実装では、サービス側のIMyServiceCallbackインタフェースではなく、ローカルIMyServiceCallbackインタフェースを実装するようにクラスを宣言しました。これが問題だろうか?異なるプロジェクト(したがって異なる名前空間)の下でインタフェースが2つ宣言されるのはなぜですか?クライアントサイドインターフェイスを実装する理由は、サーバーサイドインターフェイスから実装した場合、サービスを呼び出そうとしたときに、「ChannelFactoryに提供されたInstanceContextにCallbackContractTypeエラーを実装していないUserObjectが含まれています。もう一つの混乱する部分は、IMyCallbackなどのコールバックインターフェイス名をIMyServiceCallbackの代わりに宣言するとサーバー側で生成されたクライアント側のインターフェイスはIMyServiceCallbackになります。これはサービスインターフェイスの名前に加えて接尾辞 "コールバック"。そして、この状況で私はまた、 "ChannelFactoryに提供されたInstanceContextにCallbackContractTypeエラーを実装していないUserObjectが含まれています"を得ました。

「サービス参照の追加」について誤解されていると思いますが、実装するインタフェースをどのように実装する必要がありますか。誰か助けてくれますか?ありがとう!

更新日:

何とか問題を解決しました。まず、2つの宣言がうまくいくことが望まれます。ローカルクライアントは、サービス参照を追加するときに生成されるローカルインタフェースを実装する必要があります。私の問題は、私もDataContractを定義したが、生成された参照ファイルにはそれがないということでした。これは、サービスプロジェクトのアセンブリを参照として追加したためです(この場合、サービス参照を追加するとDatacontractは生成されません)。またはDataMember属性が不足しています。しかし、とにかく、私は両方の部分を修正した後、機能は今働いている。

答えて

2

"サービス参照を追加"してプロキシを生成すると、サービス実装とは完全に分離されています。あなたが書いたことのないサービスを利用していて、サービスのソースコードにアクセスできない可能性があります。

クライアントコードでは、クライアントが生成したインターフェイスを使用する必要があります。サービスを変更する場合は、プロキシを再生成する必要があります。

これがあまりにも厄介で、常に両端を制御することがわかっている場合は、共通アセンブリ内でサービスインターフェイスを共有し、実行時にDuplexChannelFactory.CreateChannel()を使用してプロキシクラスを生成できます。

あなたの問題については、あなたがコールバックを正しく登録していないと仮定することができます。これはhereに記載されています。

+0

お返事ありがとうございます。元の投稿の更新について述べたように、私は今、ローカルインターフェースの宣言が望ましいことに気付きました。そして、私は "あなたが書いていないサービスを消費しているかもしれないし、サービスのソースコードにアクセスできない"という意味になります。私の問題は、クライアント側で誤って生成されていない1つのDataContract宣言にあったと思います。 – tete

0

公開する場合は、IMyServiceCallbackとIMyServiceを同じプロジェクトで実装する必要があります。 IMyServiceCallbackインターフェイスを実装する必要があります。

+0

感謝を。私は購読したいだけなので、IMyServiceCallbackだけを実装したのです。 – tete

0

コールバック命令が関数呼び出しに組み込まれているときに問題を修正しました。 私は、結果を返さないメソッドにコールバックを配置するのがうまくいくことを知りました。 しかし、コールバック命令が関数内に置かれたとき、私はタイムアウトの問題に遭遇しました。

私が呼び出された関数内でのBackgroundWorkerのスレッドを使用して、それを解決:ご返信用

public static IMyServiceCallback Callback; 
. 
. 
. 

     TaskStateData taskStateData = GetSomeData(); 

     BackgroundWorker backgroundWorker = new BackgroundWorker(); 

     backgroundWorker.DoWork += (se, ev) => 
      { 
       Tuple<OperationContext, TaskStateData> data = ev.Argument as Tuple<OperationContext, TaskStateData>; 
       var operationContext = data.Item1; 

       if (operationContext != null) 
       { 
        Callback = operationContext.GetCallbackChannel<IMyServiceCallback>(); 
        Callback.OnCallBack(); 
       } 
      }; 

     Tuple<OperationContext, TaskStateData> payload = new Tuple<OperationContext, TaskStateData>(OperationContext.Current, taskStateData); 
     backgroundWorker.RunWorkerAsync(payload); 
関連する問題