简体   繁体   English

WCF双工服务是否可以在该服务尝试调用之前确定客户端的回调通道是否已实现特定方法?

[英]Can a WCF duplex service determine if the callback channel of a client has implemented a specific method before the service tries to call it?

I've implemented a WCF duplex service IMyDuplexService with a callback contract IMyCallbackContract. 我已经实现了带有回调协定IMyCallbackContract的WCF双工服务IMyDuplexService。

It was deployed successfully; 它已成功部署; clients can subscribe to the service and the service can call methods on the client using the callback channel without issues. 客户端可以订阅该服务,并且该服务可以使用回调通道在客户端上调用方法而不会出现问题。

I've since added a new method to the callback contract and it can also be deployed successfully; 从那以后,我在回调协定中添加了新方法,它也可以成功部署。 old clients can still subscribe to the service as well as new clients, the service can call the old methods on both the old and new clients using the callback channel, as well as new methods on the new clients without issues. 旧客户端和新客户端仍然可以订阅该服务,该服务可以使用回调通道在旧客户端和新客户端上调用旧方法,也可以在新客户端上调用新方法而不会出现问题。

Is there any way to determine if a specific client is an old or new client without having to implement this "versioning" logic myself? 有什么方法可以确定特定客户端是旧客户端还是新客户端,而不必自己实现此“版本”逻辑?

For example, if the client was implemented using the older version of the callback contract and the service tries to call the new method on the old client, the following exception is thrown: System.ServiceModel.ActionNotSupportedException occurred HResult=-2146233087 Message=The message with Action 'http://domain/virtual_directory/IMyDuplexService/MyNewMethod' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, eg Message, Transport, None). Source=mscorlib StackTrace: Server stack trace: at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter) at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at MyService.IMyCallbackContract.MyNewMethod() 例如,如果使用较旧版本的回调协定实现了客户端,并且服务尝试在旧客户端上调用新方法,则会引发以下异常: System.ServiceModel.ActionNotSupportedException occurred HResult=-2146233087 Message=The message with Action 'http://domain/virtual_directory/IMyDuplexService/MyNewMethod' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, eg Message, Transport, None). Source=mscorlib StackTrace: Server stack trace: at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter) at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at MyService.IMyCallbackContract.MyNewMethod() System.ServiceModel.ActionNotSupportedException occurred HResult=-2146233087 Message=The message with Action 'http://domain/virtual_directory/IMyDuplexService/MyNewMethod' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, eg Message, Transport, None). Source=mscorlib StackTrace: Server stack trace: at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter) at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at MyService.IMyCallbackContract.MyNewMethod()

Is it possible for the service to determine if the client supports the new method before trying to call it? 服务是否有可能在尝试调用新方法之前确定客户端是否支持新方法?

I tried to use reflection but the following doesn't return null on an older client: clientCallbackChannelInstance.GetType().GetMethod("MyNewMethod") 我尝试使用反射,但是以下内容在较旧的客户端上不会返回nullclientCallbackChannelInstance.GetType().GetMethod("MyNewMethod")

Is implementing my own "versioning" scheme the only way? 是实现我自己的“版本”方案的唯一方法吗?

PS I don't need help architecting or implementing my own versioning scheme. PS我不需要架构或实施自己的版本控制方案的帮助。 I just don't want to "reinvent the wheel." 我只是不想“重新发明轮子”。 ;) ;)

Thank you. 谢谢。

Would wrapping the method call for the new method in a try catch block suffice? 在try catch块中包装该方法是否需要新方法? The exception caught would be the specific type you are seeing. 捕获的异常将是您所看到的特定类型。 Example: 例:

try
{
    clientCallbackChannelInstance.MyNewMethod();
}
catch (System.ServiceModel.ActionNotSupportedException exception) 
{
    //new method is not supported if code reaches here
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM