IIS5与IIS6 应用程序生命周期和页生命周期

来源:转载

在写这篇博客之前,知好多前辈已经写过,自己班门弄斧,主要是加深自己对细节的理解,另一方面希望对浏览此篇文章的读者一个新的认识。注定是一长篇。肯定有新的认识,图示都是原创。

此篇所有牵涉的细节,我会一一列出,估计持续更新数日。

当从浏览器发送到服务器一个请求,整个流程与细节的把握。IIS5和IIS6的有些许的不同。

全面理解,把握细节:

一,请求到达IIS再到Framework。若看以下的讲解,需要了解:

1,IIS5和IIS6都具备inetinfo.exe进程。

2, inetinfo.exe(任务管理器看到)的作用:包括许多由IIS提供的服务(HTTP、FTP、SMTP等)。Inetinfo.exe接收来自TCP/IP子系统的请求,并将这些请求送往各自的服务,      这些服务又解释请求,执行请求,并把结果返回给客户机。 因为所有这些服务都在同一个进程  (inetinfo.exe)  中运行 ,所以它们能够共享高速缓存的数据,如文件句柄、      帐户信息和日志文件数据。

3,Name Pipes命名管道是一种协议,相当于TCP/IP中的Socket协议,两者有很大的相似之处,用到局域网和广域网的各自优点。

详情请参照:http://msdn.microsoft.com/zh-cn/library/ms187892.aspx

4,inetinfo.exe和aspnet_isapi.dll的关系,这里之处为”调用“是否有不妥之处。也就是了解.exe文件和.dll文件的之间的关系,此点自己查阅相关资料。

5,注册表:在这里的主要作用为文件的关联。详情自己查阅相关资料。

6,Work Process工作者进程在IIS5和IIS6分别叫做w3wp.exe和aspnet_wp.exe。两者指得都是工作者进程,只是名字不同。

7,IIS(非托管)和FrameWork(托管)之间的通信:IIS是非托管程序,而FrameWork上是托管程序,两者通过指针ecb将Request传递资源包。

8,托管和非托管代码代码。请参考:http://www.cnblogs.com/Holmes-Jin/archive/2012/03/14/2396411.html

9,http.sys在(C:/Windows/System32/drivers/)中,内核模式与用户模式,属于操作系统的知识,这里不做深入研究。

一, IIS5inetinfo.exe 接受来自浏览器的请求,然后 调用 ”aspnet_isapi.dll“,aspnet_isapi.dll" 遵照 "” 命名管道协议Named Pipes “通过 ecb指针(非托管的资源包) 和Work Process( w3wp.exe )进行传输,此时aspnet_isapi.dll与w3wp.exe属于不同的进程,传输效率不是最优的,在iis6中优化了这一点。

二, IIS6 是服务器的网卡驱动 内核模块C:/Windows/System32/drivers/http.sys 监听到,然后会查询 注册表Regitry 此请求和那个应用程序 关联 (注册表的用途之一 处理。交予 W3SVC服务属于svchost.exe进程中的一个服务, 能在任务管理器“服务“中看到 )然后查看 inetinfo.exe 交予 aspnet_isapi.dll ,此时的aspnet_isapi.dll被划进 Worker Process工作者进程 中( aspnet_wp.exe ),交予FrameWork处理。因为aspnet_wp.exe与FrameWork属于同一工作者进程,传输效率大大优于IIS5。 IIS6,它是完全为ASP.NET做过优化的。

是的,我也做个图。

二,请求到达进入framework后所做的处理。

对所请求的文件的文件扩展名进行检查,确定应由哪个 ISAPI 扩展处理该请求,然后将该请求传递给合适的 ISAPI 扩展。ASP.NET 处理已映射到其上的文件扩展名,如 .aspx、.ascx、.ashx 和 .asmx

1,先创建“appdomain”,应用程序域。隔离作用。有关应用程序域的作用:请参考http://www.cnblogs.com/leslies2/archive/2012/03/06/2379235.html

