Implement your own ASP.net host system

Source: Internet
Author: User
Tags http request implement socket thread hosting web hosting net domain root directory
asp.net to implement its own ASP.net host system

Yang Shan Mountains and rivers

I. The concept of host
Hosting is. NET is a very basic concept, all of them. NET application code to fully function requires access to the managed Environment (CLR--common Language Runtime), which is actually referred to as the host (host) to be started. NET code is prepared. For the time being, there are 3 types of stored procedures on the Windows system that can take this responsibility:
1, Shell (usually explorer), provided from the user's desktop to boot. NET program to create a process that initiates the process to establish the CLR
2, browser host (Internet Explorer), processing from the Web download. NET code execution.
3, server host (for example, IIS worker process aspnet_wp.exe)
Generally speaking, the ASP.net program we develop is run in the context of IIS (in fact, the CLR is started by an ISAPI control), but in practice the ASP.net program can get rid of IIS running in any managed environment alone. This article discusses how ASP.net programs can be launched in a custom environment, hoping to help us understand how asp.net works, while enabling the asp.net we develop to execute in any. NET environment, whether it is a server operating system or a normal desktop operating system.

Ii. execution analysis of asp.net in IIS hosts
About the implementation of ASP.net in IIS details, many articles do a detailed authoritative analysis, this article does not intend to repeat, here are some references:
Http://www.yesky.com/SoftChannel/72342380468043776/20030924/1731387.shtml
Http://chs.gotdotnet.com/quickstart/ASPplus/doc/procmodel.ASPx
These articles roughly focus on how the host ring will start, ASP. NET applications how to generate assemblies, how to load, and how to interact with the host.

Third, construct own ASP.net host program
Asp. NET is a Microsoft ASP's substitution technology appears, So we'll focus on how to apply ASP.net through the web (obviously there are other ways), specifically: We write a console program in the language of the. NET platform, which launches a ASP.net application environment and executes requests for ASPX. Specifically, the following work needs to be done:
1, the implementation of a Web Server, listening to all Web requests, the implementation of HTTP web hosting
2, start an application domain, Create a asp.net applicationhost, build a asp.net application domain, and create a HttpWorkerRequest implementation class that can handle ASPX requests, compile ASPX pages, cache compiled managed code into the current application domain, and then execute Code to get execution results. It is recommended that you carefully review the two classes in MSDN for reference before continuing with the reading below.
The System.Web.Hosting.ApplicationHost class is used to establish a separate application domain. Of course, it is not an ordinary application domain, but to build an execution environment for ASP.net, to prepare the required space, data structure, etc. There is only one static method static object Createapplicationhost (
Type host//specific user implementation class is the class that the ASP.net application domain needs to load
String Virtualdir,//The execution directory of this application domain throughout the Web, virtual directory
String Physicaldir//corresponding physical directory
);
The host parameter points to a specific class, and since the class actually belongs to a contact class between two application domains, it is necessary to inherit from the MarshalByRefObject by marshalling data between two application domains. To allow access across application domain boundaries in the supporting application (for why, it is recommended that you check reference 3).
As you can see, we need to start two application domains (Web server functional application domain and asp.net application domain), and these two (application) domains are implemented through stream object references across (application) domains, so that the results executed in the ASP.net domain can be performed through the web The server domain is returned to the requester.
Can be roughly shown below
Execute asp.net Web server side










Web Client

Code Implementation Analysis:
Using System;
Using System.Web;
Using System.Web.Hosting;
Using System.IO;
Using System.Net;
Using System.NET.Sockets;
Using System.Text;
Using System.Threading;

