WCF客户端运行时架构体系详解[下篇]

当基于某个终结点创建的ChannelFactory<TChannel>被开启的之后,位于服务模型层的客户端运行时框架被成功构建。站在编程的角度看ChannelFactory<TChannel>,它就是一个创建用于服务调用的服务代理对象的工厂。由于服务调用需要借助于服务代理来完成,我们很有必要从整个客户端运行架构层面来了解服务代理和基于服务代理的服务调用是如何实现的。

目录 一、服务代理是一个透明代理 二、服务调用的流程       操作选择       输入参数检验       序列化请求消息       请求消息的发送和回复消息的接收       回复消息的检验       反序列化回复消息       检验返回值(或者ref/out参数)

一、服务代理是一个透明代理

如果你阅读了《WCF技术剖析(卷1)》第8章《客户端(Client)》,你应该知道通过ChannelFactory<TChannel>创建的服务代理对象是一个“透明代理(Transparent Proxy)”对象。而这可以通过调用RemotingServices的静态方法IsTransparentProxy来检验。为此我写了如下一段简单的检验程序,而输出的结果证实了“服务代理是透明代理”的结论。

   1: using (ChannelFactory<ICalculate> channelFactory = new ChannelFactory<ICalculate>("calculateservice"))
   2: {
   3:     ICalculate calculator = channelFactory.CreateChannel();
   4:     bool isTransparentProxy = RemotingServices.IsTransparentProxy(calculator);
   5:     Console.WriteLine("Service porxy is a transparent proxy? {0}.", isTransparentProxy ? "Yes" : "No");
   6: }

输出结果:

   1: Service porxy is a transparent proxy? Yes.

既然服务代理是一个透明代理,它一定对应了具体的真实代理(RealProxy)。实际上,服务代理对象内部具有一个类型为ServiceChannelProxy的对象作为其真实代理对象。ServiceChannelProxy是WCF中的一个继承自RealProxy的类型,而其核心则是一个类型为ServiceChannel的对象。ServiceChannelProxy和ServiceChannel均是定义在System.ServiceModel.Channels命名空间下的内部(Internal)类型

当我们使用ChannelFactory<TChannel>创建一个服务代理的时候,WCF会根据代表客户端运行时的ClientRuntime创建一个ServiceChannel对象。并且调用之前创建的信道工厂栈并最终创建信道栈。由于ServiceChannel同时引用着代表服务模型层核心的ClientRuntime和信道层的信道栈,所以我们可以说ServiceChannel是连接WCF客户端服务模型层与信道层之间的纽带。当ServiceChannel被成功创建后,WCF会基于该对象创建ServiceChannelProxy对象。最然返回这个真实代理对象的透明代理。

当我们通过显式(将服务代理对象转换成ICommunicationObject类型,并显式调用其Open方法)或者隐式(如果服务代理在未开启的状态下被用于服务调用,在进行服务调用之前会被隐式地开启)开启时,整个信道栈会被开启。下图揭示了服务代理(透明代理)、ServiceChannelProxy(真实代理)、ServiceChannel、ClientRuntime和信道栈之间的关系。

二、服务调用的流程

由于服务代理是一个透明代理,所以针对它的任何一个方法调用都会最终转换到对其真实代理(ServiceChannelProxy)的Invoke方法的调用。所以ServiceChannelProxy会接管所有针对于服务代理对象的服务调用,并最终将调用递交给内部的ServiceChannel处理。

接下来,我们来简单地介绍一下针对一次简单的针对服务代理的服务调用,ServiceChannel在其内部是按照怎样的流程来处理的。实际上,相同的内容已经出现在了《WCF技术剖析(卷1)》第8章《客户端(Client)》中。下面的列表体现了ServiceChannel进行服务调用的整个流程(以请求/回复消息交换模式为例)。

操作选择

如果当前ClientRuntime的OperationSelector属性具有一个操作选择器,则调用其SelectOperation方法或者针对当前服务调用的客户端操作;

输入参数检验

遍历当前ClientRuntime的ParameterInspectors属性表示的参数检验器列表,调用其BeforeCall方法对输入参数实施检验;

序列化请求消息

