我已实施wsDualHttpBinding
行为Callback
。这样可以正常运行。
我的服务配置
<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 :(得分: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)
});
说实话,这在很多层面上非常糟糕,除了最基本的应用之外,我不会推荐它。