您的位置:首页 > 其它

深入理解WCF系统体系(之二:WCF客户端如何构建?(下))

2012-04-11 22:35 597 查看
前一节介绍了WCF客户端构建的过程,其间又说明了WCF框架中核心ClientRuntime对象建立过程,以及客户端所采用的ClientMessageInspectors、ClientMessageFormatter、ClientOperationSelector等等基础。

本节目录:

1、RealProxy建立的过程
2、TransparentProxy建立的过程
3、服务调用过程。
4、总结

1、RealProxy建立的过程

通过之前的介绍,大家都应该有个共识:客户端通过透明代理建立对应的实际代理对服务进行调用,而在WCF在实际代理对象类型为ServiceChannelProxy。实际代理对象ServiceChannelProxy的建立又是通过它的构造函数完成。先来看看它的构造函数:

internal ServiceChannelProxy(Type interfaceType, Type proxiedType, MessageDirection direction, ServiceChannel serviceChannel) : base(proxiedType)
{
if (!MessageDirectionHelper.IsDefined(direction))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("direction"));
}
this.interfaceType = interfaceType;
this.proxiedType = proxiedType;
this.serviceChannel = serviceChannel;
this.proxyRuntime = serviceChannel.ClientRuntime.GetRuntime();
this.methodDataCache = new MethodDataCache();
this.objectWrapper = new MbrObject(this, proxiedType);
}

在WCF客户端中,ChannelFactory通过绑定创建; 在 ChannelFactory创建的过程中,会初始化ServiceEndpoint;通过ServiceEndpoint又创建ServiceChannelFactory;通过ServiceChannelFactory

创建ServiceChannel。而ServiceChannelProxy接口中的Type类型就是契约接口类型,MessageDirection

是一个枚举类型,有Input\Output两个枚举值。这些类型,真实代理对象就创建成功。

通过以上述过程,真实代理对象就创建成功。

2、TransparentProxy建立的过程

首先看看一下代码:

var instanceContext = new InstanceContext(new CalculatorCallback());
using (var channkeFactory = new DuplexChannelFactory<ICalculator>(instanceContext,"calculator"))
{
ICalculator proxy = channkeFactory.CreateChannel();
}

通过上节的分析,通过channkeFactory.CreateChannel()得到的proxy就是TransparentProxy对象。那么channkeFactory通过CreateChannel创建TransparentProxy对象都经过了那些过程呢。?要了解这个过程,还得从源
码分析得出:

public class DuplexChannelFactory<TChannel> : ChannelFactory<TChannel>
{
public TChannel CreateChannel(InstanceContext callbackInstance)
{
return this.CreateChannel(callbackInstance, base.CreateEndpointAddress(base.Endpoint), null);
}

public static TChannel CreateChannel(object callbackObject, string endpointConfigurationName)
{
return DuplexChannelFactory<TChannel>.CreateChannel(DuplexChannelFactory<TChannel>.GetInstanceContextForObject(callbackObject), endpointConfigurationName);
}

public override TChannel CreateChannel(EndpointAddress address, Uri via)
{
return this.CreateChannel(base.CallbackInstance, address, via);
}

public TChannel CreateChannel(InstanceContext callbackInstance, EndpointAddress address)
{
if (address == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
}
return this.CreateChannel(callbackInstance, address, address.Uri);
}

public static TChannel CreateChannel(InstanceContext callbackInstance, string endpointConfigurationName)
{
TChannel channel = new DuplexChannelFactory<TChannel>(callbackInstance, endpointConfigurationName).CreateChannel();
ChannelFactory<TChannel>.SetFactoryToAutoClose(channel);
return channel;
}

public static TChannel CreateChannel(object callbackObject, Binding binding, EndpointAddress endpointAddress)
{
return DuplexChannelFactory<TChannel>.CreateChannel(DuplexChannelFactory<TChannel>.GetInstanceContextForObject(callbackObject), binding, endpointAddress);
}

public static TChannel CreateChannel(InstanceContext callbackInstance, Binding binding, EndpointAddress endpointAddress)
{
TChannel channel = new DuplexChannelFactory<TChannel>(callbackInstance, binding, endpointAddress).CreateChannel();
ChannelFactory<TChannel>.SetFactoryToAutoClose(channel);
return channel;
}

public virtual TChannel CreateChannel(InstanceContext callbackInstance, EndpointAddress address, Uri via)
{
if (address == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
}
if ((base.CallbackType != null) && (callbackInstance == null))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxCreateDuplexChannelNoCallback1")));
}
if (callbackInstance == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxCreateDuplexChannelNoCallback")));
}
if (callbackInstance.UserObject == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxCreateDuplexChannelNoCallbackUserObject")));
}
if (!base.HasDuplexOperations())
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxCreateDuplexChannel1", new object[] { base.Endpoint.Contract.Name })));
}
Type c = callbackInstance.UserObject.GetType();
Type callbackContractType = base.Endpoint.Contract.CallbackContractType;
if ((callbackContractType != null) && !callbackContractType.IsAssignableFrom(c))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxCreateDuplexChannelBadCallbackUserObject", new object[] { callbackContractType })));
}
base.EnsureOpened();
TChannel local = (TChannel) base.ServiceChannelFactory.CreateChannel(typeof(TChannel), address, via);
IDuplexContextChannel channel = local as IDuplexContextChannel;
if (channel != null)
{
channel.CallbackInstance = callbackInstance;
}
return local;
}

public static TChannel CreateChannel(object callbackObject, Binding binding, EndpointAddress endpointAddress, Uri via)
{
return DuplexChannelFactory<TChannel>.CreateChannel(DuplexChannelFactory<TChannel>.GetInstanceContextForObject(callbackObject), binding, endpointAddress, via);
}

public static TChannel CreateChannel(InstanceContext callbackInstance, Binding binding, EndpointAddress endpointAddress, Uri via)
{
TChannel channel = new DuplexChannelFactory<TChannel>(callbackInstance, binding).CreateChannel(endpointAddress, via);
ChannelFactory<TChannel>.SetFactoryToAutoClose(channel);
return channel;
}

}

查看以上代码,我们发现DuplexChannelFactory<TChannel>类的CreateChannel()方法中没有不带参数的,那它通过CreateChannel()方法创建TransparentProxy时,肯定是调用了基类的方法。
接下去分析ChannelFactory<TChannel>的CreateChannel方法。代码如下:

public class ChannelFactory<TChannel> : ChannelFactory, IChannelFactory<TChannel>, IChannelFactory, ICommunicationObject
{
public TChannel CreateChannel()
{
return this.CreateChannel(base.CreateEndpointAddress(base.Endpoint), null);
}
public virtual TChannel CreateChannel(EndpointAddress address, Uri via)
{
TChannel local;
bool traceOpenAndClose = base.TraceOpenAndClose;
try
{
using (ServiceModelActivity activity = (DiagnosticUtility.ShouldUseActivity && base.TraceOpenAndClose) ? ServiceModelActivity.CreateBoundedActivity() : null)
{
if (DiagnosticUtility.ShouldUseActivity)
{
ServiceModelActivity.Start(activity, this.OpenActivityName, this.OpenActivityType);
base.TraceOpenAndClose = false;
}
if (address == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
}
if (base.HasDuplexOperations())
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxCreateNonDuplexChannel1", new object[] { base.Endpoint.Contract.Name })));
}
base.EnsureOpened();
local = (TChannel) this.ServiceChannelFactory.CreateChannel(typeof(TChannel), address, via);
}
}
finally
{
base.TraceOpenAndClose = traceOpenAndClose;
}
return local;
}
}

注意到这一句:

local = (TChannel) this.ServiceChannelFactory.CreateChannel(typeof(TChannel), address, via);

继续分析ServiceChannelFactory.CreateChannel(typeof(TChannel), address, via)的过程:

