2017-02-08 1 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

예, 나는 방법이 없다고 생각했습니다. 그러나 방법이 없다고 생각할 때 나는 여전히 패배했다. 그래서 나는 콜백 인터페이스를 클래스 라이브러리로 옮겼고, 라이브러리에 내 OperationContext를 전달하여 라이브러리 자체가 클라이언트를 위해 콜백을 호출 할 수 있도록했다. – techspider

관련 문제