根据拦截和返回值自动重试客户端WCF调用

2024-05-22

是否可以拦截 WCF 调用的结果并重试该操作?

例如,操作的返回值可能包含状态代码,指示我传递到原始调用的会话令牌已过期。在这种情况下,我可以检索新的会话令牌并使用新的会话令牌重试调用。

是否可以通过使用 WCF 拦截返回值、检查它,然后以对操作调用者完全透明的方式重试调用来执行此重试操作?

我已经知道如何检查通话IParameterInspector,但此时没有内置方法可以重试调用。

我正在寻找一种使用纯拦截的方法,以便它对客户端完全透明。


假设您希望这发生在客户端,那么您可以使用IClientMessageInspector http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.aspx- 如果你想在服务器端实现这个,你可以创建一个IDispatchMessageInspector http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.aspx.

通过实施IClientMessageInspector您将检查结果AfterReceiveReply event http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.afterreceivereply.aspx如果需要重试,那么您可以启动重试...当调用返回时,您只需“覆盖”使您用新的重试的结果...这样操作调用者甚至不会注意到任何事情(只是通话有时需要更长的时间)。

尽管您在实现重试功能时必须小心(需要适当处理可能的重入问题)。

对于一些示例代码(没有重试本身),请参阅http://weblogs.asp.net/paolopia/archive/2007/08/23/writing-a-wcf-message-inspector.aspx http://weblogs.asp.net/paolopia/archive/2007/08/23/writing-a-wcf-message-inspector.aspx

编辑 - 根据评论:

如何实现重试操作取决于几个方面。

基本上,您需要将调用关联到请求消息,并将请求消息关联到重播消息。

您可以做到这一点的一种方法是实施IClientMessageFormatter.SerializeRequest http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageformatter.serializerequest.aspx OR IParameterInspector http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iparameterinspector.aspx- 这将允许您记录调用了哪个方法以及哪些参数以及框架为其创建的消息对象。

通过实施IClientMessageInspector.BeforeSendRequest http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.beforesendrequest.aspx您可以分配一个唯一的correlationState这反过来又允许您在您的实现中关联回复消息IClientMessageInspector.AfterReceiveReply http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.afterreceivereply.aspx因为框架将使用它作为第二个参数来调用您的实现。

从那里您可以使用反射重试调用(自从您在您的文件中记录了类型、方法和参数以来,所有需要的信息都可用)IClientMessageFormatter and/or IParameterInspector实现)并用新回复覆盖回复消息。

另一个(也许更容易)的选择是实现一个自定义的 WCF 客户端类并向调用者提供该类...这使您可以远离不同检查器等的混乱,并对任何调用的操作提供更直接的控制。

编辑2 - 根据评论:

当实施一个IClientMessageInspector你还必须实施IEndpointBehavior http://msdn.microsoft.com/en-us/library/system.servicemodel.description.iendpointbehavior.aspx这又具有一个方法ApplyClientBehavior http://msdn.microsoft.com/en-us/library/system.servicemodel.description.iendpointbehavior.applyclientbehavior.aspx它由 WCF 运行时调用来添加您的IClientMessageInspector。在该方法中,您实例化您的实现,该实现在构造函数中采用一个参数,而该参数又是endpoint.Contract.ContractType http://msdn.microsoft.com/en-us/library/system.servicemodel.description.contractdescription.contracttype.aspx or clientRuntime.ContractClientType http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.clientruntime.aspx。您将此类型存储在检查器实例中...有关如何编码的提示,请参见示例http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/19500d14-78b7-4356-b817-fcc9abc2afcf/ http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/19500d14-78b7-4356-b817-fcc9abc2afcf/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据拦截和返回值自动重试客户端WCF调用 的相关文章