internal abstract class ServiceChannelFactory : ChannelFactoryBase
{
public object CreateChannel(Type channelType, EndpointAddress address, Uri via)
{
if (via == null)
{
via = this.ClientRuntime.Via;
if (via == null)
{
via = address.Uri;
}
}
ServiceChannel serviceChannel = this.CreateServiceChannel(address, via);
serviceChannel.Proxy = CreateProxy(channelType, channelType, MessageDirection.Input, serviceChannel);
serviceChannel.ClientRuntime.GetRuntime().InitializeChannel((IClientChannel) serviceChannel.Proxy);
OperationContext current = OperationContext.Current;
if ((current != null) && (current.InstanceContext != null))
{
current.InstanceContext.WmiChannels.Add((IChannel) serviceChannel.Proxy);
serviceChannel.WmiInstanceContext = current.InstanceContext;
}
return serviceChannel.Proxy;
}

[SecuritySafeCritical]
internal static object CreateProxy(Type interfaceType, Type proxiedType, MessageDirection direction, ServiceChannel serviceChannel)
{
if (!proxiedType.IsInterface)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxChannelFactoryTypeMustBeInterface")));
}
ServiceChannelProxy proxy = new ServiceChannelProxy(interfaceType, proxiedType, direction, serviceChannel);
return proxy.GetTransparentProxy();
}
}

CreateChannel方法返回的是serviceChannel.Proxy,而serviceChannel.Proxy又是

proxy.GetTransparentProxy()获取到的TransparentProxy.

3、服务调用过程。
WCF客户端对服务接口的调用最终通过RealProxy对象,也就是ServiceChannelProxy的Invoke方法来完成。
下面来看看Invoke方法。

public override IMessage Invoke(IMessage message)
{
IMessage message3;
try
{
IMethodCallMessage methodCall = message as IMethodCallMessage;
if (methodCall == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString("SFxExpectedIMethodCallMessage")));
}
MethodData methodData = this.GetMethodData(methodCall);
switch (methodData.MethodType)
{
case MethodType.Service:
return this.InvokeService(methodCall, methodData.Operation);

case MethodType.BeginService:
return this.InvokeBeginService(methodCall, methodData.Operation);

case MethodType.EndService:
return this.InvokeEndService(methodCall, methodData.Operation);

case MethodType.Channel:
return this.InvokeChannel(methodCall);

case MethodType.Object:
return this.InvokeObject(methodCall);

case MethodType.GetType:
return this.InvokeGetType(methodCall);
}
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Invalid proxy method type", new object[0])));
}
catch (Exception exception)
{
if (Fx.IsFatal(exception))
{
throw;
}
message3 = this.CreateReturnMessage(exception, message as IMethodCallMessage);
}
return message3;
}

3.1、MethodData的Service类型

MethodType.Service为同步调用方式;MethodType.BeginService、MethodType.EndService为异步方式。

首先看看MethodType.Service,它调用了ServiceChannelProxy的InvokeService方法完成。InvokeService方法定义如下:

private IMethodReturnMessage InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
{
object[] objArray;
object[] ins = operation.MapSyncInputs(methodCall, out objArray);
object ret = this.serviceChannel.Call(operation.Action, operation.IsOneWay, operation, ins, objArray);
object[] returnArgs = operation.MapSyncOutputs(methodCall, objArray, ref ret);
return this.CreateReturnMessage(ret, returnArgs, methodCall);
}

可以看出,在 InvokeService中,通过serviceChannel.Call返回调用结果,最有又通过ServerChannelProxy的

CreateReturnMessage方法返回Message。

ProxyOperationRuntime在WCF中也是很重要的对象。它的定义以及构造函数如下:

