2017-02-08 6 views
1

私はCallbackのふるまいでwsDualHttpBindingを実装しました。これは問題なく正常に動作します。クラスライブラリからWCFコールバックを呼び出すにはどうすればよいですか?

マイサービスコンフィグ

<behaviors> 
    <serviceBehaviors> 
    <behavior name="default"> 
     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="false"/> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 
<services> 
    <service name="MyServiceNamespace" behaviorConfiguration="default"> 
    <endpoint address="" binding="wsDualHttpBinding" contract="MyServiceCoontract" /> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 
</services> 
<protocolMapping> 
     <add binding="basicHttpsBinding" scheme="https"/> 
</protocolMapping> 
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/> 

マイサービス契約

[ServiceContract(CallbackContract=typeof(IMQServiceCallBack))] 
public interface IMQService 
{ 
    [OperationContract] 
    void PublishMessage(Message message); 
} 

public interface IMQServiceCallBack 
{ 
    [OperationContract(IsOneWay = true)] 
    void MessageAcked(string fileName); 

    [OperationContract(IsOneWay = true)] 
    void MessageNacked(string fileName); 
} 

マイサービス

public class MQService : IMQService 
{ 
    public IMQServiceCallBack CallBack 
    { 
     get 
     { 
      return OperationContext.Current.GetCallbackChannel<IMQServiceCallBack>(); 
     } 
    } 

    public void PublishMessage(Common.Message message) 
    { 
     var mqManager = MQManager.GetInstance(); 
     mqManager.PublishMessage(message); 
     CallBack.MessageAcked(message.FileName); 
    } 
} 

コールバックは私の実装ごとに、原則的に正常に動作します。しかし、私のコールバック呼び出しは、私のサービスクラスからではなく、クラスライブラリから来るべきです。

mqManager.PublishMessage(message)をクラスライブラリに使用してメッセージを公開すると、そのライブラリに肯定応答用のコールバックが既に存在します。私MQManagerクラスだから、

void channel_BasicAcks() 
{ 
    //need to invoke service call back from here 
} 

コールバックは、基本的にchannel_BasicAcks()コールバッククラスライブラリで呼び出されたとき、私は順番にサービスが私のクライアントをコールバックしなければならないように、このライブラリーを消費し、私のサービスを警告する必要があります。私はクラスライブラリのコールバックメソッドから私のサービスを警告する方法の中間ステップに立ち往生しています。ここの方向は私を助けるだろう。

答えて

0

短い答え

それを行うには良い方法はありません。

長い答え

基本的な問題は、あなただけOperationContext.Currentを使用して、WCFサービスを実行しているスレッド内からのコールバックチャネルにアクセスできることです。

、あなたのサービスシングルトンを作り、あなたのサービスインスタンス内の静的メンバー内のすべてのコールバックを格納し、クライアントがコールバックを受信するために呼び出す必要があります 登録サービス操作のいくつかの種類を提供することを含む、かなり汚い回避策はあり

何か

[ServiceContract(CallbackContract=typeof(IMQServiceCallBack))] 
public interface IMQService 
{ 
    [OperationContract] 
    void PublishMessage(Message message); 

    [OperationContract] 
    void Register(); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class MQService : IMQService 
{ 
    public static List<CallBack> callbacks; 

    public void Register() 
    { 
     callbacks.Add(OperationContext.Current.GetCallbackChannel<IMQServiceCallBack>()); 
    } 
} 

のようにあなたは、あなたのアプリケーションドメインの別の部分からリモートコールバックを呼び出すことができます。これは非常に多くのレベルではかなり恐ろしいです

var service = new MQService(); 
service.callbacks.ForEach((c) => { 
    c.MessageAcked(someMessage) 
}); 

のようなものは、正直に言うと、私は最も基本的な用途以外のためにそれをお勧めしません。

+0

はい、私は方法がないと思った。しかし、何もないと思ったときに私は敗北しました。SOの方法があります:)私はコールバックインターフェイスをクラスライブラリに移動し、そのライブラリに自分のOperationContextを渡したので、ライブラリ自体がクライアントに対してコールバックを呼び出すことができます – techspider

関連する問題