CASSINI源代码分析(3)

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

internal class Host : MarshalByRefObject {……}

首先,我们看到Host仅能够在cassini项目中使用,因为是 internal 的类定义。另外,继承自MarshalByRefObject,允许在支持远程处理的应用程序中跨应用程序域边界访问对象。我们联想到asp.net对于应用程序的执行方式是应用程序域为划分边界的,作为Host必须能够支持跨应用程序域,以便多个应用程序在其边界内执行。

先来看看其成员变量:

private bool _started; //是否已经启动

private bool _stopped; //是否停止了

private Server _server; //对外交互父对象

private int _port; //以下大致应该是一个web server应当具有的内部变量

private String _virtualPath;

private String _lowerCasedVirtualPath;

private String _lowerCasedVirtualPathWithTrailingSlash;

private String _physicalPath;

private String _installPath;

private String _physicalClientScriptPath;

private String _lowerCasedClientScriptPathWithTrailingSlashV10;

private String _lowerCasedClientScriptPathWithTrailingSlashV11;

private Socket _socket; //通信用的套接字

private WaitCallback _onStart; //回调函数

private WaitCallback _onSocketAccept;

private EventHandler _onAppDomainUnload; //事件监控,当某个应用程序域将要退出时候发生,由Host类处理。

public override Object InitializeLifetimeService() {

return null; // never expire lease

}是重载MarshalByRefObject的成员,正如源代码中的注释说言,通过返回null告诉.net framework永远不要将此类的实例失效过期。分布式垃圾回收负责控制服务器应用程序的生存期,并负责在它们的生存期到期时删除它们。传统上,分布式垃圾回收使用引用计数和 Ping 进行控制。这在每个对象有少数几个客户端时可以很好地工作,但在每个对象有数千个客户端时效率很低。生存期服务可采用传统分布式垃圾回收器的功能,并在客户端数目增加时能很好地扩展。

Configure函数很值得分析,因为在Server.CreateHost中出现过,看看:

public void Configure(Server server, int port, String virtualPath, String physicalPath, String installPath) {

_server = server;

_port = port;

_virtualPath = virtualPath;

_lowerCasedVirtualPath = CultureInfo.InvariantCulture.TextInfo.ToLower(_virtualPath);

_lowerCasedVirtualPathWithTrailingSlash = virtualPath.EndsWith("/") ? virtualPath : virtualPath + "/";

_lowerCasedVirtualPathWithTrailingSlash = CultureInfo.InvariantCulture.TextInfo.ToLower(_lowerCasedVirtualPathWithTrailingSlash);

_physicalPath = physicalPath;

_installPath = installPath;

//以上都是赋值和参数检验代码

_physicalClientScriptPath = installPath + "\\asp.netclientfiles\\";

//以下开始确定asp.net提供的客户端脚本路径

String version4 = FileVersionInfo.GetVersionInfo(typeof(HttpRuntime).Module.FullyQualifiedName).FileVersion; //查找当前asp.net运行时模块的版本信息

String version3 = version4.Substring(0, version4.LastIndexOf('.'));

_lowerCasedClientScriptPathWithTrailingSlashV10 = "/aspnet_client/system_web/" + version4.Replace('.', '_') + "/";

_lowerCasedClientScriptPathWithTrailingSlashV11 = "/aspnet_client/system_web/" + version3.Replace('.', '_') + "/";

//下面开始为套接字设置准备回调函数

_onSocketAccept = new WaitCallback(OnSocketAccept);

_onStart = new WaitCallback(OnStart);

// start watching for app domain unloading

_onAppDomainUnload = new EventHandler(OnAppDomainUnload);

Thread.GetDomain().DomainUnload += _onAppDomainUnload;

}

显然,config函数做了以下事情:

1、 将一些配置参数传入到host类的内部变量

2、 确定asp.net提供的一些环境,譬如脚本环境、脚本存在的路径,以便asp.net的一些组件可以顺利执行(就象在IIS中一样)

3、 准备一些回调函数、事件监听函数处理发生的事件

外部使用host还通过Start过程,我们看看:

public void Start() {

if (_started) //已经启动了,不可启动两个实例

throw new InvalidOperationException();

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

_socket.Bind(new IPEndPoint(IPAddress.Any, _port));

_socket.Listen((int)SocketOptionName.MaxConnections);

_started = true;

ThreadPool.QueueUserWorkItem(_onStart);

}

该函数完成:

1、 排除启动两个实例

2、 在给定的端口上启动监听

3、 启动_onStart回调函数线程,运行监听套接字,但是是异步调用,start函数完成后马上返回。

那_onStart函数是怎么处理的呢?

private void OnStart(Object unused) {

while (_started) {

try {

Socket socket = _socket.Accept();

ThreadPool.QueueUserWorkItem(_onSocketAccept, socket);

}

catch {

Thread.Sleep(100);

}

}

_stopped = true;

}

此线程一直进行循环,调用套接字的Accept函数,当一个连接接入到,马上调用一个新的线程(_onSocketAccept)和一个新的socket,然后产生一个新的线程来处理客户请求。遇到例外就暂停后继续Accept引入的套接字。一旦_started标志被设置false,则停止监听退出。

private void OnSocketAccept(Object acceptedSocket) {

Connection conn = new Connection(this, (Socket)acceptedSocket);

conn.ProcessOneRequest();

}

此处线程马上产生一个Connection对象,并调用Connection的ProcessOneRequest来处理。看来真正处理一个web request的过程在Connection对象内。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航