zoukankan      html  css  js  c++  java
  • 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:WindowsSystem32drivers)中,内核模式与用户模式,属于操作系统的知识,这里不做深入研究。

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

    二,IIS6是服务器的网卡驱动内核模块C:WindowsSystem32drivershttp.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,创建核心对象,ISAPIRuntimeHttpRuntime,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 : IComponentIDisposableIHttpAsyncHandlerIHttpHandlerIRequestCompletedNotifierISyncContext



    **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页面生命周期概述。
     
    最后推荐一个精简的博客。图示

    
    

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

  • 相关阅读:
    Vue(小案例_vue+axios仿手机app)_go实现退回上一个路由
    nyoj 635 Oh, my goddess
    nyoj 587 blockhouses
    nyoj 483 Nightmare
    nyoj 592 spiral grid
    nyoj 927 The partial sum problem
    nyoj 523 亡命逃窜
    nyoj 929 密码宝盒
    nyoj 999 师傅又被妖怪抓走了
    nyoj 293 Sticks
  • 原文地址:https://www.cnblogs.com/leee/p/4169167.html
Copyright © 2011-2022 走看看