Implement your own ASP.NET host system
Yangshan River
I. Host concept hosting is a very basic concept of .NET, all .NET application code must fully function to enter the hosting environment (CLR - Comm - Common Language Runtime, and this environment is actually called host ( Host) Prepare for .NET code to be started. At present, on the Windows system, there are 3 types of saved programs that are responsible for this heavy responsibility: 1. Shell (usually Explorer), provide startup .NET programs from the user desktop, create a process, start this process to establish CLR 2, browser The host, handles .NET code execution from the web download. 3. Server hosts (such as IIS Auxiliary Process ASPNET_WP.EXE) Usually, we developed ASP.NET programs run in an IIS environment (actually starting CLR by an ISAPI control), but actually ASP.NET program You can get rid of IIS to run in any hosted environment. This article discusses how the ASP.NET program starts in a custom environment, hoping to help us understand the progress of the ASP.NET, while making us developed ASP.NET can be executed in any .NET environment, no matter the server operation The system is still an ordinary desktop operating system.
Second, the implementation of ASP.NET in the IIS host About the details of ASP.NET in IIS, many articles have made detailed authority, this article does not plan to give some references here: http://www.yesky. COM / SoftChannel / 72342380468043776/20030924 / 1731387.shtmlhttp: //chs.gotdotnet.com/quickstart/aspplus/doc/prockmodel.aspx These articles are generally analyzed: How to start, how will the ASP.NET application generate programs? Set, how to load, interact with the host.
Third, constructing your own ASP.NET host program ASP.NET is the alternative technology of Microsoft ASP, so we focus on how to apply ASP.NET through web mode (obviously other ways), specific: we use .NET The platform's language is written in a console program, which launches an ASP.NET application environment to perform requests for ASPX. Specifically, you need to do the following: 1. Implement a web server to listen to all web requests, implement HTTP Web Hosting 2, start an application domain, create an ASP.NET ApplicationHost, create an ASP.NET application The domain, and the specific implementation class of HTTPWORKERREQUEST, which can process the ASPX request, compile the ASPX page, and the compiled managed code cache into the current application domain, then execute the code to get the execution result. It is recommended to carefully check the two categories of these two classes in the MSDN before continuing reading. System.Web.hosting.ApplicationHost class is used to create a separate application domain. Of course, it is not an ordinary application domain, but to establish an execution environment for ASP.NET, preparing the required space, data structure, etc. There is only one static method Static Object CreateApplicationHost (Type Host // Specific user implementation class, that is, the ASP.NET application domain requires load class string virtualdir, // This application field executes directory in the entire Web, virtual directory String PhysicalDir / / Corresponding physical directory); where the Host parameter points to a specific class, since the class actually belongs to the contact class between the two application domains, grouping data between two application domains, so you must inherit Since MARSHALBYREFOBJECT to allow access to application domain boundaries in support applications (as for why, recommendations 3). It can be seen that we need to start two application domains (Web Server feature application domains and ASP.NET application domains), and these two (application) domains are referenced by flow objects in cross-(application) domain. To achieve, the results executed in the ASP.NET domain can be returned to the requester through the web server domain. You can express the web server-side web client for executing ASP.NET approach.
Code Implementation Analysis: Using System; Using System.Web; Using System.Web.hosting; Using System.io; Using System.net; Using System.Text; Using System.Threading; Used System.Threading Download Admiral System.TESTEM.TET;
Namespace myiis {class asphostserver {[stathread] static void main (string [] args) {// creates and launched server myserver myserver = new myserver ("/", "c: // inetpub // wwwroot // myweb"); }
Class MyServer // Processing the HTTP Protocol Server Class {Private AspdotNethost AspnetHost; //asp.net Host's instance private tcplistener mytcp; // web listening socket Bool Bsvcrunning = true; // Service Whether running indication FISTREAM FS; // Processing the normal text of the HTTP request requires public myServer (String Virtualdir, vString realpath) {// Start the web listening service in the constructor try {mytcp = new TCPListener (8001); Mytcp.Start (); // Starting at 8001 port Monitor Console.WriteLine ("Service Start ..."); // creates a separate application domain using the createApplicationHost method to execute the ASP.NET program aspnetHost = (AspdotNethost) ApplicationHost (ASPDOTHOST), VIRTUALDIR, REALPATH); thread t = new thread (new ThreadStart (MainSvcThread)); t.Start (); // request service responsible for handling each thread starts a client} catch (NullReferenceException) {Console.WriteLine ( "NullReferenceException throwed!");}}
Public void mainsvcthread () //asp.net Host's main service thread {int S = 0; string strrequest; // request information string strdir; // Request directory string strrequestfile; // Request file name String Strerr = ""; // Error message string string string string strWeBroot = rpath; // Apply root directory Strream = ""; // Disk path string struponse = ""; // response response Buffer string strmsg = ""; // Format response information BYTE [] BS; // Output byte buffer while (bsvcrunning) {socket SCKET SCKET SCKET SCKET SCKETCP.ACCEPTSOCKET (); // Each request comes if (SCK. ("Client {0} Connected!", Sck.RemoteEndPoint; Byte [] BRECV = New Byte [1024]; // Buffer INT L = SCK.Receive (BRECV, BRECV.LENGTH, 0 String strbuf = encoding.default.getstring (brev); // Convert to string to facilitate analysis of s = strbuf.indexof ("http", 1); string httpver = strbuf.substring (s, 8); // StrRequest = strbuf.substring (0, s-1); strrequest.replace ("/////"); if (") <1) && (") <1) && (") <1) && (") <1) && (") StrRequest.endswith ("/"))) {strrequest = "/";} s = Strrequest.lastIndexOf ("/") 1; strrequestfile = strrequest.substring (s); strdir = strrequest.substring (strrequest.indexof ("/"), strrequest.lastindexof ("/") - 3); // Access URL if (strdir == ") {strdir = strWebroot;} else {strdir = strdir.replace (" / "," // "); strRealdir = strWebroot strdir;} console.writeline (" Client Request Dir: {0} ", strRealdir); if (strrequestfile.length ==
0) {strrequestfile = "default.htm"; // Default document} int ketLabytes = 0; // Total byte strRRESPONSE = ""; // output content strRealFile = strRealDir "//" strrequestfile; IF (strRealfile.endswith) // There is bug !! {string output = ""; // Note that the following statements have passed a ref type to the Host object ProcessRequest method, // aspnetHost Will perform a request from the ASP.NET execution application domain to return to the current Web Server, which actually occurs in a domain call aspnetHost.ProcessRequest (strrequestfile, ref output); // Convert to byte BS = system.text.Encoding.default.getBytes (output); itotlabytes = BS.LENGTH; // Calling socket will return WriteHeader (httpver, "text / html", ITOTLABYTES, "200 ok", Ref SCK); Flushbuf (BS, REF SCK);} else {try {fs = new filestream (strRealFile, filemode.open, fileaccess.read, fileshare.read); binaryreader reader = new binaryreader (fs); // Read BS = new byte [fs.length]; int RB; while ((RB = Reader.Read (BS, BS.Length))! = 0) {strresponse = strresponse encoding.default.getstring (BS, 0, RB ITOTLABYTES = ITTLABYTES RB;} reader.close (); fs.close (); WriteHeader (httpver, "text / html", itotlabytes, "200 ok", ref SCK; Flushbuf (BS, Ref SCK);} catch System.io.filenotFoundException) {// Assumption No file, report 404 Writehead (Httpver, "Text / HTML", ITOTLABYTES, "404 OK", Ref SCK;}}} Sck.Close (); // http Request end}} // WriteHeader wants the client to send HTTP header public void writeheader (String Ver, String Mime, Int Len, String Statucode, Ref socket SCK) {String BUF = "
IF (mime.length == 0) {mime = "text / html"; buf = buf ver statucode "/ r / n"; buf = buf "server: myiis" "/ r / n"; buf = BUF "Content-Type:" MIME "/ R / N"; buf = buf "accept-rabges: bytes" "/ r / n"; buf = buf "Content-length:" len "/ r / N / R / N "; byte [] BS = Encoding.default.getbytes (BUF); Flushbuf (BS, Ref SCK);}}
// Flushbuf Refresh Send Information Buffer Public Void Flushbuf to Customers (Byte [] BS, Ref Socket SCK) {INUM = 0; Try {IF (Sck.Connected) {IF ((Inum = Sck.send (BS, BS, BS) .Length, 0)) == - 1) {Console.writeline ("Flush Err: Send Data Err");} else {Console.writeline ("Send Bytes: {0}", Inum);}} else {Console .Writeline ("Client Diconnectioned!");}} Catch (Exception E) {Console.WriteLine ("Error: {0}", E);}}}
// ASPDOTNETHost class instances need to cross two application domain, so the inherited from MarshalByRefObject class ASPDOTNETHost: MarshalByRefObject {public void ProcessRequest (string fileName, ref string output) {MemoryStream ms = new MemoryStream (); // memory stream, of course, to speed StreamWriter SW = New StreamWriter (MS); // Output SW.AUTOFLUSH = true; // Set to Auto Refresh / First Constructing an HttpWorkRequest request class so that ASP.NET can analyze the request information while incoming an output stream object during the ASP.NET execution flow returns html HttpWorkerRequest worker = new SimpleWorkerRequest (fileName, "", sw); // scheduling a page, there's a lot of details included, followed by analysis HttpRuntime.ProcessRequest (worker); StreamReader sr = new StreamReader (ms); // Prepare to read MS.Position = 0 from the memory stream; // Move pointer to the head output = sr.readToEnd ();}}} httpruntime.processRequest (worker); What details are included? In general: 1. First, the Worker object is passed to the application domain of the ASP.NET, tells the request that has occurred for which ASPX file, and what the current directory is, if the output occurs during the execution, where should the output content? (SW object). This has a cross-(application) domain called by the current application domain of Web Server to our own ASP.NET application domain, which may also occur due to the first access, or the session event, or the session event. 2. ASP.NET's application domain detects if the requested ASPX file exists, does not exist, reports an error; if there is a code that exists in the code cache, if there is, and the ASP.NET detected You need to recompile, you will directly execute the code in the cache; if you do not exist or need to recompile, you need to read the ASPX file, compile it into a .NET code, deposit the cache. Some pages may have code and template separation into multiple files, even some resource files, which require read after compiling virtual machine code, and then execute in the hosted environment. 3. Perform the code in the compiled code cache in the ASP.NET, and the output data is output using the SW object. Of course, according to different configurations, there are also many details of the occurrence of calls / events. How to debug the program, observe the result? Establish a console type engineering, enter the code after completing the above code, copy the resulting program to the bin subdirectory of the start directory (such as c: / inetpub / wwwroot / myweb) as a site application, then start, which is created in it The ASP.NET application domain will not be wrong due to the assembly loading failed.
Create an ASP.NET Project In the directory, add the DEFAULT.HTM file and test Test.aspx, join .NET execution code, then start IE, enter: http://127.0.0.1: 8001 / Default .htm http://127.0.0.1:8001/test.aspx feels the execution process. Even the projects you can set up in the project, carefully debug and observe the details. Try a try in person, you must have a harvest! Fourth, the meaning of the ASP.NET host is a half-day ASP.NET host, what is the meaning of us? First, it is roughly from the code level to clearly analyze the details of ASP.NET, learn to understand the details, in addition to the ASP.NET failure can be accurately positioned and excluded, can help us write the ASP.NET application More efficient and robust code. Second, we can provide a thinking that we can run our ASP.NET program on a low configuration machine and detach from IIS. ASP.NET's "original" host IIS needs to run on Server OS, you know in the eyes of security experts, IIS can be one of the source of large hidden dangers. We can write many traditional programs to be written using ASP.NET, but detach from IIS independent execution, such as executing ASP.NET on Win98 systems. Web Server and ASP.NET are executed in the hosted environment, comparing ISAPI to establish a host and then execute, in addition to increasing efficiency, you can also use the rich management regulation function provided by the .NET platform, write the B / S program closer to traditional programs. This is a guarantee for programmers to be efficient (write code efficiency and performance efficiency). In addition, for items made by ASP.NET, you can easily develop debugging, run maintenance, installation. Even a normal desktop program, we can also write these interfaces and code through similar to making web pages, and then independently establish a Host environment in this example. Load execution of certain pages according to user interaction request, and then connect the interface to the client The component is displayed. You can get an instant compilation feature of ASP.NET and the ASP.NET host hosted environment, which is free to use API, which is easy to develop, install, and maintenance. After all, the managed environment is almost prepared for all the features you need.
V. References 1, .NET MSDN 2, Tsinghua University Press ".NET Network Advanced Programming" Andrew Krowczyk VionD Kumar Outdoor 3, Tsinghua University Press ".NET Framework Program (Revised Edition)" JSFFTRY RICHTER