internal class ProxyOperationRuntime
{
// Fields
private string action;
private MethodInfo beginMethod;
private bool deserializeReply;
internal static readonly object[] EmptyArray = new object[0];
private ParameterInfo[] endOutParams;
private readonly IClientFaultFormatter faultFormatter;
private readonly IClientMessageFormatter formatter;
private ParameterInfo[] inParams;
private readonly bool isInitiating;
private readonly bool isOneWay;
private readonly bool isTerminating;
private readonly string name;
internal static readonly ParameterInfo[] NoParams = new ParameterInfo[0];
private ParameterInfo[] outParams;
private readonly IParameterInspector[] parameterInspectors;
private readonly ImmutableClientRuntime parent;
private string replyAction;
private ParameterInfo returnParam;
private bool serializeRequest;
private MethodInfo syncMethod;

// Methods
internal ProxyOperationRuntime(ClientOperation operation, ImmutableClientRuntime parent)
{
if (operation == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operation");
}
if (parent == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parent");
}
this.parent = parent;
this.formatter = operation.Formatter;
this.isInitiating = operation.IsInitiating;
this.isOneWay = operation.IsOneWay;
this.isTerminating = operation.IsTerminating;
this.name = operation.Name;
this.parameterInspectors = EmptyArray<IParameterInspector>.ToArray(operation.ParameterInspectors);
this.faultFormatter = operation.FaultFormatter;
this.serializeRequest = operation.SerializeRequest;
this.deserializeReply = operation.DeserializeReply;
this.action = operation.Action;
this.replyAction = operation.ReplyAction;
this.beginMethod = operation.BeginMethod;
this.syncMethod = operation.SyncMethod;
if (this.beginMethod != null)
{
this.inParams = ServiceReflector.GetInputParameters(this.beginMethod, true);
if (this.syncMethod != null)
{
this.outParams = ServiceReflector.GetOutputParameters(this.syncMethod, false);
}
else
{
this.outParams = NoParams;
}
this.endOutParams = ServiceReflector.GetOutputParameters(operation.EndMethod, true);
this.returnParam = operation.EndMethod.ReturnParameter;
}
else if (this.syncMethod != null)
{
this.inParams = ServiceReflector.GetInputParameters(this.syncMethod, false);
this.outParams = ServiceReflector.GetOutputParameters(this.syncMethod, false);
this.returnParam = this.syncMethod.ReturnParameter;
}
if ((this.formatter == null) && (this.serializeRequest || this.deserializeReply))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("ClientRuntimeRequiresFormatter0", new object[] { this.name })));
}
}

[SecurityCritical]
internal object[] MapSyncInputs(IMethodCallMessage methodCall, out object[] outs)
{
if (this.outParams.Length == 0)
{
outs = EmptyArray;
}
else
{
outs = new object[this.outParams.Length];
}
if (this.inParams.Length == 0)
{
return EmptyArray;
}
return methodCall.InArgs;
}

[SecurityCritical]
internal object[] MapSyncOutputs(IMethodCallMessage methodCall, object[] outs, ref object ret)
{
return this.MapOutputs(this.outParams, methodCall, outs, ref ret);
}

[SecurityCritical]
private object[] MapOutputs(ParameterInfo[] parameters, IMethodCallMessage methodCall, object[] outs, ref object ret)
{
if ((ret == null) && (this.returnParam != null))
{
ret = GetDefaultParameterValue(TypeLoader.GetParameterType(this.returnParam));
}
if (parameters.Length == 0)
{
return null;
}
object[] args = methodCall.Args;
for (int i = 0; i < parameters.Length; i++)
{
if (outs[i] == null)
{
args[parameters[i].Position] = GetDefaultParameterValue(TypeLoader.GetParameterType(parameters[i]));
}
else
{
args[parameters[i].Position] = outs[i];
}
}
return args;
}

/
****/
}

IMethodCallMessage的InArgs:获取未标记为 out 参数的参数数组;Args:获取传递给该方法的参数数组(MSDN中的定义)。

那么最核心的ServiceChannel的Call方法又做了什么事情呢。。?让我们看看它的定义:

internal object Call(string action, bool oneway, ProxyOperationRuntime operation, object[] ins, object[] outs)
{
return this.Call(action, oneway, operation, ins, outs, this.operationTimeout);
}

internal object Call(string action, bool oneway, ProxyOperationRuntime operation, object[] ins, object[] outs, TimeSpan timeout)
{
this.ThrowIfDisallowedInitializationUI();
this.ThrowIfIdleAborted(operation);
ProxyRpc rpc = new ProxyRpc(this, operation, action, ins, timeout);
using (rpc.Activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null)
{
if (DiagnosticUtility.ShouldUseActivity)
{
ServiceModelActivity.Start(rpc.Activity, SR.GetString("ActivityProcessAction", new object[] { action }), ActivityType.ProcessAction);
}
this.PrepareCall(operation, oneway, ref rpc);
if (!this.explicitlyOpened)
{
this.EnsureDisplayUI();
this.EnsureOpened(rpc.TimeoutHelper.RemainingTime());
}
else
{
this.ThrowIfOpening();
base.ThrowIfDisposedOrNotOpen();
}
try
{
ConcurrencyBehavior.UnlockInstanceBeforeCallout(OperationContext.Current);
if (oneway)
{
this.binder.Send(rpc.Request, rpc.TimeoutHelper.RemainingTime());
}
else
{
rpc.Reply = this.binder.Request(rpc.Request, rpc.TimeoutHelper.RemainingTime());
if (rpc.Reply == null)
{
base.ThrowIfFaulted();
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.GetString("SFxServerDidNotReply")));
}
}
}
finally
{
this.CompletedIOOperation();
CallOnceManager.SignalNextIfNonNull(this.autoOpenManager);
ConcurrencyBehavior.LockInstanceAfterCallout(OperationContext.Current);
}
rpc.OutputParameters = outs;
this.HandleReply(operation, ref rpc);
}
return rpc.ReturnValue;
}

