用WCF Behavior Extension預先處理request

WCF framework有很多可以設定的功能,包括throttling,concurrency models,支援不同的protocols,pipleline。

WCF server跟client 接收response或是送出request都會經過一組pipleline。

Client 的object 透過proxy class 會被包成WCF message,message 經過channel stack 由指定的protocol encode 之後 transfer。

Server 收到request 之後,由channel stack decode request,再交給dispatch runtime負責dispatch request給指定的operation。

WCF pipleline
(圖片取自MSDN)

WCF提供了 pipleline的extension。

在dispatcher 接到 request 之後或是送出 response 之前,在 channel 收到message 之後,都可以customize extension function 做些 inspect parameter,log之類的事情。

WCF pipleline
(圖片取自MSDN)

我想在dispatcher裡,做一個inspector去throttle特定的request。

雖然WCF已經提供了throttling功能,是 by endpoint來 configure。我需要的功能是依據特定的request的header來throttling。

我用IDispatchMessageInspector interface。

public class DispatchMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
// Get operation and header

//Throttling Here

return null;

}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{

}

在web.config中,設定BehaviorExtension

 <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyService.ServiceImplementation.Helper_Behavior">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true"/> 
          <messageBehaviorExtension />
        </behavior> 
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add
          name="messageBehaviorExtension"
          type="MyService.MessageBehaviorExtension, MyService, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
        />
      </behaviorExtensions>
    </extensions>

新定義的 BehaviorExtension 透過 implement WCF 的 BehaviorExtensionElement 跟 IServiceBehavior,把 DispatchMessageInspector 掛到指定的 endpoint 上。

 public class MessageBehaviorExtension : BehaviorExtensionElement, IServiceBehavior
    {

        public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
            {
                ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
                if (channelDispatcher != null)
                {
                    foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                    {
                        DispatchMessageInspector inspector = new DispatchMessageInspector();
                        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
                    }
                }
            }
        }

        public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            
        }

        public override Type BehaviorType
        {
            get { return this.GetType(); }
        }

        protected override object CreateBehavior()
        {
            return this;
        }
    }

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s