Added logging
This commit is contained in:
@@ -64,6 +64,7 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
private HttpListener _listener;
|
||||
private bool _listening;
|
||||
private Logger _logger;
|
||||
private int _port;
|
||||
private Thread _receiveRequestThread;
|
||||
private string _rootPath;
|
||||
@@ -112,6 +113,23 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logging functions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
/// to one of the <see cref="LogLevel"/> values which you want.
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// A <see cref="Logger"/> that provides the logging functions.
|
||||
/// </value>
|
||||
public Logger Log {
|
||||
get {
|
||||
return _logger;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the port on which to listen for incoming requests.
|
||||
/// </summary>
|
||||
@@ -231,10 +249,16 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void error(string message)
|
||||
{
|
||||
OnError.Emit(this, new ErrorEventArgs(message));
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
_listener = new HttpListener();
|
||||
_listening = false;
|
||||
_logger = new Logger();
|
||||
_rootPath = getRootPath();
|
||||
_svcHosts = new ServiceHostManager();
|
||||
|
||||
@@ -262,103 +286,107 @@ namespace WebSocketSharp.Server {
|
||||
: rootPath;
|
||||
}
|
||||
|
||||
private void onError(string message)
|
||||
private void processHttpRequest(HttpListenerContext context)
|
||||
{
|
||||
#if DEBUG
|
||||
var callerFrame = new StackFrame(1);
|
||||
var caller = callerFrame.GetMethod();
|
||||
Console.WriteLine("HTTPSV: Error@{0}: {1}", caller.Name, message);
|
||||
#endif
|
||||
OnError.Emit(this, new ErrorEventArgs(message));
|
||||
}
|
||||
|
||||
private void onRequest(HttpListenerContext context)
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
var eventArgs = new HttpRequestEventArgs(context);
|
||||
|
||||
if (req.HttpMethod == "GET" && !OnGet.IsNull())
|
||||
var method = context.Request.HttpMethod;
|
||||
if (method == "GET" && OnGet != null)
|
||||
{
|
||||
OnGet(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "HEAD" && !OnHead.IsNull())
|
||||
if (method == "HEAD" && OnHead != null)
|
||||
{
|
||||
OnHead(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "POST" && !OnPost.IsNull())
|
||||
if (method == "POST" && OnPost != null)
|
||||
{
|
||||
OnPost(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "PUT" && !OnPut.IsNull())
|
||||
if (method == "PUT" && OnPut != null)
|
||||
{
|
||||
OnPut(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "DELETE" && !OnDelete.IsNull())
|
||||
if (method == "DELETE" && OnDelete != null)
|
||||
{
|
||||
OnDelete(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "OPTIONS" && !OnOptions.IsNull())
|
||||
if (method == "OPTIONS" && OnOptions != null)
|
||||
{
|
||||
OnOptions(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "TRACE" && !OnTrace.IsNull())
|
||||
if (method == "TRACE" && OnTrace != null)
|
||||
{
|
||||
OnTrace(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "CONNECT" && !OnConnect.IsNull())
|
||||
if (method == "CONNECT" && OnConnect != null)
|
||||
{
|
||||
OnConnect(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.HttpMethod == "PATCH" && !OnPatch.IsNull())
|
||||
if (method == "PATCH" && OnPatch != null)
|
||||
{
|
||||
OnPatch(this, eventArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
res.StatusCode = (int)HttpStatusCode.NotImplemented;
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotImplemented;
|
||||
}
|
||||
|
||||
private bool processWebSocketRequest(HttpListenerContext context)
|
||||
{
|
||||
var wsContext = context.AcceptWebSocket();
|
||||
var path = wsContext.Path.UrlDecode();
|
||||
|
||||
IServiceHost svcHost;
|
||||
if (!_svcHosts.TryGetServiceHost(path, out svcHost))
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotImplemented;
|
||||
return false;
|
||||
}
|
||||
|
||||
wsContext.WebSocket.Log = _logger;
|
||||
svcHost.BindWebSocket(wsContext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void processRequestAsync(HttpListenerContext context)
|
||||
{
|
||||
WaitCallback callback = (state) =>
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
|
||||
try
|
||||
{
|
||||
if (req.IsUpgradeTo("websocket"))
|
||||
if (context.Request.IsUpgradeTo("websocket"))
|
||||
{
|
||||
if (upgradeToWebSocket(context))
|
||||
if (processWebSocketRequest(context))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
onRequest(context);
|
||||
processHttpRequest(context);
|
||||
}
|
||||
|
||||
res.Close();
|
||||
context.Response.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
onError(ex.Message);
|
||||
_logger.Fatal(ex.Message);
|
||||
error("An exception has occured.");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -371,8 +399,7 @@ namespace WebSocketSharp.Server {
|
||||
{
|
||||
try
|
||||
{
|
||||
var context = _listener.GetContext();
|
||||
processRequestAsync(context);
|
||||
processRequestAsync(_listener.GetContext());
|
||||
}
|
||||
catch (HttpListenerException)
|
||||
{
|
||||
@@ -381,7 +408,9 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
onError(ex.Message);
|
||||
_logger.Fatal(ex.Message);
|
||||
error("An exception has occured.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -394,23 +423,6 @@ namespace WebSocketSharp.Server {
|
||||
_receiveRequestThread.Start();
|
||||
}
|
||||
|
||||
private bool upgradeToWebSocket(HttpListenerContext context)
|
||||
{
|
||||
var res = context.Response;
|
||||
var wsContext = context.AcceptWebSocket();
|
||||
var path = wsContext.Path.UrlDecode();
|
||||
|
||||
IServiceHost svcHost;
|
||||
if (!_svcHosts.TryGetServiceHost(path, out svcHost))
|
||||
{
|
||||
res.StatusCode = (int)HttpStatusCode.NotImplemented;
|
||||
return false;
|
||||
}
|
||||
|
||||
svcHost.BindWebSocket(wsContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
@@ -430,11 +442,13 @@ namespace WebSocketSharp.Server {
|
||||
string msg;
|
||||
if (!absPath.IsValidAbsolutePath(out msg))
|
||||
{
|
||||
onError(msg);
|
||||
_logger.Error(msg);
|
||||
error(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var svcHost = new WebSocketServiceHost<T>();
|
||||
var svcHost = new WebSocketServiceHost<T>(_logger);
|
||||
svcHost.Uri = absPath.ToUri();
|
||||
if (!Sweeping)
|
||||
svcHost.Sweeping = false;
|
||||
|
@@ -194,6 +194,7 @@ namespace WebSocketSharp.Server {
|
||||
var ws = context.WebSocket;
|
||||
var path = context.Path.UrlDecode();
|
||||
|
||||
ws.Log = Log;
|
||||
IServiceHost svcHost;
|
||||
if (!_svcHosts.TryGetServiceHost(path, out svcHost))
|
||||
{
|
||||
@@ -226,11 +227,13 @@ namespace WebSocketSharp.Server {
|
||||
string msg;
|
||||
if (!absPath.IsValidAbsolutePath(out msg))
|
||||
{
|
||||
Log.Error(msg);
|
||||
Error(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var svcHost = new WebSocketServiceHost<T>();
|
||||
var svcHost = new WebSocketServiceHost<T>(Log);
|
||||
svcHost.Uri = BaseUri.IsAbsoluteUri
|
||||
? new Uri(BaseUri, absPath)
|
||||
: absPath.ToUri();
|
||||
|
@@ -47,6 +47,7 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
private IPAddress _address;
|
||||
private bool _listening;
|
||||
private Logger _logger;
|
||||
private int _port;
|
||||
private Thread _receiveRequestThread;
|
||||
private bool _secure;
|
||||
@@ -61,14 +62,33 @@ namespace WebSocketSharp.Server {
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This constructor initializes a new instance of this class as non self host.
|
||||
/// </remarks>
|
||||
protected WebSocketServerBase()
|
||||
: this(new Logger())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class
|
||||
/// with the specified <paramref name="logger"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This constructor initializes a new instance of this class as non self host.
|
||||
/// </remarks>
|
||||
/// <param name="logger">
|
||||
/// A <see cref="Logger"/> that provides the logging functions.
|
||||
/// </param>
|
||||
protected WebSocketServerBase(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_selfHost = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class that listens for incoming connection attempts
|
||||
/// on the specified WebSocket URL.
|
||||
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class
|
||||
/// that listens for incoming connection attempts on the specified WebSocket URL.
|
||||
/// </summary>
|
||||
/// <param name="url">
|
||||
/// A <see cref="string"/> that contains a WebSocket URL.
|
||||
@@ -93,8 +113,9 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class that listens for incoming connection attempts
|
||||
/// on the specified <paramref name="address"/>, <paramref name="port"/>, <paramref name="absPath"/> and <paramref name="secure"/>.
|
||||
/// Initializes a new instance of the <see cref="WebSocketServerBase"/> class
|
||||
/// that listens for incoming connection attempts on the specified <paramref name="address"/>,
|
||||
/// <paramref name="port"/>, <paramref name="absPath"/> and <paramref name="secure"/>.
|
||||
/// </summary>
|
||||
/// <param name="address">
|
||||
/// A <see cref="IPAddress"/> that contains a local IP address.
|
||||
@@ -106,21 +127,22 @@ namespace WebSocketSharp.Server {
|
||||
/// A <see cref="string"/> that contains an absolute path.
|
||||
/// </param>
|
||||
/// <param name="secure">
|
||||
/// A <see cref="bool"/> that indicates providing a secure connection or not. (<c>true</c> indicates providing a secure connection.)
|
||||
/// A <see cref="bool"/> that indicates providing a secure connection or not.
|
||||
/// (<c>true</c> indicates providing a secure connection.)
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Either <paramref name="address"/> or <paramref name="absPath"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <para>
|
||||
/// <paramref name="absPath"/> is invalid.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Pair of <paramref name="port"/> and <paramref name="secure"/> is invalid.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <paramref name="absPath"/> is invalid.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// -or-
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Pair of <paramref name="port"/> and <paramref name="secure"/> is invalid.
|
||||
/// </para>
|
||||
/// </exception>
|
||||
protected WebSocketServerBase(IPAddress address, int port, string absPath, bool secure)
|
||||
{
|
||||
@@ -222,6 +244,30 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logging functions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
/// to one of the <see cref="LogLevel"/> values which you want.
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// A <see cref="Logger"/> that provides the logging functions.
|
||||
/// </value>
|
||||
public Logger Log {
|
||||
get {
|
||||
return _logger;
|
||||
}
|
||||
|
||||
internal set {
|
||||
if (value == null)
|
||||
return;
|
||||
|
||||
_logger = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the port on which to listen for incoming connection attempts.
|
||||
/// </summary>
|
||||
@@ -247,9 +293,15 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void error(string message)
|
||||
{
|
||||
OnError.Emit(this, new ErrorEventArgs(message));
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
_listening = false;
|
||||
_logger = new Logger();
|
||||
_selfHost = true;
|
||||
_tcpListener = new TcpListener(_address, _port);
|
||||
}
|
||||
@@ -268,16 +320,6 @@ namespace WebSocketSharp.Server {
|
||||
init();
|
||||
}
|
||||
|
||||
private void onError(string message)
|
||||
{
|
||||
#if DEBUG
|
||||
var callerFrame = new StackFrame(1);
|
||||
var caller = callerFrame.GetMethod();
|
||||
Console.WriteLine("WSSV: Error@{0}: {1}", caller.Name, message);
|
||||
#endif
|
||||
OnError.Emit(this, new ErrorEventArgs(message));
|
||||
}
|
||||
|
||||
private void processRequestAsync(TcpListenerWebSocketContext context)
|
||||
{
|
||||
WaitCallback callback = (state) =>
|
||||
@@ -288,7 +330,8 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
onError(ex.Message);
|
||||
_logger.Fatal(ex.Message);
|
||||
error("An exception has occured.");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -301,8 +344,7 @@ namespace WebSocketSharp.Server {
|
||||
{
|
||||
try
|
||||
{
|
||||
var context = _tcpListener.AcceptWebSocket(_secure);
|
||||
processRequestAsync(context);
|
||||
processRequestAsync(_tcpListener.AcceptWebSocket(_secure));
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
@@ -311,7 +353,9 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
onError(ex.Message);
|
||||
_logger.Fatal(ex.Message);
|
||||
error("An exception has occured.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -360,7 +404,10 @@ namespace WebSocketSharp.Server {
|
||||
/// </param>
|
||||
protected virtual void Error(string message)
|
||||
{
|
||||
onError(message);
|
||||
if (message.IsNullOrEmpty())
|
||||
return;
|
||||
|
||||
error(message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@@ -58,7 +58,7 @@ namespace WebSocketSharp.Server {
|
||||
/// </summary>
|
||||
public WebSocketService()
|
||||
{
|
||||
ID = String.Empty;
|
||||
ID = String.Empty;
|
||||
IsBound = false;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,31 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logging functions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If you wanted to change the current logger to the service own logger, you would set this property
|
||||
/// to a new <see cref="Logger"/> instance that you created.
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// A <see cref="Logger"/> that provides the logging functions.
|
||||
/// </value>
|
||||
protected Logger Log {
|
||||
get {
|
||||
return IsBound
|
||||
? _websocket.Log
|
||||
: null;
|
||||
}
|
||||
|
||||
set {
|
||||
if (!IsBound)
|
||||
return;
|
||||
|
||||
_websocket.Log = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of query string variables used in the WebSocket opening handshake.
|
||||
/// </summary>
|
||||
|
@@ -56,7 +56,8 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
#region Internal Constructors
|
||||
|
||||
internal WebSocketServiceHost()
|
||||
internal WebSocketServiceHost(Logger logger)
|
||||
: base(logger)
|
||||
{
|
||||
_sessions = new WebSocketServiceManager();
|
||||
}
|
||||
@@ -230,6 +231,8 @@ namespace WebSocketSharp.Server {
|
||||
{
|
||||
var ws = context.WebSocket;
|
||||
var path = context.Path.UrlDecode();
|
||||
|
||||
ws.Log = Log;
|
||||
if (path != Uri.GetAbsolutePath().UrlDecode())
|
||||
{
|
||||
ws.Close(HttpStatusCode.NotImplemented);
|
||||
|
Reference in New Issue
Block a user