上面代码中有至关重要的一段:

if (oneway)
{
this.binder.Send(rpc.Request, rpc.TimeoutHelper.RemainingTime());
}
else
{
rpc.Reply = this.binder.Request(rpc.Request, rpc.TimeoutHelper.RemainingTime());
}

通过是否单程oneway,来进行Send或者Request。那binder由是什么对象呢。。?

在ServiceChannel中,定义:

privatereadonly IChannelBinder binder。这点可以从RealProxy对象中可以看出来:



在本例中使用netTcpBinding绑定,所以binder为DuplexChannelBinder。不同的协议类型,
binder就不一样。以wsHttpBinding为例,它的binder为RequestChannelBinder。

DuplexChannelBinder的Send与Request定义如下:

public void Send(Message message, TimeSpan timeout)
{
this.channel.Send(message, timeout);
}

public Message Request(Message message, TimeSpan timeout)
{
SyncDuplexRequest request = null;
bool flag = false;
RequestReplyCorrelator.PrepareRequest(message);
lock (this.ThisLock)
{
if (!this.Pumping)
{
flag = true;
this.syncPumpEnabled = true;
}
if (!flag)
{
request = new SyncDuplexRequest(this);
}
this.RequestStarting(message, request);
}
if (flag)
{
TimeoutHelper helper = new TimeoutHelper(timeout);
UniqueId messageId = message.Headers.MessageId;
try
{
this.channel.Send(message, helper.RemainingTime());
if ((DiagnosticUtility.ShouldUseActivity && (ServiceModelActivity.Current != null)) && (ServiceModelActivity.Current.ActivityType == ActivityType.ProcessAction))
{
ServiceModelActivity.Current.Suspend();
}
while (true)
{
Message message2;
do
{
TimeSpan span = helper.RemainingTime();
if (!this.channel.TryReceive(span, out message2))
{
throw TraceUtility.ThrowHelperError(this.GetReceiveTimeoutException(timeout), message);
}
if (message2 == null)
{
this.AbortRequests();
return null;
}
if (message2.Headers.RelatesTo == messageId)
{
this.ThrowIfInvalidReplyIdentity(message2);
return message2;
}
}
while (this.HandleRequestAsReply(message2));
if (DiagnosticUtility.ShouldTraceInformation)
{
EndpointDispatcher endpointDispatcher = null;
if ((this.ChannelHandler != null) && (this.ChannelHandler.Channel != null))
{
endpointDispatcher = this.ChannelHandler.Channel.EndpointDispatcher;
}
TraceUtility.TraceDroppedMessage(message2, endpointDispatcher);
}
message2.Close();
}
}
finally
{
lock (this.ThisLock)
{
this.RequestCompleting(null);
this.syncPumpEnabled = false;
if (this.pending > 0)
{
this.EnsurePumping();
}
}
}
}
TimeoutHelper helper2 = new TimeoutHelper(timeout);
this.channel.Send(message, helper2.RemainingTime());
this.EnsurePumping();
return request.WaitForReply(helper2.RemainingTime());
}

在Request中,除了调用Channel的Send方法以外,还调用了SyncDuplexRequest的WaitForReply返回消息。

SyncDuplexRequest的WaitForReply定义如下:

internal Message WaitForReply(TimeSpan timeout)
{
try
{
if (!TimeoutHelper.WaitOne(this.wait, timeout))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.parent.GetReceiveTimeoutException(timeout));
}
}
finally
{
this.CloseWaitHandle();
}
this.parent.ThrowIfInvalidReplyIdentity(this.reply);
return this.reply;
}

3.2MethodData的Channel类型:

