- 1、本文档共12页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
写在前面的话:网上讲A运行模式的好文章已经很多了,笔者本不用多此一举,另成一文。但从笔者自己的学习经验看,如果学到的这些知识不能对应到类库中的源代码,印象总归不够深刻,大有隔靴搔痒之感。只好自己写上一篇,对这方面的知识做个小小的总结。文中所有内容都是笔者在看了网上很多文章后,结合自己的开发经验得出的一些理解,难免有错误的地方,欢迎批评指出。另外,由于笔者能力所限,很多地方并未说透(真正对应到代码),也盼高手能够给予补充。一.进入A运行时之前虽然本文的重点是对托管代码的解析,但为了整个知识点的完整性,这里简单介绍一下IIS处理请求的一些基本情况。在一个IIS服务器上,你可以设置多个应用程序池(每个应用程序池可以单独设置允许使用的最大内存数量、CPU使用率、回收工作进程的时间间隔等参数,而且一个应用程序池里面只能使用一个版本的.NET Framework),然后把自己的Web应用分别部署到这些应用程序池中。在默认情况下,每个应用池会有一个工作进程w3wp.exe来维护(如果开通了Web园功能,也可以设置多个工作进程)。每个应用程序(虚拟目录)在池中都有自己的应用程序域,这些应用程序域都处于这个应用程序池的工作进程的进程空间内。IIS是通过各种ISAPI的扩展来处理各种类型的应用的。当我们从客户端提交一个请求过来之后,IIS会根据请求的页面或者服务的类型,把请求映射到指定的ISAPI扩展。比方说,如果我们需要让IIS支持perl这样的服务器端程序(当然,这个移植工作早就有人做过了),我们就需要编写一个专门处理对perl页面进行的请求的ISAPI扩展。根据ISAPI的定义(符合这个定义的ISAPI扩展才能和IIS正常交互),在你的扩展中可以包括ISAPI Extension和ISAPI Filter两大部分。ISAPI Extension是对请求的处理程序,完成和web服务器之间的输入输出;而ISAPI Filter则是一些回调接口,你可以通过实现这些接口来介入到整个请求处理的每一步骤,对Authentication,RevolveCache等环节进行控制。另外,ISAPI本身就是在工作进程里运行的,而运行时也是在工作进程里运行的,所以两者的交互非常有效率。对于.aspx页面,这个扩展就是aspnet_isapi.dll。因为这些ISAPI都是非托管的Win32应用,直接对它们进行改动是比较困难的。所以,为了增强A运行时的可扩展性,aspnet_isapi.dll本身的功能非常少,我们可以把aspnet_isapi.dll简单理解为请求信息的路由器,负责把请求从IIS传送到运行时。而后面我们将要讲到的HttpHandle和HttpModule则分别担负起了ISAPI Extension和ISAPI Filter的功能,幸运的是,HttpHandle和HttpModule可以由纯的托管代码来实现。二.从非托管代码到托管代码前面说了,aspnet_isapi.dll是非托管代码,而运行时是托管代码,他们都运行在w3wp.exe工作进程里面,那么两者之间的调用点发生在什么地方呢?在介绍接下来的内容之前必须先介绍一个概念:ECB。ECB的全称是Extension Control Block,它是一个非托管资源包,具有对ISAPI接口完整的访问能力,包含了所有和一个传入请求有关的底层信息,如提交的标单中的数据等等。所以说,中的托管代码想要访问aspnet_isapi.dll对外提供的接口,就需要通过ECB。其实更准确的来说,是托管代码公布了一个IUnknown类型的接口供aspnet_isapi.dll调用,而aspnet_isapi.dll在调用的时候会把自己的ecb地址传进去。明白了ECB的概念,下面我们要介绍一个接口和一个接口的实现类(位于System.Web.Hosting名字空间下),请读者注意笔者在代码中的注释(本文的主要目的就是和大家一起从代码实现的角度来认识整个A运行时,所以代码里的注释是笔者添加的关键性说明,后面的所有代码段都是这样):IISAPIRuntime1/**//*InterfaceType(ComInterfaceType.InterfaceIsIUnknown)指明了这个接口将作为 IUnknown 派生接口向 COM 公开,这就使得isapi.dll可以以COM方式调用此接口。*/2[ComImport, Guid(08a2c56f-7c16-41c1-a8be-432917a1a2d1), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]3publicinterface IISAPIRuntime4{5void StartProcessing();6vo
文档评论(0)