通过当前ClientOperation的SerializeRequest属性判断是否需要进行请求消息的序列化。如果需要,则根据当前ClientOperation的Formatter属性获取消息格式化器,最终调用SerializeRequest方法将以方法调用形式体现的服务调用序列化成请求消息。

请求消息检验

遍历以当前ClientOperation的MessageInspectors属性表示的消息检验器列表,并调用BeforeSendRequest方法对请求消息实施发送前的检验。

请求消息的发送和回复消息的接收

将请求消息递交给信道层进行进一步处理,经过编码后的请求消息通过传输信道发送到服务端并等待回复。当回复消息抵达客户端后,信道层对其进行接收、解码相应的处理。

回复消息的检验

遍历以当前ClientOperation的MessageInspectors属性表示的消息检验器列表,并调用AfterReceiveReply方法对回复消息实施发送前的检验。

反序列化回复消息

通过当前ClientOperation的DeserializeReply属性判断是否需要进行回复消息的反序列化。如果需要,则根据当前ClientOperation的Formatter属性获取消息格式化器,最终调用DeserializeReply方法将包含在回复消息的调用结果反序列化成方法调用的返回值或者ref/out参数对象。

检验返回值(或者ref/out参数)

遍历当前ClientRuntime的ParameterInspectors属性表示的参数检验器列表,调用其AfterCall方法对返回值或者ref/out参数对象进行检验。

WCF客户端运行时架构体系详解[上篇] WCF客户端运行时架构体系详解[下篇]

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

WCF技术剖析(卷1)之目录

第1章  WCF简介 (WCF Overview)     1.1  SOA基本概念的和设计思想        1.2  WCF是对现有Windows平台下...

23280
来自专栏北京马哥教育

TcpDump使用手册

0x01 Tcpdump简介 ---- tcpdump 是一个运行在命令行下的嗅探工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他...

76070
来自专栏我叫刘半仙

手写一个简化版Tomcat

      Tomcat作为Web服务器深受市场欢迎,有必要对其进行深入的研究。在工作中,我们经常会把写好的代码打包放在Tomcat里并启动,然后在浏览器里就能...

41050
来自专栏用户2442861的专栏

修改npm全局安装模式的路径

刚学nodeJS不久,很纳闷为什么全局安装的模块在 'node安装目录/node_modules‘ 中没找到!后来仔细看了下安装成功后的信息,才发现原来是自动安...

11020
来自专栏张善友的专栏

.net 2.0 你是如何使用事务处理?

     事务处理作为企业级开发必备的基础设施, .net 2.0通过System.Transactions对事务提供强大的支持.你还是在使用.net 1.x下...

22560
来自专栏张善友的专栏

WCF 4.0路由服务Routing Service

在面向服务的应用系统中,最重要的概念就是消息,消息的传输是一个非常重要的问题。而在大多数情况下,消息要经历多个网络节点,这里会涉及到消息路由问题。WS规范很早就...

21380
来自专栏JackeyGao的博客

终端操作(SHELL)技巧

本篇是一些小但是有用的终端操作技巧和一些快捷方式,可以让你在 linux 命令行有出奇的效率。一方面这些技巧可以让你的效率有所提高, 但有时候也会有隐患, 所以...

15200
来自专栏大内老A

WCF的安全审核——记录谁在敲打你的门

WCF所谓的安全审核就是针对认证和授权所做的针对EventLog的日志记录。我们不但可以设置进行审核的事件(认证成功/失败,授权成功或失败),还可以选择记录信息...

27080
来自专栏技术之路

go微服务框架go-micro深度学习(二) 入门例子

    上一篇帖子简单介绍了go-micro的整体框架结构,这一篇主要写go-micro使用方式的例子,中间会穿插一些go-micro的源码,和调用流程图,帮大...

1.9K50
来自专栏和蔼的张星的图像处理专栏

1.Win10+VsCode的C/CPP编译环境搭建

我是从开始学C++的时候就一直用的是visual studio,毕竟宇宙第一IDE,写和调试都是超级方便快捷,唯一的缺点可能就是启动慢一点。 之前电脑没有换固...

86060

扫码关注云+社区

领取腾讯云代金券