private IMethodReturnMessage InvokeChannel(IMethodCallMessage methodCall)
{
string str = null;
ActivityType unknown = ActivityType.Unknown;
if (DiagnosticUtility.ShouldUseActivity && ((ServiceModelActivity.Current == null) || (ServiceModelActivity.Current.ActivityType != ActivityType.Close)))
{
MethodData methodData = this.GetMethodData(methodCall);
if ((methodData.MethodBase.DeclaringType == typeof(ICommunicationObject)) && methodData.MethodBase.Name.Equals("Close", StringComparison.Ordinal))
{
str = SR.GetString("ActivityClose", new object[] { this.serviceChannel.GetType().FullName });
unknown = ActivityType.Close;
}
}
using (ServiceModelActivity activity = string.IsNullOrEmpty(str) ? null : ServiceModelActivity.CreateBoundedActivity())
{
if (DiagnosticUtility.ShouldUseActivity)
{
ServiceModelActivity.Start(activity, str, unknown);
}
return this.ExecuteMessage(this.serviceChannel, methodCall);
}
}

private IMethodReturnMessage ExecuteMessage(object target, IMethodCallMessage methodCall)
{
MethodBase methodBase = methodCall.MethodBase;
object[] args = methodCall.Args;
object ret = null;
try
{
ret = methodBase.Invoke(target, args);
}
catch (TargetInvocationException exception)
{
return this.CreateReturnMessage(exception.InnerException, methodCall);
}
return this.CreateReturnMessage(ret, args, args.Length, null, methodCall);
}

对于Channel,直接调用methodBase.Invoke进行调用

3.3、MethodData的Object类型

private IMethodReturnMessage InvokeObject(IMethodCallMessage methodCall)
{
return RemotingServices.ExecuteMessage(this.objectWrapper, methodCall);
}
RemotingServices中ExecuteMessage的定义如下:
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
public static IMethodReturnMessage ExecuteMessage(MarshalByRefObject target, IMethodCallMessage reqMsg)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
RealProxy realProxy = GetRealProxy(target);
if ((realProxy is RemotingProxy) && !realProxy.DoContextsMatch())
{
throw new RemotingException(Environment.GetResourceString("Remoting_Proxy_WrongContext"));
}
StackBuilderSink sink = new StackBuilderSink(target);
return (IMethodReturnMessage) sink.SyncProcessMessage(reqMsg, 0, true);
}
StackBuilderSink中SyncProcessMessage的处理过程:
public virtual IMessage SyncProcessMessage(IMessage msg)
{
return this.SyncProcessMessage(msg, 0, false);
}

