Removed the configuration with an App.config file from the HttpServer class

This commit is contained in:
sta 2013-07-24 17:23:48 +09:00
parent 998a296d18
commit cd7dfea62d
4 changed files with 103 additions and 140 deletions

View File

@ -49,6 +49,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AssemblyInfo.cs" /> <Compile Include="AssemblyInfo.cs" />

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Configuration;
using WebSocketSharp; using WebSocketSharp;
using WebSocketSharp.Net; using WebSocketSharp.Net;
using WebSocketSharp.Server; using WebSocketSharp.Server;
@ -9,59 +10,59 @@ namespace Example3
{ {
private static HttpServer _httpsv; private static HttpServer _httpsv;
public static void Main(string[] args) public static void Main (string [] args)
{ {
_httpsv = new HttpServer(4649); _httpsv = new HttpServer (4649);
#if DEBUG #if DEBUG
_httpsv.Log.Level = LogLevel.TRACE; _httpsv.Log.Level = LogLevel.TRACE;
#endif #endif
//_httpsv.RootPath = "../../Public"; _httpsv.RootPath = ConfigurationManager.AppSettings ["RootPath"];
//_httpsv.Sweeping = false; //_httpsv.Sweeping = false;
_httpsv.AddWebSocketService<Echo>("/Echo"); _httpsv.AddWebSocketService<Echo> ("/Echo");
_httpsv.AddWebSocketService<Chat>("/Chat"); _httpsv.AddWebSocketService<Chat> ("/Chat");
_httpsv.OnGet += (sender, e) => _httpsv.OnGet += (sender, e) =>
{ {
onGet(e); onGet (e);
}; };
_httpsv.OnError += (sender, e) => _httpsv.OnError += (sender, e) =>
{ {
Console.WriteLine(e.Message); Console.WriteLine (e.Message);
}; };
_httpsv.Start(); _httpsv.Start ();
Console.WriteLine("HTTP Server listening on port: {0} service path:", _httpsv.Port); Console.WriteLine ("HTTP Server listening on port: {0} service path:", _httpsv.Port);
foreach (var path in _httpsv.ServicePaths) foreach (var path in _httpsv.ServicePaths)
Console.WriteLine(" {0}", path); Console.WriteLine (" {0}", path);
Console.WriteLine(); Console.WriteLine ();
Console.WriteLine("Press enter key to stop server..."); Console.WriteLine ("Press enter key to stop the server...");
Console.ReadLine(); Console.ReadLine ();
_httpsv.Stop(); _httpsv.Stop ();
} }
private static byte[] getContent(string path) private static byte [] getContent (string path)
{ {
if (path == "/") if (path == "/")
path += "index.html"; path += "index.html";
return _httpsv.GetFile(path); return _httpsv.GetFile (path);
} }
private static void onGet(HttpRequestEventArgs eventArgs) private static void onGet (HttpRequestEventArgs eventArgs)
{ {
var request = eventArgs.Request; var request = eventArgs.Request;
var response = eventArgs.Response; var response = eventArgs.Response;
var content = getContent(request.RawUrl); var content = getContent (request.RawUrl);
if (content != null) if (content != null)
{ {
response.WriteContent(content); response.WriteContent (content);
return; return;
} }
response.StatusCode = (int)HttpStatusCode.NotFound; response.StatusCode = (int) HttpStatusCode.NotFound;
} }
} }
} }

View File