由System.Web.Hosting. ApplicationManager 类,此类有公开的方法和未公开的方法,大多和客户端和服务端的应用程序域有关系。详情:http://msdn.microsoft.com/zh-cn/system.web.hosting.applicationmanager.aspx

2,创建“hostingenvironment”,宿主环境。

由System.Web.Hosting. HostingEnviroment 类实例化一个对象创建。详情参考:http://msdn.microsoft.com/zh-cn/library/vstudio/System.Web.Hosting.HostingEnvironment(v=vs.100).aspx

3,创建核心对象, ISAPIRuntime 、 HttpRuntime,HttpWorkRequest、HttpContext、HttpRequest、HttpResponse和和HttpApplicationFactory、HttpApplication 。实现IHttpHandler

此过程最为复杂,自己理解,

第一,由aspnet_isapi.dll调用System.Web.Hosting.ISAPIRuntime类中的ProcessRequest方法。此类有2个重要作用。读者可以用反编译工具查询这个类。

作用:1,接受IntPtr类型的指针变量ecb创建System.Web. HttpWorkRequest 类wr对象。 大多数情况下,代码不会直接处理  HttpWorkerRequest,这是因为请求和响应数据是通过HttpRequest和 HttpResponse 类公开的。

作用:2,调用HttpRuntime类的public static  void   ProcessRequest ( HttpWorkerRequest  wr)调用 ProcessRequestNoDemand ( wr ); 方法继续调用 ProcessRequestNow ( wr ); 方法继续调用 theRuntime . ProcessRequestInternal ( wr ); 方法创建HttpContext 有 context = new  HttpContext ( wr , false); 读者也可以用反编译工具查询这个类。

第二,创建HttpApplicationFactory对象,将context创建并 传值 到Application对象。在创建之前HttpApplicationFactory会到HttpApplication池中查看,有没有空闲的。若有直接用。没有的时候才创建新的HttpApplication。 读者也可以用反编译工具查询这个类。

第三,HttpRuntime类创建Context的时候同样具有另外一个作用,调用 HttpApplicationFactory 就是创建Appplication对象, IHttpHandler applicationInstance =  HttpApplicationFactory . GetApplicationInstance ( context );继续调用 theApplicationFactory . GetNormalApplicationInstance ( context );

有关HttpApplication。是作用整个程序运行期间(用于数据共享)。

HttpRquerst(URL传来的Querystring和提交的表单form数据)。

HttpResponse(有一个TextWriter对象,存储想浏览器发送的数据。)

有关TextWriter和Render方法,以下简介:有关到页面生命周期。下面会有讲述。

1,

System.IO.TextWriter有个子类叫做System.Web.UI.HtmlTextWriter  用reflector可以看到public class HtmlTextWriter :  TextWriter

根据MSDN的描述,HtmlTextWriter类用于将 标记字符和文本 写入到ASP.NET服务器控件输出流。此类提供了ASP.NET服务器控件在向客户端呈现标记时所使用的格式设置功能。

HtmlTextWriter是一个储存html代码的类。示例:http://blog.itpub.net/14466241/viewspace-573265/

2,

①但是上面的向“客户端呈现”是另一个类的功能,Render方法。此方法有好多类都具有,“呈现“。多为虚方法,让其自定义子类实现多态。比如ControlAdapter用于改写控件的html代码的一个类。

在处理的这个阶段, Page 对象会在每个控件上调用此方法。所有 ASP.NET Web 服务器控件都有一个用于写出发送给浏览器的控件标记的  Render 方法。

创建自定义控件的时候,通常要覆盖此方法以输出控件的标记。不过,如果自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不需要覆盖  Render 方法。示例:http://www.cnblogs.com/tonyqus/archive/2005/02/15/104576.html

public abstract class ControlAdapter{
protected internal virtual void Render(HtmlTextWriter writer);

}

②当然render方法也存在System.Web.UI.Control中,也是虚方法。

protected internal virtual void Render(HtmlTextWriter writer){this.RenderChildren(writer);}

public class HttpApplication :  IComponent ,  IDisposable ,  IHttpAsyncHandler , IHttpHandler,  IRequestCompletedNotifier ,  ISyncContext

