最近一個項目是將web版的程序,改成單機版。話說這個web版號稱當年十幾我的用了至少3個月的時間開發,後來三年還不斷有修改,而如今要在1個月內由一我的完成,這簡直是不可能完成的任務!直覺告訴我,重寫確定不是辦法,還好有朋友用過Cassini http://cassinidev.codeplex.com (可替代IIS的單機Web Form解決方案)當即投入測試,可用;有源碼,不擔憂出太大問題。web
如今項目結束了,看了一遍CassiniDev,它的基本思路是:app
1.新建socket,綁定並監聽本機上一個可用的端口。dom
2.對新建鏈接(新的請求)建立新的socket。socket
public void Start() { _socket = CreateSocketBindAndListen(AddressFamily.InterNetwork, _ipAddress, _port); //start the timer //DecrementRequestCount(); ThreadPool.QueueUserWorkItem(delegate { while (!_shutdownInProgress) { try { Socket acceptedSocket = _socket.Accept(); ThreadPool.QueueUserWorkItem(delegate { if (!_shutdownInProgress) { Connection conn = new Connection(this, acceptedSocket); if (conn.WaitForRequestBytes() == 0) { conn.WriteErrorAndClose(400); return; } Host host = GetHost(); if (host == null) { conn.WriteErrorAndClose(500); return; } //IncrementRequestCount(); host.ProcessRequest(conn); } }); } catch { Thread.Sleep(100); } } }); }
3.經過一個微軟的內部類「System.Web.Compilation.BuildManagerHost」(未對外公佈,MSDN查不到),生成Host實例。ide
/// <remarks> /// This is Dmitry's hack to enable running outside of GAC. /// There are some errors being thrown when running in proc /// </remarks> private object CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType,int port) { // create BuildManagerHost in the worker app domain //ApplicationManager appManager = ApplicationManager.GetApplicationManager(); Type buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost"); IRegisteredObject buildManagerHost = ApplicationManager.CreateObject(_appId, buildManagerHostType, virtualPath, physicalPath, false); // call BuildManagerHost.RegisterAssembly to make Host type loadable in the worker app domain buildManagerHostType.InvokeMember("RegisterAssembly", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic, null, buildManagerHost, new object[] { hostType.Assembly.FullName, hostType.Assembly.Location }); // create Host in the worker app domain // FIXME: getting FileLoadException Could not load file or assembly 'WebDev.WebServer20, Version=4.0.1.6, Culture=neutral, PublicKeyToken=f7f6e0b4240c7c27' or one of its dependencies. Failed to grant permission to execute. (Exception from HRESULT: 0x80131418) // when running dnoa 3.4 samples - webdev is registering trust somewhere that we are not return ApplicationManager.CreateObject(_appId, hostType, virtualPath, physicalPath, false); }
4.繼承「SimpleWorkerRequest」類(它是System.Web.HttpWorkerRequest 抽象類的簡單實現,該抽象類可用於在 Internet 信息服務 (IIS) 應用程序以外承載ASP.NET 應用程序),寫一個本身的Request類。性能
5.由HttpRuntime驅動全部 ASP.NET Web 處理執行。測試
HttpRuntime.ProcessRequest(this);
這個開源組件確實不錯,好用,穩定,在winxp, vista, win7, win8均可用。但有一個性能上的不足,在建立微軟內部類「System.Web.Compilation.BuildManagerHost」實例時,耗時要5-6秒的時間,機器差一點的話,要9-20秒,目前暫無改進。ui