@ -28,38 +28,21 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using WebSocketSharp.Net; using WebSocketSharp.Net;
namespace WebSocketSharp.Server { namespace WebSocketSharp.Server
{
/// <summary> /// <summary>
/// Provides a simple HTTP server that allows to accept the WebSocket connection requests. /// Provides a simple HTTP server that allows to accept the WebSocket connection requests.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para>
/// The HttpServer instance can provide the multi WebSocket services. /// The HttpServer instance can provide the multi WebSocket services.
/// </para>
/// <para>
/// <para>
/// The HttpServer instance can set the document root path of server using
/// the application configuration file or <see cref="RootPath"/> property.
/// </para>
/// <code lang="xml">
/// &lt;?xml version="1.0" encoding="utf-8"?&gt;
/// &lt;configuration&gt;
/// &lt;appSettings&gt;
/// &lt;add key="RootPath" value="./Public" /&gt;
/// &lt;/appSettings&gt;
/// &lt;/configuration&gt;
/// </code>
/// </para>
/// </remarks> /// </remarks>
public class HttpServer { public class HttpServer
{
#region Private Fields #region Private Fields
private HttpListener _listener; private HttpListener _listener;
@ -79,8 +62,8 @@ namespace WebSocketSharp.Server {
/// Initializes a new instance of the <see cref="HttpServer"/> class that listens for incoming requests /// Initializes a new instance of the <see cref="HttpServer"/> class that listens for incoming requests
/// on port 80. /// on port 80.
/// </summary> /// </summary>
public HttpServer() public HttpServer ()
: this(80) : this (80)
{ {
} }
@ -91,10 +74,10 @@ namespace WebSocketSharp.Server {
/// <param name="port"> /// <param name="port">
/// An <see cref="int"/> that contains a port number. /// An <see cref="int"/> that contains a port number.
/// </param> /// </param>
public HttpServer(int port) public HttpServer (int port)
{ {
_port = port; _port = port;
init(); init ();
} }
#endregion #endregion
@ -118,7 +101,7 @@ namespace WebSocketSharp.Server {
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// The default logging level is the <see cref="LogLevel.ERROR"/>. /// The default logging level is the <see cref="LogLevel.ERROR"/>.
/// If you wanted to change the current logging level, you would set the <c>Log.Level</c> property /// If you want to change the current logging level, you set the <c>Log.Level</c> property
/// to one of the <see cref="LogLevel"/> values which you want. /// to one of the <see cref="LogLevel"/> values which you want.
/// </remarks> /// </remarks>
/// <value> /// <value>
@ -146,9 +129,8 @@ namespace WebSocketSharp.Server {
/// Gets or sets the document root path of server. /// Gets or sets the document root path of server.
/// </summary> /// </summary>
/// <value> /// <value>
/// An <see cref="string"/> that contains the document root path of server. /// A <see cref="string"/> that contains the document root path of server.
/// The default value is set from the application configuration file if is available; /// The default value is <c>./Public</c>.
/// otherwise, <c>./Public</c>.
/// </value> /// </value>
public string RootPath { public string RootPath {
get { get {
@ -249,178 +231,158 @@ namespace WebSocketSharp.Server {
#region Private Methods #region Private Methods
private void error(string message) private void error (string message)
{ {
OnError.Emit(this, new ErrorEventArgs(message)); OnError.Emit (this, new ErrorEventArgs (message));
} }
private void init() private void init ()
{ {
_listener = new HttpListener(); _listener = new HttpListener ();
_listening = false; _listening = false;
_logger = new Logger(); _logger = new Logger ();
_rootPath = getRootPath(); _rootPath = "./Public";
_svcHosts = new ServiceHostManager(); _svcHosts = new ServiceHostManager ();
_windows = false; _windows = false;
var os = Environment.OSVersion; var os = Environment.OSVersion;
if (os.Platform != PlatformID.Unix && os.Platform != PlatformID.MacOSX) if (os.Platform != PlatformID.Unix && os.Platform != PlatformID.MacOSX)
_windows = true; _windows = true;
var prefix = String.Format( var prefix = String.Format ("http{0}://*:{1}/", _port == 443 ? "s" : "", _port);
"http{0}://*:{1}/", _port == 443 ? "s" : String.Empty, _port); _listener.Prefixes.Add (prefix);
_listener.Prefixes.Add(prefix);
} }
private static string getRootPath() private void processHttpRequest (HttpListenerContext context)
{ {
string rootPath = null; var eventArgs = new HttpRequestEventArgs (context);
try {
rootPath = ConfigurationManager.AppSettings["RootPath"];
}
catch {
}
return rootPath.IsNullOrEmpty()
? "./Public"
: rootPath;
}
private void processHttpRequest(HttpListenerContext context)
{
var eventArgs = new HttpRequestEventArgs(context);
var method = context.Request.HttpMethod; var method = context.Request.HttpMethod;
if (method == "GET" && OnGet != null) if (method == "GET" && OnGet != null)
{ {
OnGet(this, eventArgs); OnGet (this, eventArgs);
return; return;
} }
if (method == "HEAD" && OnHead != null) if (method == "HEAD" && OnHead != null)
{ {
OnHead(this, eventArgs); OnHead (this, eventArgs);
return; return;
} }
if (method == "POST" && OnPost != null) if (method == "POST" && OnPost != null)
{ {
OnPost(this, eventArgs); OnPost (this, eventArgs);
return; return;
} }
if (method == "PUT" && OnPut != null) if (method == "PUT" && OnPut != null)
{ {
OnPut(this, eventArgs); OnPut (this, eventArgs);
return; return;
} }
if (method == "DELETE" && OnDelete != null) if (method == "DELETE" && OnDelete != null)
{ {
OnDelete(this, eventArgs); OnDelete (this, eventArgs);
return; return;
} }
if (method == "OPTIONS" && OnOptions != null) if (method == "OPTIONS" && OnOptions != null)
{ {
OnOptions(this, eventArgs); OnOptions (this, eventArgs);
return; return;
} }
if (method == "TRACE" && OnTrace != null) if (method == "TRACE" && OnTrace != null)
{ {
OnTrace(this, eventArgs); OnTrace (this, eventArgs);
return; return;
} }
if (method == "CONNECT" && OnConnect != null) if (method == "CONNECT" && OnConnect != null)
{ {
OnConnect(this, eventArgs); OnConnect (this, eventArgs);
return; return;
} }
if (method == "PATCH" && OnPatch != null) if (method == "PATCH" && OnPatch != null)
{ {
OnPatch(this, eventArgs); OnPatch (this, eventArgs);
return; return;
} }
context.Response.StatusCode = (int)HttpStatusCode.NotImplemented; context.Response.StatusCode = (int) HttpStatusCode.NotImplemented;
} }
private bool processWebSocketRequest(HttpListenerContext context) private bool processWebSocketRequest (HttpListenerContext context)
{ {
var wsContext = context.AcceptWebSocket(); var wsContext = context.AcceptWebSocket ();
var path = wsContext.Path.UrlDecode(); var path = wsContext.Path.UrlDecode ();
IServiceHost svcHost; IServiceHost svcHost;
if (!_svcHosts.TryGetServiceHost(path, out svcHost)) if (!_svcHosts.TryGetServiceHost (path, out svcHost))
{ {
context.Response.StatusCode = (int)HttpStatusCode.NotImplemented; context.Response.StatusCode = (int) HttpStatusCode.NotImplemented;
return false; return false;
} }
wsContext.WebSocket.Log = _logger; wsContext.WebSocket.Log = _logger;
svcHost.BindWebSocket(wsContext); svcHost.BindWebSocket (wsContext);
return true; return true;
} }
private void processRequestAsync(HttpListenerContext context) private void processRequestAsync (HttpListenerContext context)
{ {
WaitCallback callback = (state) => WaitCallback callback = state =>
{ {
try try {
{ if (context.Request.IsUpgradeTo ("websocket"))
if (context.Request.IsUpgradeTo("websocket"))
{ {
if (processWebSocketRequest(context)) if (processWebSocketRequest (context))
return; return;
} }
else else
{ {
processHttpRequest(context); processHttpRequest (context);
} }
context.Response.Close(); context.Response.Close ();
} }
catch (Exception ex) catch (Exception ex) {
{ _logger.Fatal (ex.Message);
_logger.Fatal(ex.Message); error ("An exception has occured.");
error("An exception has occured.");
} }
}; };
ThreadPool.QueueUserWorkItem(callback); ThreadPool.QueueUserWorkItem (callback);
} }
private void receiveRequest() private void receiveRequest ()
{ {
while (true) while (true)
{ {
try try {
{ processRequestAsync (_listener.GetContext ());
processRequestAsync(_listener.GetContext());
} }
catch (HttpListenerException) catch (HttpListenerException) {
{ _logger.Info ("HttpListener has been stopped.");
// HttpListener has been closed.
break; break;
} }
catch (Exception ex) catch (Exception ex) {
{ _logger.Fatal (ex.Message);
_logger.Fatal(ex.Message); error ("An exception has occured.");
error("An exception has occured.");
break; break;
} }
} }
} }
private void startReceiveRequestThread() private void startReceiveRequestThread ()
{ {
_receiveRequestThread = new Thread(new ThreadStart(receiveRequest)); _receiveRequestThread = new Thread (new ThreadStart (receiveRequest));
_receiveRequestThread.IsBackground = true; _receiveRequestThread.IsBackground = true;
_receiveRequestThread.Start(); _receiveRequestThread.Start ();
} }
#endregion #endregion
@ -428,7 +390,7 @@ namespace WebSocketSharp.Server {
#region Public Methods #region Public Methods
/// <summary> /// <summary>
/// Adds the specified type WebSocket service. /// Adds the specified typed WebSocket service.
/// </summary> /// </summary>
/// <param name="absPath"> /// <param name="absPath">
/// A <see cref="string"/> that contains an absolute path associated with the WebSocket service. /// A <see cref="string"/> that contains an absolute path associated with the WebSocket service.
@ -436,24 +398,24 @@ namespace WebSocketSharp.Server {
/// <typeparam name="T"> /// <typeparam name="T">
/// The type of the WebSocket service. The T must inherit the <see cref="WebSocketService"/> class. /// The type of the WebSocket service. The T must inherit the <see cref="WebSocketService"/> class.
/// </typeparam> /// </typeparam>
public void AddWebSocketService<T>(string absPath) public void AddWebSocketService<T> (string absPath)
where T : WebSocketService, new() where T : WebSocketService, new ()
{ {
string msg; string msg;
if (!absPath.IsValidAbsolutePath(out msg)) if (!absPath.IsValidAbsolutePath (out msg))
{ {
_logger.Error(msg); _logger.Error (msg);
error(msg); error (msg);
return; return;
} }
var svcHost = new WebSocketServiceHost<T>(_logger); var svcHost = new WebSocketServiceHost<T> (_logger);
svcHost.Uri = absPath.ToUri(); svcHost.Uri = absPath.ToUri ();
if (!Sweeping) if (!Sweeping)
svcHost.Sweeping = false; svcHost.Sweeping = false;
_svcHosts.Add(absPath, svcHost); _svcHosts.Add (absPath, svcHost);
} }
/// <summary> /// <summary>
@ -466,41 +428,41 @@ namespace WebSocketSharp.Server {
/// <param name="path"> /// <param name="path">
/// A <see cref="string"/> that contains a virtual path to the file to get. /// A <see cref="string"/> that contains a virtual path to the file to get.
/// </param> /// </param>
public byte[] GetFile(string path) public byte[] GetFile (string path)
{ {
var filePath = _rootPath + path; var filePath = _rootPath + path;
if (_windows) if (_windows)
filePath = filePath.Replace("/", "\\"); filePath = filePath.Replace ("/", "\\");
return File.Exists(filePath) return File.Exists (filePath)
? File.ReadAllBytes(filePath) ? File.ReadAllBytes (filePath)
: null; : null;
} }
/// <summary> /// <summary>
/// Starts to receive the HTTP requests. /// Starts to receive the HTTP requests.
/// </summary> /// </summary>
public void Start() public void Start ()
{ {
if (_listening) if (_listening)
return; return;
_listener.Start(); _listener.Start ();
startReceiveRequestThread(); startReceiveRequestThread ();
_listening = true; _listening = true;
} }
/// <summary> /// <summary>
/// Stops receiving the HTTP requests. /// Stops receiving the HTTP requests.
/// </summary> /// </summary>
public void Stop() public void Stop ()
{ {
if (!_listening) if (!_listening)
return; return;
_listener.Close(); _listener.Close ();
_receiveRequestThread.Join(5 * 1000); _receiveRequestThread.Join (5 * 1000);
_svcHosts.Stop(); _svcHosts.Stop ();
_listening = false; _listening = false;
} }

View File

@ -59,7 +59,6 @@
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.ServiceModel" /> <Reference Include="System.ServiceModel" />
<Reference Include="System.Configuration" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AssemblyInfo.cs" /> <Compile Include="AssemblyInfo.cs" />