CassiniDev源碼學習 - 可替代IIS的單機Web Form解決方案


最近一個項目是將web版的程序,改為單機版。話說這個web版號稱當年十幾個人用了至少3個月的時間開發,后來三年還不斷有修改,而現在要在1個月內由一個人完成,這簡直是不可能完成的任務!直覺告訴我,重寫肯定不是辦法,還好有朋友用過Cassini http://cassinidev.codeplex.com (可替代IIS的單機Web Form解決方案)立即投入測試,可用;有源碼,不擔心出太大問題。

 

現在項目結束了,看了一遍CassiniDev,它的基本思路是:

1.新建socket,綁定並監聽本機上一個可用的端口。

 

2.對新建連接(新的請求)創建新的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實例。

     /// <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秒,目前暫無改進。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM