【转】WCF设置拦截器捕捉到request和reply消息

原文:https://www.cnblogs.com/yanglang/p/7063743.html

我们需要拦截消息,并把消息打印出来,那么我们就需要一个拦截器,叫做MessageInspector,WCF为我们提供了两种拦截器:

客户端拦截器 IClientMessageInspector

提供两个接口

BeforeSendRequest:向服务器发送请求前执行

AfterReceiveReply:接收到服务器的回复消息后执行

服务端拦截器 IDispatchMessageInspector

他也提供两个接口

AfterReceiveRequest:invoke操作之前执行

BeforeSendReply:发送reply给客户端之前执行

在这里我们在服务端设置个拦截器,然后打印出请求和回复的消息,所以我们使用IDispatchMessageInspector这个接口

实现接口 MessageInspector.cs

 1 namespace Cookiezhi.WcfStudy.Hosting.MessageInspect
 2 {
 3     public class MessageInspector : IDispatchMessageInspector
 4     {
 5         public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
 6         {
 7             Console.WriteLine(request.ToString());
 8             return DateTime.Now;
 9         }
10 
11         public void BeforeSendReply(ref Message reply, object correlationState)
12         {
13             Console.WriteLine(reply.ToString());
14             DateTime requestTime = (DateTime)correlationState;
15 
16             var duration = DateTime.Now - requestTime;
17             Console.WriteLine(duration);
18         }
19     }
20 }

其中AfterReceiveRequest先执行,然后去执行远程方法,然后再执行BeforeSendReply,所以在这里加了一个操作计时的功能(可选)。

然后我们要将这个拦截器给寄宿在我们的终结点上,所以需要定义一个终结点行为(EndpointBehavior),并寄宿在服务上。

MessageInspectorBehavior.cs,在ApplyDispatchBehavior方法实现中将我们新建的Inspector实例加到dispatcher的MessageInspectors中

 1 namespace Cookiezhi.WcfStudy.Hosting.MessageInspect
 2 {
 3     public class MessageInspectorBehavior : IEndpointBehavior
 4     {
 5         public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
 6         {
 7         }
 8 
 9         public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
10         {
11         }
12 
13         public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
14         {
15             endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MessageInspector());
16 } 17 18 public void Validate(ServiceEndpoint endpoint) 19 { 20 } 21 } 22 }

最后创建一个配置元素用于在配置文件中给终结点配置这个行为.

 1 namespace Cookiezhi.WcfStudy.Hosting.MessageInspect
 2 {
 3     public class MessageInspectorExtensionElement : BehaviorExtensionElement
 4     {
 5         public override Type BehaviorType
 6         {
 7             get { return typeof(MessageInspectorBehavior); }
 8         }
 9 
10         protected override object CreateBehavior()
11         {
12             return new MessageInspectorBehavior();
13         }
14     }
15 }

下面就是配置这个行为了

App.config

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3 
 4   <system.serviceModel>
 5     <extensions>
 6       <behaviorExtensions>
 7         <add name="messageInspector" type="Cookiezhi.WcfStudy.Hosting.MessageInspect.MessageInspectorExtensionElement, Cookiezhi.WcfStudy.Hosting"/>
 8       </behaviorExtensions>
 9     </extensions>
10     
11     <behaviors>
12       <serviceBehaviors>
13         <behavior name="mexBehavior">
14           <serviceMetadata httpGetEnabled="true"/>
15         </behavior>
16       </serviceBehaviors>
17       <endpointBehaviors>
18         <behavior name="messageInspector">
19           <messageInspector />
20         </behavior>
21       </endpointBehaviors>
22     </behaviors>
23     
24     <services>
25       <service name="Cookiezhi.WcfStudy.Services.ComplexCalculateService" behaviorConfiguration="mexBehavior">
26         <endpoint address="" binding="basicHttpBinding" contract="Cookiezhi.WcfStudy.Contracts.ServiceContracts.IComplexCalculate" behaviorConfiguration="messageInspector" />
27         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
28         <host>
29           <baseAddresses>
30             <add baseAddress="http://127.0.0.1:9999/complexcalcservice"/>
31           </baseAddresses>
32         </host>
33       </service>
34     </services>
35     
36   </system.serviceModel>
37   
38     <startup> 
39         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
40     </startup>
41 </configuration>

客户端的代码不要做出任何的改变,

然后我们尝试一下

Great! 我们成功的拦截了请求,并将请求信息打印了出来。

总结,有了这个拦截器,我们可以做很多的事情,比如修改消息头和消息体,计算消息的大小(流量统计),统计服务调用的次数和平均时间,客户端情况,等等。

posted @ 2018-03-09 16:15  Perfectionist  阅读(313)  评论(0编辑  收藏  举报