Added a new AddWebSocketService method to the WebSocketServer and HttpServer classes

This commit is contained in:
sta 2013-10-02 14:39:56 +09:00
parent 2b57a58da2
commit 24e74b60b7
8 changed files with 356 additions and 64 deletions

View File

@ -10,10 +10,21 @@ namespace Example2
private static int _num = 0; private static int _num = 0;
private string _name; private string _name;
private string _prefix;
public Chat ()
: this ("anon#")
{
}
public Chat (string prefix)
{
_prefix = prefix;
}
private string getName () private string getName ()
{ {
return Context.QueryString ["name"] ?? ("anon#" + getNum ()); return Context.QueryString ["name"] ?? (_prefix + getNum ());
} }
private int getNum () private int getNum ()

View File

@ -10,19 +10,19 @@ namespace Example2
{ {
public static void Main (string [] args) public static void Main (string [] args)
{ {
/* Single service server /* Single service server
var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649"); var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649", () => new Echo ());
//var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649/Echo"); //var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649/Echo", () => new Echo ());
//var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649/エコー"); //var wssv = new WebSocketServiceHost<Echo> ("ws://localhost:4649/エコー", () => new Echo ());
//var wssv = new WebSocketServiceHost<Echo> (4649); //var wssv = new WebSocketServiceHost<Echo> (4649, () => new Echo ());
//var wssv = new WebSocketServiceHost<Echo> (4649, "/Echo"); //var wssv = new WebSocketServiceHost<Echo> (4649, "/Echo", () => new Echo ());
//var wssv = new WebSocketServiceHost<Echo> (4649, "/エコー"); //var wssv = new WebSocketServiceHost<Echo> (4649, "/エコー", () => new Echo ());
//var wssv = new WebSocketServiceHost<Chat> ("ws://localhost:4649"); //var wssv = new WebSocketServiceHost<Chat> ("ws://localhost:4649", () => new Chat ());
//var wssv = new WebSocketServiceHost<Chat> ("ws://localhost:4649/Chat"); //var wssv = new WebSocketServiceHost<Chat> ("ws://localhost:4649/Chat", () => new Chat ());
//var wssv = new WebSocketServiceHost<Chat> ("ws://localhost:4649/チャット"); //var wssv = new WebSocketServiceHost<Chat> ("ws://localhost:4649/チャット", () => new Chat ());
//var wssv = new WebSocketServiceHost<Chat> (4649); //var wssv = new WebSocketServiceHost<Chat> (4649, () => new Chat ());
//var wssv = new WebSocketServiceHost<Chat> (4649, "/Chat"); //var wssv = new WebSocketServiceHost<Chat> (4649, "/Chat", () => new Chat ());
//var wssv = new WebSocketServiceHost<Chat> (4649, "/チャット"); //var wssv = new WebSocketServiceHost<Chat> (4649, "/チャット", () => new Chat ());
#if DEBUG #if DEBUG
wssv.Log.Level = LogLevel.TRACE; wssv.Log.Level = LogLevel.TRACE;
#endif #endif
@ -30,7 +30,7 @@ namespace Example2
wssv.Start (); wssv.Start ();
Console.WriteLine ( Console.WriteLine (
"WebSocket Service Host (url: {0})\n listening on address: {1} port: {2}\n", "A WebSocket Service Host (url: {0})\n listening on address: {1} port: {2}\n",
wssv.Uri, wssv.Address, wssv.Port); wssv.Uri, wssv.Address, wssv.Port);
*/ */
@ -48,6 +48,7 @@ namespace Example2
//wssv.KeepClean = false; //wssv.KeepClean = false;
wssv.AddWebSocketService<Echo> ("/Echo"); wssv.AddWebSocketService<Echo> ("/Echo");
wssv.AddWebSocketService<Chat> ("/Chat"); wssv.AddWebSocketService<Chat> ("/Chat");
//wssv.AddWebSocketService<Chat> ("/Chat", () => new Chat ("Anon#"));
//wssv.AddWebSocketService<Echo> ("/エコー"); //wssv.AddWebSocketService<Echo> ("/エコー");
//wssv.AddWebSocketService<Chat> ("/チャット"); //wssv.AddWebSocketService<Chat> ("/チャット");
@ -56,6 +57,7 @@ namespace Example2
"A WebSocket Server listening on port: {0} service path:", wssv.Port); "A WebSocket Server listening on port: {0} service path:", wssv.Port);
foreach (var path in wssv.WebSocketServices.ServicePaths) foreach (var path in wssv.WebSocketServices.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 server...");

View File

@ -10,10 +10,21 @@ namespace Example3
private static int _num = 0; private static int _num = 0;
private string _name; private string _name;
private string _prefix;
public Chat ()
: this ("anon#")
{
}
public Chat (string prefix)
{
_prefix = prefix;
}
private string getName () private string getName ()
{ {
return Context.QueryString ["name"] ?? ("anon#" + getNum ()); return Context.QueryString ["name"] ?? (_prefix + getNum ());
} }
private int getNum () private int getNum ()

View File

@ -25,6 +25,7 @@ namespace Example3
//_httpsv.KeepClean = false; //_httpsv.KeepClean = false;
_httpsv.AddWebSocketService<Echo> ("/Echo"); _httpsv.AddWebSocketService<Echo> ("/Echo");
_httpsv.AddWebSocketService<Chat> ("/Chat"); _httpsv.AddWebSocketService<Chat> ("/Chat");
//_httpsv.AddWebSocketService<Chat> ("/Chat", () => new Chat ("Anon#"));
_httpsv.OnGet += (sender, e) => _httpsv.OnGet += (sender, e) =>
{ {
@ -34,7 +35,7 @@ namespace Example3
_httpsv.Start (); _httpsv.Start ();
if (_httpsv.IsListening) if (_httpsv.IsListening)
{ {
Console.WriteLine ("HTTP Server listening on port: {0} service path:", _httpsv.Port); Console.WriteLine ("An HTTP Server listening on port: {0} service path:", _httpsv.Port);
foreach (var path in _httpsv.WebSocketServices.ServicePaths) foreach (var path in _httpsv.WebSocketServices.ServicePaths)
Console.WriteLine (" {0}", path); Console.WriteLine (" {0}", path);

View File

@ -45,7 +45,7 @@ The `WebSocket` class exists in the `WebSocketSharp` namespace.
#### Step 2 #### #### Step 2 ####
Creating a instance of the `WebSocket` class with the specified WebSocket URL to connect. Creating an instance of the `WebSocket` class with the specified WebSocket URL to connect.
```cs ```cs
using (var ws = new WebSocket ("ws://example.com")) using (var ws = new WebSocket ("ws://example.com"))
@ -187,7 +187,8 @@ namespace Example
{ {
public static void Main (string [] args) public static void Main (string [] args)
{ {
var wssv = new WebSocketServiceHost<Laputa> ("ws://dragonsnest.far/Laputa"); var wssv = new WebSocketServer ("ws://dragonsnest.far");
wssv.AddWebSocketService<Laputa> ("/Laputa");
wssv.Start (); wssv.Start ();
Console.ReadKey (true); Console.ReadKey (true);
wssv.Stop (); wssv.Stop ();
@ -204,11 +205,11 @@ Required namespace.
using WebSocketSharp.Server; using WebSocketSharp.Server;
``` ```
The `WebSocketService`, `WebSocketServiceHost<T>` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace. The `WebSocketService` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.
#### Step 2 #### #### Step 2 ####
Creating a class that inherits the `WebSocketService` class. Creating the class that inherits the `WebSocketService` class.
For example, if you want to provide an echo service, For example, if you want to provide an echo service,
@ -226,7 +227,7 @@ public class Echo : WebSocketService
} }
``` ```
Or if you want to provide a chat service, And if you want to provide a chat service,
```cs ```cs
using System; using System;
@ -235,9 +236,21 @@ using WebSocketSharp.Server;
public class Chat : WebSocketService public class Chat : WebSocketService
{ {
private string _suffix;
public Chat ()
: this (String.Empty)
{
}
public Chat (string suffix)
{
_suffix = suffix;
}
protected override void OnMessage (MessageEventArgs e) protected override void OnMessage (MessageEventArgs e)
{ {
Sessions.Broadcast (e.Data); Sessions.Broadcast (e.Data + _suffix);
} }
} }
``` ```
@ -248,25 +261,23 @@ In addition, if you override the `OnOpen`, `OnError` and `OnClose` methods, each
#### Step 3 #### #### Step 3 ####
Creating a instance of the `WebSocketServiceHost<T>` class if you want the single WebSocket service server. Creating an instance of the `WebSocketServer` class.
```cs
var wssv = new WebSocketServiceHost<Echo> ("ws://example.com:4649");
```
Or creating a instance of the `WebSocketServer` class if you want the multi WebSocket service server.
```cs ```cs
var wssv = new WebSocketServer (4649); var wssv = new WebSocketServer (4649);
wssv.AddWebSocketService<Echo> ("/Echo"); wssv.AddWebSocketService<Echo> ("/Echo");
wssv.AddWebSocketService<Chat> ("/Chat"); wssv.AddWebSocketService<Chat> ("/Chat", () => new Chat (" Nice boat."));
``` ```
You can add any WebSocket service with a specified path to the service to your `WebSocketServer` by using the `WebSocketServer.AddWebSocketService<T>` method. You can add any WebSocket service with a specified path to the service to your `WebSocketServer` by using the `WebSocketServer.AddWebSocketService<TWithNew>` or `WebSocketServer.AddWebSocketService<T>` method.
The type of `T` inherits `WebSocketService` class, so you can use a class that was created in **Step 2**. The type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.
If you create a instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it is necessary to run with root permission. The type of `T` must inherit `WebSocketService` class.
So you can use the classes created in **Step 2**.
If you create an instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it is necessary to run with root permission.
$ sudo mono example2.exe $ sudo mono example2.exe
@ -290,18 +301,19 @@ wssv.Stop ();
I modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext` and some other classes of [Mono] to create the HTTP server that can upgrade the connection to the WebSocket connection when receives a WebSocket connection request. I modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext` and some other classes of [Mono] to create the HTTP server that can upgrade the connection to the WebSocket connection when receives a WebSocket connection request.
You can add any WebSocket service with a specified path to the service to your `HttpServer` by using the `HttpServer.AddWebSocketService<T>` method. You can add any WebSocket service with a specified path to the service to your `HttpServer` by using the `HttpServer.AddWebSocketService<TWithNew>` or `HttpServer.AddWebSocketService<T>` method.
```cs ```cs
var httpsv = new HttpServer (4649); var httpsv = new HttpServer (4649);
httpsv.AddWebSocketService<Echo> ("/"); httpsv.AddWebSocketService<Echo> ("/Echo");
httpsv.AddWebSocketService<Chat> ("/Chat", () => new Chat (" Nice boat."));
``` ```
For more information, could you see **[Example3]**? For more information, could you see **[Example3]**?
### Secure Connection ### ### Secure Connection ###
As a **WebSocket Client**, creating a instance of the `WebSocket` class with the WebSocket URL with **wss** scheme. As a **WebSocket Client**, creating an instance of the `WebSocket` class with the WebSocket URL with **wss** scheme.
```cs ```cs
using (var ws = new WebSocket ("wss://example.com")) using (var ws = new WebSocket ("wss://example.com"))
@ -322,7 +334,7 @@ ws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyE
If you set this property to nothing, the validation does nothing with the server certificate, always returns valid. If you set this property to nothing, the validation does nothing with the server certificate, always returns valid.
As a **WebSocket Server**, creating and setting a instance of the WebSocket server with some settings for the secure connection. As a **WebSocket Server**, creating and setting an instance of the WebSocket server with some settings for the secure connection.
```cs ```cs
var wssv = new WebSocketServer (4649, true); var wssv = new WebSocketServer (4649, true);
@ -349,7 +361,7 @@ And if you want to output a log, you use some output methods. The following outp
ws.Log.Debug ("This is a debug message."); ws.Log.Debug ("This is a debug message.");
``` ```
The `WebSocketServiceHost<T>`, `WebSocketServer` and `HttpServer` classes include the same logging functions. The `WebSocketServer` and `HttpServer` classes include the same logging functions.
## Examples ## ## Examples ##

View File

@ -2,6 +2,8 @@
/* /*
* HttpServer.cs * HttpServer.cs
* *
* A simple HTTP server that allows to accept the WebSocket connection requests.
*
* The MIT License * The MIT License
* *
* Copyright (c) 2012-2013 sta.blockhead * Copyright (c) 2012-2013 sta.blockhead
@ -26,6 +28,13 @@
*/ */
#endregion #endregion
#region Thanks
/*
* Thanks:
* Juan Manuel Lallana <juan.manuel.lallana@gmail.com>
*/
#endregion
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -510,20 +519,53 @@ namespace WebSocketSharp.Server
/// <param name="servicePath"> /// <param name="servicePath">
/// A <see cref="string"/> that contains an absolute path to the WebSocket service. /// A <see cref="string"/> that contains an absolute path to the WebSocket service.
/// </param> /// </param>
/// <typeparam name="TWithNew">
/// The type of the WebSocket service. The TWithNew must inherit the <see cref="WebSocketService"/> class and
/// must have a public parameterless constructor.
/// </typeparam>
public void AddWebSocketService<TWithNew> (string servicePath)
where TWithNew : WebSocketService, new ()
{
AddWebSocketService<TWithNew> (servicePath, () => new TWithNew ());
}
/// <summary>
/// Adds the specified typed WebSocket service with the specified <paramref name="servicePath"/> and
/// <paramref name="serviceConstructor"/>.
/// </summary>
/// <remarks>
/// <para>
/// This method converts <paramref name="servicePath"/> to URL-decoded string and
/// removes <c>'/'</c> from tail end of <paramref name="servicePath"/>.
/// </para>
/// <para>
/// <paramref name="serviceConstructor"/> returns a initialized specified typed WebSocket service
/// instance.
/// </para>
/// </remarks>
/// <param name="servicePath">
/// A <see cref="string"/> that contains an absolute path to the WebSocket service.
/// </param>
/// <param name="serviceConstructor">
/// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <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 servicePath) public void AddWebSocketService<T> (string servicePath, Func<T> serviceConstructor)
where T : WebSocketService, new () where T : WebSocketService
{ {
var msg = servicePath.CheckIfValidServicePath (); var msg = servicePath.CheckIfValidServicePath () ??
(serviceConstructor == null ? "'serviceConstructor' must not be null." : null);
if (msg != null) if (msg != null)
{ {
_logger.Error (String.Format ("{0}\nservice path: {1}", msg, servicePath ?? "")); _logger.Error (String.Format ("{0}\nservice path: {1}", msg, servicePath ?? ""));
return; return;
} }
var host = new WebSocketServiceHost<T> (_logger); var host = new WebSocketServiceHost<T> (serviceConstructor, _logger);
host.Uri = servicePath.ToUri (); host.Uri = servicePath.ToUri ();
if (!KeepClean) if (!KeepClean)
host.KeepClean = false; host.KeepClean = false;

View File

@ -28,6 +28,13 @@
*/ */
#endregion #endregion
#region Thanks
/*
* Thanks:
* Juan Manuel Lallana <juan.manuel.lallana@gmail.com>
*/
#endregion
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Sockets; using System.Net.Sockets;
@ -245,20 +252,53 @@ namespace WebSocketSharp.Server
/// <param name="servicePath"> /// <param name="servicePath">
/// A <see cref="string"/> that contains an absolute path to the WebSocket service. /// A <see cref="string"/> that contains an absolute path to the WebSocket service.
/// </param> /// </param>
/// <typeparam name="TWithNew">
/// The type of the WebSocket service. The TWithNew must inherit the <see cref="WebSocketService"/>
/// class and must have a public parameterless constructor.
/// </typeparam>
public void AddWebSocketService<TWithNew> (string servicePath)
where TWithNew : WebSocketService, new ()
{
AddWebSocketService<TWithNew> (servicePath, () => new TWithNew ());
}
/// <summary>
/// Adds the specified typed WebSocket service with the specified <paramref name="servicePath"/> and
/// <paramref name="serviceConstructor"/>.
/// </summary>
/// <remarks>
/// <para>
/// This method converts <paramref name="servicePath"/> to URL-decoded string and
/// removes <c>'/'</c> from tail end of <paramref name="servicePath"/>.
/// </para>
/// <para>
/// <paramref name="serviceConstructor"/> returns a initialized specified typed WebSocket service
/// instance.
/// </para>
/// </remarks>
/// <param name="servicePath">
/// A <see cref="string"/> that contains an absolute path to the WebSocket service.
/// </param>
/// <param name="serviceConstructor">
/// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <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 servicePath) public void AddWebSocketService<T> (string servicePath, Func<T> serviceConstructor)
where T : WebSocketService, new () where T : WebSocketService
{ {
var msg = servicePath.CheckIfValidServicePath (); var msg = servicePath.CheckIfValidServicePath () ??
(serviceConstructor == null ? "'serviceConstructor' must not be null." : null);
if (msg != null) if (msg != null)
{ {
Log.Error (String.Format ("{0}\nservice path: {1}", msg, servicePath ?? "")); Log.Error (String.Format ("{0}\nservice path: {1}", msg, servicePath ?? ""));
return; return;
} }
var host = new WebSocketServiceHost<T> (Log); var host = new WebSocketServiceHost<T> (serviceConstructor, Log);
host.Uri = BaseUri.IsAbsoluteUri host.Uri = BaseUri.IsAbsoluteUri
? new Uri (BaseUri, servicePath) ? new Uri (BaseUri, servicePath)
: servicePath.ToUri (); : servicePath.ToUri ();

View File

@ -28,6 +28,13 @@
*/ */
#endregion #endregion
#region Thanks
/*
* Thanks:
* Juan Manuel Lallana <juan.manuel.lallana@gmail.com>
*/
#endregion
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Sockets; using System.Net.Sockets;
@ -48,10 +55,11 @@ namespace WebSocketSharp.Server
/// The T must inherit the <see cref="WebSocketService"/> class. /// The T must inherit the <see cref="WebSocketService"/> class.
/// </typeparam> /// </typeparam>
public class WebSocketServiceHost<T> : WebSocketServerBase, IWebSocketServiceHost public class WebSocketServiceHost<T> : WebSocketServerBase, IWebSocketServiceHost
where T : WebSocketService, new () where T : WebSocketService
{ {
#region Private Fields #region Private Fields
private Func<T> _serviceConstructor;
private string _servicePath; private string _servicePath;
private WebSocketSessionManager _sessions; private WebSocketSessionManager _sessions;
private volatile ServerState _state; private volatile ServerState _state;
@ -61,9 +69,10 @@ namespace WebSocketSharp.Server
#region Internal Constructors #region Internal Constructors
internal WebSocketServiceHost (Logger logger) internal WebSocketServiceHost (Func<T> serviceConstructor, Logger logger)
: base (logger) : base (logger)
{ {
_serviceConstructor = serviceConstructor;
_sessions = new WebSocketSessionManager (logger); _sessions = new WebSocketSessionManager (logger);
_state = ServerState.READY; _state = ServerState.READY;
_sync = new object (); _sync = new object ();
@ -80,8 +89,18 @@ 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 WebSocketServiceHost (int port) /// <param name="serviceConstructor">
: this (port, "/") /// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="serviceConstructor"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="port"/> is 0 or less, or 65536 or greater.
/// </exception>
public WebSocketServiceHost (int port, Func<T> serviceConstructor)
: this (port, "/", serviceConstructor)
{ {
} }
@ -92,9 +111,31 @@ namespace WebSocketSharp.Server
/// <param name="url"> /// <param name="url">
/// A <see cref="string"/> that contains a WebSocket URL. /// A <see cref="string"/> that contains a WebSocket URL.
/// </param> /// </param>
public WebSocketServiceHost (string url) /// <param name="serviceConstructor">
/// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <exception cref="ArgumentNullException">
/// <para>
/// <paramref name="url"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="serviceConstructor"/> is <see langword="null"/>.
/// </para>
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="url"/> is invalid.
/// </exception>
public WebSocketServiceHost (string url, Func<T> serviceConstructor)
: base (url) : base (url)
{ {
if (serviceConstructor == null)
throw new ArgumentNullException ("serviceConstructor");
_serviceConstructor = serviceConstructor;
_sessions = new WebSocketSessionManager (Log); _sessions = new WebSocketSessionManager (Log);
_state = ServerState.READY; _state = ServerState.READY;
_sync = new object (); _sync = new object ();
@ -111,14 +152,28 @@ namespace WebSocketSharp.Server
/// A <see cref="bool"/> that indicates providing a secure connection or not. /// A <see cref="bool"/> that indicates providing a secure connection or not.
/// (<c>true</c> indicates providing a secure connection.) /// (<c>true</c> indicates providing a secure connection.)
/// </param> /// </param>
public WebSocketServiceHost (int port, bool secure) /// <param name="serviceConstructor">
: this (port, "/", secure) /// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="serviceConstructor"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="port"/> is 0 or less, or 65536 or greater.
/// </exception>
/// <exception cref="ArgumentException">
/// Pair of <paramref name="port"/> and <paramref name="secure"/> is invalid.
/// </exception>
public WebSocketServiceHost (int port, bool secure, Func<T> serviceConstructor)
: this (port, "/", secure, serviceConstructor)
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of the WebSocketServiceHost&lt;T&gt; class that listens for /// Initializes a new instance of the WebSocketServiceHost&lt;T&gt; class that listens for
/// incoming connection attempts on the specified <paramref name="port"/> and <paramref name="servicePath"/>. /// incoming connection attempts on the specified <paramref name="port"/> and
/// <paramref name="servicePath"/>.
/// </summary> /// </summary>
/// <param name="port"> /// <param name="port">
/// An <see cref="int"/> that contains a port number. /// An <see cref="int"/> that contains a port number.
@ -126,8 +181,29 @@ namespace WebSocketSharp.Server
/// <param name="servicePath"> /// <param name="servicePath">
/// A <see cref="string"/> that contains an absolute path. /// A <see cref="string"/> that contains an absolute path.
/// </param> /// </param>
public WebSocketServiceHost (int port, string servicePath) /// <param name="serviceConstructor">
: this (System.Net.IPAddress.Any, port, servicePath) /// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <exception cref="ArgumentNullException">
/// <para>
/// <paramref name="servicePath"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="serviceConstructor"/> is <see langword="null"/>.
/// </para>
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="port"/> is 0 or less, or 65536 or greater.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="servicePath"/> is invalid.
/// </exception>
public WebSocketServiceHost (int port, string servicePath, Func<T> serviceConstructor)
: this (System.Net.IPAddress.Any, port, servicePath, serviceConstructor)
{ {
} }
@ -146,8 +222,37 @@ namespace WebSocketSharp.Server
/// A <see cref="bool"/> that indicates providing a secure connection or not. /// A <see cref="bool"/> that indicates providing a secure connection or not.
/// (<c>true</c> indicates providing a secure connection.) /// (<c>true</c> indicates providing a secure connection.)
/// </param> /// </param>
public WebSocketServiceHost (int port, string servicePath, bool secure) /// <param name="serviceConstructor">
: this (System.Net.IPAddress.Any, port, servicePath, secure) /// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <exception cref="ArgumentNullException">
/// <para>
/// <paramref name="servicePath"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="serviceConstructor"/> is <see langword="null"/>.
/// </para>
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="port"/> is 0 or less, or 65536 or greater.
/// </exception>
/// <exception cref="ArgumentException">
/// <para>
/// <paramref name="servicePath"/> is invalid.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// Pair of <paramref name="port"/> and <paramref name="secure"/> is invalid.
/// </para>
/// </exception>
public WebSocketServiceHost (int port, string servicePath, bool secure, Func<T> serviceConstructor)
: this (System.Net.IPAddress.Any, port, servicePath, secure, serviceConstructor)
{ {
} }
@ -165,8 +270,36 @@ namespace WebSocketSharp.Server
/// <param name="servicePath"> /// <param name="servicePath">
/// A <see cref="string"/> that contains an absolute path. /// A <see cref="string"/> that contains an absolute path.
/// </param> /// </param>
public WebSocketServiceHost (System.Net.IPAddress address, int port, string servicePath) /// <param name="serviceConstructor">
: this (address, port, servicePath, port == 443 ? true : false) /// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <exception cref="ArgumentNullException">
/// <para>
/// <paramref name="address"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="servicePath"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="serviceConstructor"/> is <see langword="null"/>.
/// </para>
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="port"/> is 0 or less, or 65536 or greater.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="servicePath"/> is invalid.
/// </exception>
public WebSocketServiceHost (
System.Net.IPAddress address, int port, string servicePath, Func<T> serviceConstructor)
: this (address, port, servicePath, port == 443 ? true : false, serviceConstructor)
{ {
} }
@ -188,9 +321,49 @@ namespace WebSocketSharp.Server
/// A <see cref="bool"/> that indicates providing a secure connection or not. /// A <see cref="bool"/> that indicates providing a secure connection or not.
/// (<c>true</c> indicates providing a secure connection.) /// (<c>true</c> indicates providing a secure connection.)
/// </param> /// </param>
public WebSocketServiceHost (System.Net.IPAddress address, int port, string servicePath, bool secure) /// <param name="serviceConstructor">
/// A Func&lt;T&gt; delegate that references the method used to initialize a new WebSocket service
/// instance (a new WebSocket session).
/// </param>
/// <exception cref="ArgumentNullException">
/// <para>
/// <paramref name="address"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="servicePath"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="serviceConstructor"/> is <see langword="null"/>.
/// </para>
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="port"/> is 0 or less, or 65536 or greater.
/// </exception>
/// <exception cref="ArgumentException">
/// <para>
/// <paramref name="servicePath"/> is invalid.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// Pair of <paramref name="port"/> and <paramref name="secure"/> is invalid.
/// </para>
/// </exception>
public WebSocketServiceHost (
System.Net.IPAddress address, int port, string servicePath, bool secure, Func<T> serviceConstructor)
: base (address, port, servicePath, secure) : base (address, port, servicePath, secure)
{ {
if (serviceConstructor == null)
throw new ArgumentNullException ("serviceConstructor");
_serviceConstructor = serviceConstructor;
_sessions = new WebSocketSessionManager (Log); _sessions = new WebSocketSessionManager (Log);
_state = ServerState.READY; _state = ServerState.READY;
_sync = new object (); _sync = new object ();
@ -450,14 +623,14 @@ namespace WebSocketSharp.Server
#region Explicit Interface Implementation #region Explicit Interface Implementation
/// <summary> /// <summary>
/// Binds the specified <see cref="WebSocketContext"/> to a <see cref="WebSocketService"/> instance. /// Binds the specified <see cref="WebSocketContext"/> to a WebSocket service instance.
/// </summary> /// </summary>
/// <param name="context"> /// <param name="context">
/// A <see cref="WebSocketContext"/> that contains the WebSocket connection request objects to bind. /// A <see cref="WebSocketContext"/> that contains the WebSocket connection request objects to bind.
/// </param> /// </param>
void IWebSocketServiceHost.BindWebSocket (WebSocketContext context) void IWebSocketServiceHost.BindWebSocket (WebSocketContext context)
{ {
T service = new T (); T service = _serviceConstructor ();
service.Bind (context, _sessions); service.Bind (context, _sessions);
service.Start (); service.Start ();
} }