vendredi 18 août 2017

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.

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, e.g. 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")

Is implementing my own "versioning" scheme the only way?

P.S. I don't need help architecting or implementing my own versioning scheme. I just don't want to "reinvent the wheel." ;)

Thank you.





Aucun commentaire:

Enregistrer un commentaire