Just a few short notes on the code.. It consists of an asynchronous and multithreaded webserver that can handle multiple simultaneous connections. The web server class (SimpleWebServer) has a Start() and a Stop() method that facilitates HttpListener- and thread management. It also exposes an event that is raised for each incoming request. The code itself is pretty self explanatory but here is a link to the MSDN documentation on the HttpListener Class.
class Program
{
static void Main(string[] args)
{
var ws = new SimpleWebServer("http://localhost:666/Simple/");
ws.RequestReceived += (sender, context) =>
{
var buffer = System.Text.Encoding.Default.GetBytes("Scattered I walk towards the fractured light. " + DateTime.Now);
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.OutputStream.Close();
};
ws.Start();
Console.WriteLine("Listening to http://localhost:666/Simple/");
Console.WriteLine("Press any key to stop...");
Console.ReadLine();
ws.Stop();
}
}
class SimpleWebServer
{
public delegate void RequestReceivedHandler(object sender, HttpListenerContext context);
public event RequestReceivedHandler RequestReceived;
private readonly HttpListener _listener;
private bool _running;
private readonly Thread _connthread;
public SimpleWebServer(string prefix)
{
_listener = new HttpListener();
_listener.Prefixes.Add(prefix);
_connthread = new Thread(ConnectionThread);
}
public void Start()
{
_connthread.Start();
}
public void Stop()
{
_running = false;
_listener.Stop();
}
private void ConnectionThread()
{
try
{
_running = true;
_listener.Start();
while (_running)
ProcessRequest();
}
catch (HttpListenerException) { }
catch (ThreadAbortException) { }
catch (Exception) { }
}
private void ProcessRequest()
{
IAsyncResult result = _listener.BeginGetContext(ListenerCallback, _listener);
result.AsyncWaitHandle.WaitOne();
}
protected void ListenerCallback(IAsyncResult result)
{
if (_listener == null || !_listener.IsListening) return;
var context = _listener.EndGetContext(result);
OnRequestReceived(context);
}
private void OnRequestReceived(HttpListenerContext context)
{
if (RequestReceived != null) RequestReceived(this, context);
}
}
This is a very good starting point. However, I see a little problem with this. When you write to the output stream, you assume the stream is still open. That may not be always the case because the client might close the connection while you are generating the output. I do not know how to fix this beside a messy try ... catch. How can we tell if the output stream is still open?
SvaraRadera