Request handling on service

OperationContext

DispatchRuntime

EndpointDispatcher

DispatcherBuilder

ChannelDispatcher

ChannelHandler

IChannelListener

MessageRpc

ServiceHost

ServiceThrottle

InstanceContextProvider

Other

Extensible interfaces

 

 

我突然有个想法,希望能够找出Server端的OperationContext是在何时何处被初始化,这样我就可以准确判断出合适能够访问OperationContext.Current。但是,随着研究的深入,我似乎发现的一条serverextension points的主线。本人写作水平有限,希望大家能看明白。J

当调用ServiceHost.Open的时候,会发生一系列初始化操作,包括DispatchRuntimeEndpointDispatcher等等。这些都是通过DispatcherBuilder来做到的。

首先看看DispatcherBuilder.InitializeServiceHost。这个方法处理了许多逻辑,主要包括:

1.   根据ListenUriendpoint进行分组,相同ListenUriendpoint会使用同一个ChannelDispatcher

2.   处理IServiceBehaviorIContractBehaviorIEndpointBehavior以及IOperationBehavior

3.   根据Channel Type创建IChannelListener

4.   使用上一步创建的IChannelListener创建ChannelDispatcher;简单地说,ChannelDispatcher 对象将在特定 URI(称为侦听 URI)的 IChannelListener 与服务的实例相关联。 每个 ServiceHost 对象都可以拥有多个 ChannelDispatcher 对象,这多个对象每个都可与该服务的不同侦听器和侦听 URI 相关联。 当消息到达时,ChannelDispatcher查询每个相关的 EndpointDispatcher 对象以确定终结点是否可以接受消息,以及将该消息传递到可以接受消息的终结点。 当消息的目标地址与 AddressFilter 属性相匹配并且消息操作与 ContractFilter 属性相匹配时,EndpointDispatcher 对象负责处理来自ChannelDispatcher的消息。控制通道会话的生存期和行为的所有属性都可以在ChannelDispatcher对象上检查或修改。 除了 EndpointDispatcher 之外,这些属性还包括自定义 IChannelInitializer 对象、IChannelListenerServiceHost 以及相关的 InstanceContext

5.   为每一个endpoint创建EndpointDispatcher,并将其添加到对应的ChannelDispatcher中;

这些完成以后,IChannelListener开始监听注册进去的地址,关于这一步是如何做到的可以继续深入研究TransportManager

在这里,我假设现在使用的netTcpBinding,那么对应的ChannelListenerTcpDuplexChannelListener。这个类里面使用了一个类,InputQueueChannelAcceptor,当有channel需要建立时,这个类被用来建立channel同时它的方法会被调用以便从下层取出数据。这样,server端就开始正常运行了。

 

前面提到了ChannelDispatcher的创建过程,但是对于它的作用只是简单的一个描述,下面开始详细介绍。

ChannelDispatcher中,一个ListenHandler会被创建出来,这个类包含了前面提到的ChannelListener。当收到一个请求以后,ListenHandler.Dispatch会被调用;然后ChannelHandler会被创建,同时将其注册,从此它将替代ListenHandler来处理接收到的request

ChannelHandler提供了一系列callback,当有request进来,某些方法会被调用用来处理。例如OnAsyncReceiveComplete,当一个request异步接收完成时,它会被调用。

下面是一个大体的调用过程。

OnAsyncReceiveComplete

AsyncMessagePump

HandleRequest

TryAcquireCallThrottle

ServiceThrottle.TryAcquireCallThrottle

TryRetrievingInstanceContext

GetSessionChannel

InitializeServiceChannel

InstanceContextProvider.GetExistingInstanceContext

TryAcquireThrottle

ServiceThrottle.AcquireInstanceContextAndDynamic

DispatchAndReleasePump

dispatchRuntime.GetOperation

Init OperationContext

Create MessageRpc

ImmutableDispatchRuntime.Dispatch

MessageRpc.Process

这就是一个request被处理的大体过程,每个列出来的方法或许都可以是一篇文章,这里不会详细介绍每个细节,而是集中在MessageRpc.Process以及内部的处理。剩下的内容或许以后再慢慢深入研究吧。

以下是MessageRpc.Process的大体过程。

ImmutableDispatchRuntime.ProcessMsg1

ImmutableDispatchRuntime.ProcessMsg11

Check Request Msg

ConcurrencyBehavior.IsConcurrency

AuthenticationBehavior.Authenticate

ServiceAuthenticationManager.Authenticate

AuthorizationBehavior.Authorize

ServiceAuthorizationManager.Authorize

InstanceBehavior.EnsureInstanceContext

AcquireDynamicInstanceContext

ImmutableDispatchRuntime.ProcessMsg2

AfterReceiveRequest

IDispatchMessageInspector.AfterReceiveRequest

ConcurrencyBehavior.LockInstance

ImmutableDispatchRuntime.ProcessMsg3

TransactionBehavior.ResolveTransaction

ImmutableDispatchRuntime.ProcessMsg31

ImmutableDispatchRuntime.ProcessMsg4

ThreadBehavior.BindThread

ImmutableDispatchRuntime.ProcessMsg41

ChannelHandler.Register

InstanceContext.GetServiceInstance

IInstanceProvider.GetInstance

ImmutableDispatchRuntime.ProcessMsg5

DispatchOperationRuntime.InvokeBegin

DispatchOperationRuntime.InitializeCallContextCore

ICallContextInitializer.BeforeInvoke

DispatchOperationRuntime.DeserializeInputs

IDispatchMessageFormatter.DeserializeRequest

DispatchOperationRuntime.InspectInputs

IParameterInspector.BeforeCall

DispatchOperationRuntime.ValidateMustUnderstand

SecurityImpersonationBehavior.StartImpersonation

SecurityImpersonationBehavior.SetCurrentThreadPrinciple

IOperationInvoker.Invoke (Sync)

IOperationInvoker.InvokeBegin (Async)

SecurityImpersonationBehavior.StopImpersonation

DispatchOperationRuntime.InspectOutputs (Sync)

IParameterInspector.AfterCall

DispatchOperationRuntime.SerializeOutputs (Sync)

IDispatchMessageFormatter.SerializeReply

DispatchOperationRuntime.UninitializeCallContext (Sync)

ICallContextInitializer.AfterInvoke

ImmutableDispatchRuntime.ProcessMsg6 (Async)

ThreadBehavior.BindEndThread

ImmutableDispatchRuntime.ProcessMsg7

DispatchOperationRuntime.InvokeEnd

Same like Sync way

ImmutableDispatchRuntime.ProcessMsg8 (如果是Sync,直接从5进入8)

ImmutableDispatchRuntime.PrepareReply

ImmutableDispatchRuntime.PrepareAndAddressReply

ImmutableDispatchRuntime.BeforeSendReply

IDispatchMessageInspectors.BeforeSendReply

ImmutableDispatchRuntime.ProcessMsg9

ImmutableDispatchRuntime.Reply

ImmutableDispatchRuntime.ProcessMsgCleanup

OperationContext.FireOperationComplete

InstanceBehavior.ReleaseServiceIntance

IInstanceProvider.ReleaseInstance

ConcurrencyBehavior.UnlockInstance

ServiceThrottle.DeactivateInstanceContext

一口气看下来,可能会觉得不那么好理解,其实每个ProcessMsg方法都是request处理过程中的一个步骤,下面会简单阐述每个步骤做了些什么。黄色背景代表了常见的扩展点。

ProcessMsg1,主要作用是对message进行验证和授权,另外它还会根据concurrency的设置对InstanceContext进行一些处理;

ProcessMsg2,除了提供了一个扩展点以外,它会根据concurrencylock当前的InstanceContext

ProcessMsg3,主要是用在transaction中,这里不做介绍;

ProcessMsg4,暂时没有明白BindThread的作用,在这一步它会获取service instance

ProcessMsg5,真正开始处理request

ProcessMsg6ProcessMsg7,采用Async方式时才会调用;

ProcessMsg8,对reply进行处理;

ProcessMsg9,发出reply

ProcessMsgCleanup,整个request处理完以后,释放一些资源,例如service instanceinstance context

这篇文章只涉及了request的处理,还有一些问题没有解决:

1.   ChannelListener如何监听端口;

2.   Request收到以后如何分发到不同的endpoint

3.   ProcessMsg4中,ThreadBehavior.BindThread的作用;

      Update: 经过进一步研究,我发现BindThread实际上是在当前thread的SynchronizationContext上继续处理request message。同时,这个SynchronizationContext是从EndpointDispatcher.DispatchRuntime获得。通过这些,我认为service operation在被调用之前,同时只有一个thread会处理request;operation在哪个thread上调用,取决于它是sync还是async。

4.   最后,我们在config或通过其他方式进行配置时,是如何影响到后面的处理。

 

转载于:https://www.cnblogs.com/yedafeng/archive/2011/08/06/2129336.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值