internal virtual IMessage SyncProcessMessage(IMessage msg, int methodPtr, bool fExecuteInContext)
{
IMessage message3;
IMessage message = InternalSink.ValidateMessage(msg);
if (message != null)
{
return message;
}
IMethodCallMessage message2 = msg as IMethodCallMessage;
LogicalCallContext threadCallContext = null;
object obj2 = CallContext.GetLogicalCallContext().GetData("__xADCall");
bool flag = false;
try
{
object server = this._server;
VerifyIsOkToCallMethod(server, message2);
LogicalCallContext callCtx = null;
if (message2 != null)
{
callCtx = message2.LogicalCallContext;
}
else
{
callCtx = (LogicalCallContext) msg.Properties["__CallContext"];
}
threadCallContext = CallContext.SetLogicalCallContext(callCtx);
flag = true;
callCtx.PropagateIncomingHeadersToCallContext(msg);
PreserveThreadPrincipalIfNecessary(callCtx, threadCallContext);
if (this.IsOKToStackBlt(message2, server) && ((Message) message2).Dispatch(server, fExecuteInContext))
{
message3 = new StackBasedReturnMessage();
((StackBasedReturnMessage) message3).InitFields((Message) message2);
LogicalCallContext context4 = CallContext.GetLogicalCallContext();
context4.PropagateOutgoingHeadersToMessage(message3);
((StackBasedReturnMessage) message3).SetLogicalCallContext(context4);
return message3;
}
MethodBase methodBase = GetMethodBase(message2);
object[] outArgs = null;
object ret = null;
RemotingMethodCachedData reflectionCachedData = InternalRemotingServices.GetReflectionCachedData(methodBase);
object[] args = Message.CoerceArgs(message2, reflectionCachedData.Parameters);
ret = this.PrivateProcessMessage(methodBase.MethodHandle, args, server, methodPtr, fExecuteInContext, out outArgs);
this.CopyNonByrefOutArgsFromOriginalArgs(reflectionCachedData, args, ref outArgs);
LogicalCallContext logicalCallContext = CallContext.GetLogicalCallContext();
if (((obj2 != null) && ((bool) obj2)) && (logicalCallContext != null))
{
logicalCallContext.RemovePrincipalIfNotSerializable();
}
message3 = new ReturnMessage(ret, outArgs, (outArgs == null) ? 0 : outArgs.Length, logicalCallContext, message2);
logicalCallContext.PropagateOutgoingHeadersToMessage(message3);
CallContext.SetLogicalCallContext(threadCallContext);
}
catch (Exception exception)
{
message3 = new ReturnMessage(exception, message2);
((ReturnMessage) message3).SetLogicalCallContext(message2.LogicalCallContext);
if (flag)
{
CallContext.SetLogicalCallContext(threadCallContext);
}
}
return message3;

3.4MethodData的GetType类型

private IMethodReturnMessage InvokeGetType(IMethodCallMessage methodCall)
{
return this.CreateReturnMessage(this.proxiedType, null, 0, SetActivityIdInLogicalCallContext(methodCall.LogicalCallContext), methodCall);
}
private IMethodReturnMessage CreateReturnMessage(object ret, object[] outArgs, int outArgsCount, LogicalCallContext callCtx, IMethodCallMessage mcm)
{
return new ReturnMessage(ret, outArgs, outArgsCount, callCtx, mcm);
}

它调用了ReturnMessage的如下构造函数:

public ReturnMessage(object ret, object[] outArgs, int outArgsCount, LogicalCallContext callCtx, IMethodCallMessage mcm)
{
this._ret = ret;
this._outArgs = outArgs;
this._outArgsCount = outArgsCount;
if (callCtx != null)
{
this._callContext = callCtx;
}
else
{
this._callContext = CallContext.GetLogicalCallContext();
}
if (mcm != null)
{
this._URI = mcm.Uri;
this._methodName = mcm.MethodName;
this._methodSignature = null;
this._typeName = mcm.TypeName;
this._hasVarArgs = mcm.HasVarArgs;
this._methodBase = mcm.MethodBase;
}
}

4、总结:

WCF的客户端框架中介绍了很多MS封装的内部对象,整个流程的说明介绍这些对象时根据流程的介绍的需要进行
了一些介绍。下面对这些对象做个总结以认清它们之间的关系。

4.1、WCF客户端流程:

WCF客户端流程如下图:



上图流程说明:

1、由DuplexChannelFactory的父类:ChannelFactory<TChannel>的父类ChannelFactory初始化

Endpoint。

2、ChannelFactory调用ServiceChannelFactroy的BuildChannelFactory,通过初始化的Endpoint创建

ServiceChannelFactroy。(根据契约需要的通道形状,会生成继承自ServiceChannelFactory的

ServiceChannelFactoryOverX,)

3、ServiceChannelFactroy创建ServiceChannelFactroy的过程中,会初始化ClientRuntime对象
4、ServiceChannelFactoryOverX通过CreateInnerChannelBinder创建IChannelBinder对象。
5、ServiceChannelFactoryOverX通过CreateInnerChannelBinder方法创建IChannelBinder对象
6、ServiceChannelFactoryOverX通过CreateChannel创建ServiceChannel,并通过ImmutableClientRuntime初始化Channel。
7、实际代理ServiceChannelProxy 通过ServiceChannel对象,契约接口定义生成RealProxy。
8、通过RealProxy获取TransparentProxy对象
9、TransparentProxy对象调用服务
10、ServiceChannel通过IChannelBinder对象发送消息

4.2、WCF客户端使用到的对象关系

在这两节分析WCF客户端时,介绍了很多内部 对象。通过UML关系图描述一下这些类型之间的关系:



在上图中,以接口为分界线,上半部分生成ServiceChannel;下半部分生成调用服务的代理。

4.3、ServiceChannel生成时序图

最后后通过时序图介绍一下ServiceChannel、IChannelBinder对象生成过程:



备注:本节以及前一节中所有流程的说明都是以netTcpBiding作为传输协议来进行的,其他协议也类似。

分类: WCF架构体系
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: