图解:1)
浏览器 :把用户的操作封装成一个请求通过socket发送到后台服务器。
后台服务器:首先有个内核模块Http.sys 和针对每个应用程序池都有一个请求队列。然后请求到达http.sys之后,就把请求放到相应请求的队列池子里面去。 完成这些步骤后通知w3svc服务,由w3svc服务负责触发‘工作进程’,告诉工作进程已经内核当中有一个请求去取一个请求进行处理。拿到请求的报文之后,工作进程开始处理,工作进程分成两种情况 :
1.静态文件(读取出来直接封装成响应的报文然后返回给客户端,PS:返回给客户端这个过程不是由工作进程直接进行交互的,而是工作进程把响应报文交给http.sys内核模块,内核模块再把响应报文发给客户端)
2.如果是动态网页:比如请求的是a.aspx这时候就会启动asp.net应用程序池,这过程中不是直接启动的,而是走了一个aspnet_isapi.dll(动态链接库不叫程序集了,由c或c++写的,这内部实现了iis内部定义的协议接口),请求到达工作进程之后,工作进程审核一下,如果是静态文件就自己处理,如果是动态文件,把请求发到aspnet_isapi.dll(asp.net扩展模块:负责启动asp.net运行时,包括clr加载都是由它进行做这个工作的)进行处理)。此时再请求.netFramework运行时。当.net Framework启动之后,它还有一个职责把请求报文传递到.net Framework运行时里面去(或者说传递到托管的环境里面去)
此时是由ISAPIRuntime.PR(这个PR方法是用来处理当前请求的)接口来负责aspnet_isapi.dll非托管模块和托管模块进行接洽
ISAPIRuntime.PR() 里面有一个参数 ecb→句柄,通过这个句柄可以拿到当前请求的报文,也可以通过ecb句柄通过响应报文返回给非托管模块。也就是说ecb句柄才是真正连接托管和非托管的路口。
在这个方法内部把ecb封装成了HttpWorkRequest对象。这时候HttpWorkRequest就包含了请求和响应两个部分。
虽然已经帮我们封装成了两个简单的部分,但这样还是太原始。因此微软内部又对此进行了再封装,于是把HttpWorkRequest对象继续传到HttpRuntime.PR()方法,这个PR方法把HttpWorkRequest对象传递到HttpRuntiome.PR(work)方法里面,而在这个方法里面就把workRequest对象封装成了现在用的HttpContext这就是上下文的由来。所以说HttpContext就是通过ecb产生出来的。
这个时候HttpRuntime内部就通过HttpApplication.Factory工厂创建一个HttpApplication对象(这个对象就是负责整个asp.net模型的运作的最基本的一个类,也是最重要的一个类)
下面由HttpApplication负责处理asp.net模型的运作:(图2)
Asp.net模型是一个管道模型,管道模型当中有23个步骤,19公开的事件 。这事件依次的被执行。事件也算是步骤。httpContext会随着管道依次的往下走,整个管道流动的是一个对象, 其中第7个事件和第8个事件之间根据请求地址创建一般处理程序或者是页面对象,在第11和第12事件之间执行对象的PR方法,执行PR方法之后,继续往下流动。最后全部到执行完了之后,返回响应内容,同样也是到达内核模块,再向客户端发送响应报文。
附注:
Page_Load是在页面的PR方法里面执行的,页面的PR方法就是页面的生命周期
PR方法就是Process Request方法
托管:
c#\vb.net等等语言通过编译器生成的程序集(exe、dll),CLR加载程序集 然后通过JIT即使编译器转成机器码再交给操作系统内核 这一类就成为托管程序。
IL是一个统一的标准,所以也正是因为IL成就了.net平台
.net平台特点 :跨平台、跨语言 java也是跨平台跨语言,两者都是生成了IL中间语言
非托管:
c|c++|VB…(PS:这里的c|c++|vb..是原生程序)通过编译器直接生成的exe 直接交给操作系统内核,操作系统内核可以直接解析并且执行叫做非托管程序