Namespace Myiis
{
Class Asphostserver
{
[STAThread]
static void Main (string[] args)
{
Creating and starting a server
MyServer myserver=new MyServer ("/", "C:\\inetpub\\wwwroot\\myweb");
}
}

Class MyServer//handling HTTP protocol server classes
{
Private Aspdotnethost Aspnethost; Instance of ASP.net host
Private TcpListener mytcp; Web listening sockets
BOOL Bsvcrunning=true; Whether the service is running instructions
FileStream FS; Normal text requirements for processing HTTP requests

Public MyServer (String virtualdir, vstring Realpath)
{//Start the Web listening service in the constructor
Try
{
Mytcp=new TcpListener (8001);
Mytcp. Start (); Start monitoring on port 8001.
Console.WriteLine ("Service startup ...");
Using the Createapplicationhost method to establish a separate application domain to execute the asp.net program
Aspnethost = (aspdotnethost) applicationhost.createapplicationhost
(typeof (Aspdotnethost), Virtualdir, Realpath);
Thread T=new Thread (new ThreadStart (Mainsvcthread));
T.start (); The service thread initiates a request for processing each client
}
catch (NullReferenceException)
{
Console.WriteLine ("NullReferenceException throwed!");
}
}

The primary service thread for the Web server of the public void Mainsvcthread ()//asp.net host
{
int s=0;
String strrequest; Request Information
String Strdir; The requested Directory
String Strrequestfile; File name of the request
String Strerr= ""; Error message
String Strrealdir; Actual directory
String Strwebroot=rpath; Apply root directory
String Strrealfile= ""; Disk path of the file being requested
String Strresponse= ""; Respond to response buffer
String Strmsg= ""; Format Response Information
Byte[] BS; Output byte buffers

while (bsvcrunning)
{
Socket sck=mytcp. AcceptSocket (); Each request arrives
if (sck. Connected)
{
Console.WriteLine ("Client {0} connected!", sck.) Remoteendpoint);
Byte[] Brecv=new byte[1024]; Buffer
int l=sck. Receive (brecv,brecv.length,0);
String strbuf=encoding.default.getstring (BRECV); Convert to string for easy analysis
S=strbuf.indexof ("HTTP", 1);
String httpver=strbuf.substring (s,8); http/1.1 or something.
Strrequest=strbuf.substring (0,S-1);
Strrequest.replace ("\", "/");
if ((Strrequest.indexof (".") <1) && (!strrequest.endswith ("/"))
{
Strrequest + = "/";
}
S=strrequest.lastindexof ("/") +1;
Strrequestfile = strrequest.substring (s); Strdir=strrequest.substring (Strrequest.indexof ("/"), Strrequest.lastindexof ("/")-3); Gets the URL of the access
if (strdir== "/")
{
Strrealdir=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 itotlabytes=0; Total bytes needed for output
Strresponse= ""; Output content
Strrealfile = Strrealdir + "\" + strrequestfile;
if (Strrealfile.endswith) (". ASPx ")//Here's bug!!.
{
String output= "";
Notice that my following statements pass a ref-type argument to the Host object ProcessRequest method.
Aspnethost executes a request from the ASP.net execution application domain and returns the stream to the domain where the current Web server resides, which actually takes place between a domain call
Aspnethost.processrequest (strrequestfile, ref output);//convert to byte stream
Bs=system.text.encoding.default.getbytes (output);
Itotlabytes=bs. Length; Call socket will perform result return
Writeheader (Httpver, "text/html", Itotlabytes, "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,0,bs. Length))!=0)
{
Strresponse =strresponse +encoding.default.getstring (BS,0,RB);
Itotlabytes =ITOTLABYTES+RB;
}
Reader. Close ();
Fs. Close ();
Writeheader (Httpver, "text/html", Itotlabytes, "OK", ref sck);
Flushbuf (Bs,ref sck);
}
catch (System.IO.FileNotFoundException)
{//Assuming no files are found, report 404 Writeheader (Httpver, "text/html", itotlabytes, "404 OK", ref sck);
}
}
}
Sck. Close (); End of HTTP request
}
}

Writeheader want the client to send HTTP headers
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 sends the information buffer to the customer
public void Flushbuf (byte[] bs,ref Socket sck)
{
int inum=0;
Try
{
if (sck. Connected)
{
if (inum=sck. Send (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 span two application domains, so inherit from MarshalByRefObject
Class Aspdotnethost:marshalbyrefobject
{
public void ProcessRequest (string fileName, ref string output)
{
MemoryStream ms=new MemoryStream (); Memory stream, of course, for speed
StreamWriter sw = new StreamWriter (MS); Output
Sw. AutoFlush = true; Set to automatic refresh/First construct a Httpworkrequest request class so that ASP.net can parse get request information and pass in an output stream object for ASP.net to return the HTML stream during execution
HttpWorkerRequest worker = new SimpleWorkerRequest (FileName, "", SW); Schedule a page, which contains a lot of details, followed by an analysis
Httpruntime.processrequest (worker);
StreamReader sr= New StreamReader (MS); Preparing to read from the memory stream
Ms. Position = 0; Move Pointer to head
Output = Sr. ReadToEnd ();
}
}
}
Httpruntime.processrequest (worker), including the details? Generally as follows:
1. First, the worker object is passed to the asp.net application domain to tell what ASPX file was requested and what the current directory is, if the output that occurred during execution should be written to (SW object). This occurs with a cross (application) domain call from the Web server's current application domain to the asp.net application domain that we have established, and possibly because of the first access, global events, or session events, and so on.
2, ASP. NET will detect if the requested ASPX file exists, does not exist, and if so, to see if the code cache has the last compiled code. If it exists and ASP.net detects that no recompilation is required, the code in the cache is executed directly; if it does not exist or the code expires and needs to be recompiled, the ASPX file needs to be read, compiled into. NET code, and cached. Some pages may exist where code and templates are separated into multiple files, even some resource files that need to be read and compiled. NET virtual machine code, and then executes it in a managed environment.
3, the implementation of ASP.net code cache code, output data using the SW object output.
Of course, depending on the configuration, there are many different ways of calling/event occurrences.
How to debug and run the above program, observe the results?
Build a console type project, compile the above code, copy the resulting program into the bin subdirectory of the site application starting directory (such as C:\Inetpub\Wwwroot\MyWeb), and then start, This creates an ASP.net application domain that does not make an error because the assembly failed to load. Create a asp.net project in the directory, add default.htm files and test test.aspx, join. NET execution code, and then start IE, enter the address bar separately: http://127.0.0.1:8001/default.htm Http://127.0.0.1:8001/test.aspx feel the execution process. Even you can set up a breakpoint in a project like this, carefully debug and observe the details. Try it with your own hands, there must be a harvest!

Iv. the significance of constructing ASP.net host
How does it make sense for us to spend half a day on our own asp.net host?
First of all, it is a clear analysis of asp.net execution details from the code level, learning the details of the execution itself, in addition to being able to pinpoint and exclude asp.net failures, and to help us write more efficient and robust code when writing asp.net applications.
Second, we can provide a way to run our ASP.net program on a low configuration machine and get out of IIS. Asp. NET's "original" host IIS needs to run on the server OS, and you know that in the eyes of security experts, IIS is one of the sources of great pitfalls. Many traditional programs can be written using asp.net, but run independently from IIS, such as executing asp.net on a win98 system. Both Web server and asp.net are executed in a managed environment, compared to the ISAPI build host and then execute, in addition to improving efficiency, you can also use the rich management and control functions provided by the. NET platform, write B/s programs closer to the traditional programming method, This is a guarantee for programmers of efficiency (the efficiency of writing code and the effectiveness of execution).
In addition, for the use of ASP.net to do the project, we can be very convenient for the development of debugging, operation maintenance, installation. Even for ordinary desktop programs, we can write these interfaces and code in a similar way to create a Web page, and then independently build the host environment in this example, execute some pages based on user interaction requests, and then display the interface through the relevant components on the client side. You can get ASP.net's just-in-time compilation capabilities and ASP.net hosting environment, a large number of freely available APIs for easy development, installation, and maintenance. After all, the hosting environment is almost ready for everything you need.

V. reference materials
1. NET MSDN
2, Tsinghua University Press ". NET Network Advanced Programming "Andrew Krowczyk Viond Kumar Original
3, Tsinghua University Press ". NET Framework Program Design (revised edition) "Jsfftry Richter





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.