blob: 2d7e9307bb91cc2862a7778cca6a1619d7a2caf9 [file] [log] [blame] [raw]
using RemoteView.PageHandlers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
namespace RemoteView {
sealed class Server : IDisposable {
/// <summary>
/// Keep list of all resources to be invoked according to received HTTP requests
/// </summary>
private Dictionary<String, AbstractPageHandler> decoder = new Dictionary<string, AbstractPageHandler> ();
/// <summary>
/// HTTP listener for server
/// </summary>
private HttpListener listener = new HttpListener ();
/// <summary>
/// Constructor
/// </summary>
public Server () {
// Homepage
decoder.Add ("", new HomePageHandler ());
decoder.Add ("home", new HomePageHandler ());
// javascript page handles client side clicks and screen image updates
decoder.Add ("script", new JavascriptPageHandler ());
// information about the system
decoder.Add ("info", new InfoPageHandler ());
// this pages process clicks into server side windows events
decoder.Add ("leftclick", new LeftClickPageHandler ());
decoder.Add ("rightclick", new RightClickPageHandler ());
decoder.Add ("mousemove", new MouseMovePageHandler ());
// image of choosen device as a png
decoder.Add ("screen", new ScreenPageHandler ());
// image of choosen device as a png
decoder.Add ("favicon.ico", new IconPageHandler ());
// 404 error page
decoder.Add ("404", new NotFoundPageHandler ());
}
/// <summary>
/// Start server
/// </summary>
/// <param name="port">port to listen to</param>
public Server Start (string address, int port) {
try {
Console.WriteLine ("Starting server at {0}:{1}", address, port);
listener.Prefixes.Add ("http://" + address + ":" + port + "/");
listener.IgnoreWriteExceptions = true;
listener.Start ();
new Thread (Start).Start ();
} catch {
Console.WriteLine ("Could not listen on port: {0}.", port);
}
return this;
}
/// <summary>
/// This where the server runs
/// </summary>
private void Start () {
do {
HttpListenerResponse response = null;
Stream output = null;
try {
// Note: The GetContext method blocks while waiting for a request.
HttpListenerContext context = listener.GetContext ();
#if DEBUG
Console.WriteLine (context.Request.RawUrl);
#endif
String[] uri = context.Request.RawUrl.Split ('/');
AbstractPageHandler page;
bool found = decoder.TryGetValue (uri [1], out page);
if (!found) {
// if page not found display 404 page
page = decoder ["404"];
}
response = context.Response;
byte[] buffer = page.HandleRequest (response, uri);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
output = response.OutputStream;
output.Write (buffer, 0, buffer.Length);
} catch (Exception e) {
if (listener.IsListening)
Console.WriteLine (e.Message);
} finally {
if (response != null) {
try {
if (output != null)
output.Close ();
} catch {
}
response.Close ();
}
}
} while (listener.IsListening);
}
/// <summary>
/// Stop server
/// </summary>
public void Stop () {
this.listener.Stop ();
}
/// <summary>
/// is server running?
/// </summary>
/// <returns></returns>
public bool IsRunning () {
return listener.IsListening;
}
public void Dispose () {
if (listener != null)
listener.Close ();
// some page handlers might need to be disposed
foreach (AbstractPageHandler page in decoder.Values) {
if (page is IDisposable) {
((IDisposable)page).Dispose ();
}
}
}
}
}