**IhttpHangdler 里的pr方法,被Web.UI.Page与HttpApplication继承。就是将“上下文”返回到浏览器。
**IhttpModule:当一个过滤器Filter(自定义一个类),1,继承此接口2,实现此接口中的init(Application context)方法 ,3并在config文件配置
Global文件就是继承了Application类,就是一个过滤器,简化了自定义过滤器的步骤(省去config配置等麻烦),工作中就用这种形式,想做其他的事件 只需Application_事件名字就OK.
Application 本身具有一些事件 start end 等。一旦程序运行,就是种存在,共享。

public class Global : System.Web.HttpApplication{

protected void Application_Start(object sender, EventArgs e){

}

protected void Session_Start(object sender, EventArgs e){

}

protected void Application_ BeginRequest (object sender, EventArgs e)

{

}

protected void Application_ AuthenticateRequest (object sender, EventArgs e)

{

}

protected void Application_Error(object sender, EventArgs e){

}

protected void Session_End(object sender, EventArgs e){

}

protected void Application_End(object sender, EventArgs e){

}


了解这两个接口:同样意义很大。
①public interface IHttpHandler
{
// Methods
void ProcessRequest(HttpContext context);
// Properties
bool IsReusable { get; }
}
②public interface IHttpModule{ // Methods void Dispose(); void Init(HttpApplication context);}
4,由HttpApplication管道处理请求。

下面是请求管道中的19个事件.

(1)BeginRequest: 开始处理请求

(2)AuthenticateRequest授权验证请求,获取用户授权信息

(3):PostAuthenticateRequest获取成功

(4):AunthorizeRequest 授权,一般来检查用户是否获得权限

(5):PostAuthorizeRequest:获得授权

(6):ResolveRequestCache:获取页面缓存结果

(7):PostResolveRequestCache 已获取缓存

(8):PostMapRequestHandler 创建页面对象:aspx创建了页面对象,控件树。ashx创建最终处理当前http请求的 Handler 实例: 第一从HttpContext中获取当前的PR Handler ,Create获取当前的上下文(HttpContext)已经映射了PrHandler没?是:结束。空的话:创建PrHandler对象实例

(9):PostAcquireRequestState 获取Session

(10)PostAcquireRequestState 获得Session

(11)PreRequestHandlerExecute:准备执行页面对象

**中间调用页面对象继承Page类(继承 IhttpHangdler类  )的子类页面对象的ProcessRequest方法,(在Application里转换成接口IhttpHandler 的通过反射被请求页面对象的ProcessRequest 方法).

(12)PostRequestHandlerExecute 执行完页面对象了

(13)ReleaseRequestState 释放请求状态

(14)PostReleaseRequestState 已释放请求状态

(15)UpdateRequestCache 更新缓存

(16)PostUpdateRequestCache 已更新缓存

(17)LogRequest 日志记录

(18)PostLogRequest 已完成日志

(19)EndRequest 完成

对的我需要来个图。

4,在Application的第8个事件创建处理对象的时候,这里就以aspx为例子。执行页面的生命周期。流程是这样的。

首先随便vs建一个应用程序,添加一个web窗体,后置代码反射出其对应的DLL,然后用Reflector反编译查看此页面的执行的周期。

得到的

打开此路径,记得一定是红线标出的路径!!!!而不是dll之前的那个,如果直接将这个dll弄到reflector里面,会查看到你自己写的后置代码,并不能看到页面执行的东西。

移动到reflector里面的结果。

此页面,先建立控件树。然后执行页面的PR方法,进一步调用。

主要执行的ProcessRequestMain方法。开始执行里面流程。这里面的一定要仔细看。大家自己反编译。大家查看这个类再与MS给的生命周期对比。多理解几遍就很自然清楚。

http://msdn.microsoft.com/zh-cn/library/ms178472(VS.80).aspx页面生命周期概述。

最后推荐一个精简的博客。图示

此图 ,是别人所做,我找不到这人的博客了。只有图被摘下。在此特别注释。


分享给朋友:
您可能感兴趣的文章:
随机阅读: