ASP.NET页面周期请求过程总结

客户端

  第一步:用户在地址栏里面输入地址,或者是提交表单

  第二步:浏览器内部会将请求封装成HTTP请求报文,并建立Socket连接发送HTTP请求到服务器端

  第三步:等待服务器端响应

  服务器端:

  1、内核模块

  1.1 内核模块(HTTP.SYS)监听80端口

  1.2 监听到客户端的连接,并解析出请求的协议以及访问的端口

  1.3 查询注册表,并将此请求交给具体处理的进程(默认IIS会注册此过滤模块),此时请求分发给IIS

  2、IIS模块

  2.1 请求来了之后,IIS首先进行校验请求的身份

  2.2 检查请求的文件的后缀,如果是静态文件则直接处理返回(比如:js,html,css,png等)

  2.3 如果是IIS处理不了的动态文件,则直接将请求交给扩展处理程序(比如:.aspx,.ashx,.ascx请求交给aspnet_isapi.dll处理【aspnet_isapi.dll是在.Net Framework安装的时候注册的。如果是先安装.Net Framework 后安装IIS可以使用命令:aspnet_regiis -i来进行安装(在cmd和vs的命里行里面都要执行一下)】)

  IIS内部执行的过程:请求从内核拿到后,交给了w3svc服务,然后此服务去 问IIS要元数据信息,当前请求交给哪个扩展处理。

  3、工作进程阶段(workprocess)IIS6:w3wp.exe  IIS5:aspnet_wp.exe

  下面写的都是针对IIS6和IIS7经典过程:

  3.1 请求先到扩展模块:aspent_isapi.dll(这是一个非托管的程序集,微软写的一个实现了IIS扩展接口的一个COM的程序集。并且已经注册到 了IIS的扩展中),它是非托管环境和托管环境的桥梁,它负责将请求的报文数据交给aspnet runtime,另外负责将aspent处理后的响应交还给IIS。另外此扩展会负责第一次请求来的时候,启动aspent 的runtime(appdomain等)

  以下是托管环境中的代码(我们可以看到所有的源码)

  3.2 请求到达ISAPIRuntime

  此时请求交给public int ProcessRequest(IntPtr ecb, int iWRType)方法处理,其中第一个参数:ecb是windows操作系统的一个句柄,

  句柄的概念:句柄是windows操作系统特殊的标识,代表着操作系统的一个资源,32位操作系统是一个32位的数字,而64位的那就是64位的(了解即可);

  ecb非常niublity。拿到ecb后就可以拿到请求报文的所有的东西,在ProcessRequest方法内部,通过ecb创建了一个 HttpWorkRequest实例【HttpWorkRequest是一个很原始的对HTTP请求报文做了简单封装,另外封装了对ecb返回数据的封 装,也就是说请求都会从这里获得,响应也是从这里返回】

  3.3 请求交给HttpRuntime类

  请求交给HttpRuntime的private void ProcessRequestInternal(HttpWorkerRequest wr)

  第一步:通过HttpWorkerRequest创建HttpContext上下文,此上下文会在整个Appliaction管道中流动,而且是线程安全的,HttpContext包含了HttpRequest对象和HttpResponse对象,它们分别封装了Http请求的请求报文以及响应的信息。

  第二步:获取Appliaction实例

  HttpRuntime自己不处理当前请求,而是交给一个代理对象HttpAppliaction实例。

  HttpAppliaction实例是通过如下代码获取的:

  IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);

  我们看到了这是做了一个对象池技术,因为HttpAppliaction创建是通过将aspnet项目里面的Global.asax编译成 HttpAppliaction类型,然后通过反射创建出来,所以实例很宝贵,创建非常浪费性能,微软为了提高性能,使用对象池技术,使得 HttpAppliaction得到了重用。在源码内部我们看到了对象池使用了lock栈进行了管理。可以看一下反射的代码:

  private HttpApplication GetNormalApplicationInstance(HttpContext context)

  {

  HttpApplication application = null;

  lock (this._freeList)

  {

  if (this._numFreeAppInstances > 0)

  {

  application = (HttpApplication) this._freeList.Pop();

  this._numFreeAppInstances--;

  if (this._numFreeAppInstances < this._minFreeAppInstances)

  {

  this._minFreeAppInstances = this._numFreeAppInstances;

  }

  }

  }

  if (application == null)

  {

  application = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType);

  using (new ApplicationImpersonationContext())

  {

  application.InitInternal(context, this._state, this._eventHandlerMethods);

  }

  }

  return application;

  }

  在此还做了处理,如果是第一次请求的话,则首先初始化特殊的应用程序池,然后创建一个

你可能感兴趣的:(asp.net)