Fix for issue #20
This commit is contained in:
		@@ -8,7 +8,7 @@
 | 
			
		||||
    <ProjectGuid>{C648BA25-77E5-4A40-A97F-D0AA37B9FB26}</ProjectGuid>
 | 
			
		||||
    <OutputType>Exe</OutputType>
 | 
			
		||||
    <RootNamespace>Example3</RootNamespace>
 | 
			
		||||
    <AssemblyName>Example3</AssemblyName>
 | 
			
		||||
    <AssemblyName>example3</AssemblyName>
 | 
			
		||||
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@ using System.Security.Cryptography.X509Certificates;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using WebSocketSharp.Net;
 | 
			
		||||
using WebSocketSharp.Net.WebSockets;
 | 
			
		||||
using WebSocketSharp.Server;
 | 
			
		||||
 | 
			
		||||
namespace WebSocketSharp
 | 
			
		||||
{
 | 
			
		||||
@@ -164,6 +165,20 @@ namespace WebSocketSharp
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal static string CheckIfStarted (this ServerState state)
 | 
			
		||||
    {
 | 
			
		||||
      return state != ServerState.START
 | 
			
		||||
             ? "Not started, on shutdown or stopped."
 | 
			
		||||
             : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal static string CheckIfStopped (this ServerState state)
 | 
			
		||||
    {
 | 
			
		||||
      return state == ServerState.START || state == ServerState.SHUTDOWN
 | 
			
		||||
             ? "Already started or on shutdown."
 | 
			
		||||
             : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal static string CheckIfValidCloseData (this byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      return data.Length > 125
 | 
			
		||||
 
 | 
			
		||||
@@ -47,13 +47,15 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    #region Private Fields
 | 
			
		||||
 | 
			
		||||
    private HttpListener                _listener;
 | 
			
		||||
    private bool                        _listening;
 | 
			
		||||
    private volatile bool               _listening;
 | 
			
		||||
    private Logger                      _logger;
 | 
			
		||||
    private int                         _port;
 | 
			
		||||
    private Thread                      _receiveRequestThread;
 | 
			
		||||
    private string                      _rootPath;
 | 
			
		||||
    private bool                        _secure;
 | 
			
		||||
    private WebSocketServiceHostManager _serviceHosts;
 | 
			
		||||
    private volatile ServerState        _state;
 | 
			
		||||
    private object                      _sync;
 | 
			
		||||
    private bool                        _windows;
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
@@ -308,12 +310,40 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    #region Private Methods
 | 
			
		||||
 | 
			
		||||
    private void abort ()
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          return;
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      _listening = false;
 | 
			
		||||
      _serviceHosts.Stop (((ushort) CloseStatusCode.SERVER_ERROR).ToByteArray (ByteOrder.BIG));
 | 
			
		||||
      _listener.Abort ();
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private string checkIfCertExists ()
 | 
			
		||||
    {
 | 
			
		||||
      return _secure &&
 | 
			
		||||
             !EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath) &&
 | 
			
		||||
             Certificate == null
 | 
			
		||||
             ? "The secure connection requires a server certificate."
 | 
			
		||||
             : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void init ()
 | 
			
		||||
    {
 | 
			
		||||
      _listener = new HttpListener ();
 | 
			
		||||
      _listening = false;
 | 
			
		||||
      _logger = new Logger ();
 | 
			
		||||
      _serviceHosts = new WebSocketServiceHostManager (_logger);
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
 | 
			
		||||
      _windows = false;
 | 
			
		||||
      var os = Environment.OSVersion;
 | 
			
		||||
@@ -420,7 +450,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
          context.Response.Close ();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex) {
 | 
			
		||||
          _logger.Fatal (ex.Message);
 | 
			
		||||
          _logger.Fatal (ex.ToString ());
 | 
			
		||||
          context.Connection.Close (true);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@@ -434,15 +465,18 @@ namespace WebSocketSharp.Server
 | 
			
		||||
        try {
 | 
			
		||||
          processRequestAsync (_listener.GetContext ());
 | 
			
		||||
        }
 | 
			
		||||
        catch (HttpListenerException) {
 | 
			
		||||
          _logger.Info ("HttpListener has been stopped.");
 | 
			
		||||
        catch (HttpListenerException ex) {
 | 
			
		||||
          _logger.Warn (String.Format ("Receiving has been stopped.\nreason: {0}.", ex.Message));
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex) {
 | 
			
		||||
          _logger.Fatal (ex.Message);
 | 
			
		||||
          _logger.Fatal (ex.ToString ());
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (_listening)
 | 
			
		||||
        abort ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startReceiveRequestThread ()
 | 
			
		||||
@@ -452,20 +486,14 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      _receiveRequestThread.Start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void stop (ushort code, string reason)
 | 
			
		||||
    private void stopListener ()
 | 
			
		||||
    {
 | 
			
		||||
      var data = code.Append (reason);
 | 
			
		||||
      var msg = data.CheckIfValidCloseData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (String.Format ("{0}\ncode: {1}\nreason: {2}", msg, code, reason));
 | 
			
		||||
      if (!_listening)
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      _serviceHosts.Stop (data);
 | 
			
		||||
      _listening = false;
 | 
			
		||||
      _listener.Close ();
 | 
			
		||||
      _receiveRequestThread.Join (5 * 1000);
 | 
			
		||||
      _listening = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
@@ -554,21 +582,22 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public void Start ()
 | 
			
		||||
    {
 | 
			
		||||
      if (_listening)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      if (_secure &&
 | 
			
		||||
          !EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath) &&
 | 
			
		||||
          Certificate == null
 | 
			
		||||
      )
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error ("Secure connection requires a server certificate.");
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
        var msg = _state.CheckIfStopped () ?? checkIfCertExists ();
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          _logger.Error (String.Format ("{0}\nstate: {1}\nsecure: {2}", msg, _state, _secure));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      _listener.Start ();
 | 
			
		||||
      startReceiveRequestThread ();
 | 
			
		||||
      _listening = true;
 | 
			
		||||
        _serviceHosts.Start ();
 | 
			
		||||
        _listener.Start ();
 | 
			
		||||
        startReceiveRequestThread ();
 | 
			
		||||
        _listening = true;
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.START;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -576,13 +605,22 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public void Stop ()
 | 
			
		||||
    {
 | 
			
		||||
      if (!_listening)
 | 
			
		||||
        return;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStarted ();
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          _logger.Error (String.Format ("{0}\nstate: {1}", msg, _state));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      _serviceHosts.Stop ();
 | 
			
		||||
      _listener.Close ();
 | 
			
		||||
      _receiveRequestThread.Join (5 * 1000);
 | 
			
		||||
      _listening = false;
 | 
			
		||||
      stopListener ();
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -597,17 +635,26 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Stop (ushort code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
      if (!_listening)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      var msg = code.CheckIfValidCloseStatusCode ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      byte [] data = null;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (String.Format ("{0}\ncode: {1}", msg, code));
 | 
			
		||||
        return;
 | 
			
		||||
        var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                  code.CheckIfValidCloseStatusCode () ??
 | 
			
		||||
                  (data = code.Append (reason)).CheckIfValidCloseData ();
 | 
			
		||||
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          _logger.Error (String.Format ("{0}\nstate: {1}\ncode: {2}\nreason: {3}", msg, _state, code, reason));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      stop (code, reason);
 | 
			
		||||
      _serviceHosts.Stop (data);
 | 
			
		||||
      stopListener ();
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -615,17 +662,33 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// and <see cref="string"/> used to stop the WebSocket services.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="code">
 | 
			
		||||
    /// A <see cref="CloseStatusCode"/> that contains a status code indicating the reason for stop.
 | 
			
		||||
    /// One of the <see cref="CloseStatusCode"/> values that represent the status codes indicating
 | 
			
		||||
    /// the reasons for stop.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="reason">
 | 
			
		||||
    /// A <see cref="string"/> that contains the reason for stop.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Stop (CloseStatusCode code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
      if (!_listening)
 | 
			
		||||
        return;
 | 
			
		||||
      byte [] data = null;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                  (data = ((ushort) code).Append (reason)).CheckIfValidCloseData ();
 | 
			
		||||
 | 
			
		||||
      stop ((ushort) code, reason);
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          _logger.Error (String.Format ("{0}\nstate: {1}\nreason: {2}", msg, _state, reason));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      _serviceHosts.Stop (data);
 | 
			
		||||
      stopListener ();
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								websocket-sharp/Server/ServerState.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								websocket-sharp/Server/ServerState.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
#region License
 | 
			
		||||
/*
 | 
			
		||||
 * ServerState.cs
 | 
			
		||||
 *
 | 
			
		||||
 * The MIT License
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2013 sta.blockhead
 | 
			
		||||
 * 
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 * 
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace WebSocketSharp.Server
 | 
			
		||||
{
 | 
			
		||||
  internal enum ServerState
 | 
			
		||||
  {
 | 
			
		||||
    READY,
 | 
			
		||||
    START,
 | 
			
		||||
    SHUTDOWN,
 | 
			
		||||
    STOP
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -48,6 +48,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    #region Private Fields
 | 
			
		||||
 | 
			
		||||
    private WebSocketServiceHostManager _serviceHosts;
 | 
			
		||||
    private volatile ServerState        _state;
 | 
			
		||||
    private object                      _sync;
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
@@ -87,6 +89,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
        throw new ArgumentException ("Must not contain the path component: " + url, "url");
 | 
			
		||||
 | 
			
		||||
      _serviceHosts = new WebSocketServiceHostManager (Log);
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -139,6 +143,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      : base (address, port, "/", secure)
 | 
			
		||||
    {
 | 
			
		||||
      _serviceHosts = new WebSocketServiceHostManager (Log);
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
@@ -193,26 +199,30 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Private Methods
 | 
			
		||||
    #region Protected Methods
 | 
			
		||||
 | 
			
		||||
    private void stop (ushort code, string reason)
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Aborts receiving the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method is called when an exception occurs while receiving the WebSocket connection requests.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    protected override void Abort ()
 | 
			
		||||
    {
 | 
			
		||||
      var data = code.Append (reason);
 | 
			
		||||
      var msg = data.CheckIfValidCloseData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        Log.Error (String.Format ("{0}\ncode: {1}\nreason: {2}", msg, code, reason));
 | 
			
		||||
        return;
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          return;
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _serviceHosts.Stop (data);
 | 
			
		||||
      StopListener ();
 | 
			
		||||
      _serviceHosts.Stop (((ushort) CloseStatusCode.SERVER_ERROR).ToByteArray (ByteOrder.BIG));
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Protected Methods
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Accepts a WebSocket connection request.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -301,13 +311,54 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      return _serviceHosts.Remove (servicePath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Starts to receive the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public override void Start ()
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStopped ();
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}", msg, _state));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _serviceHosts.Start ();
 | 
			
		||||
 | 
			
		||||
        base.Start ();
 | 
			
		||||
        if (!IsListening)
 | 
			
		||||
        {
 | 
			
		||||
          _serviceHosts.Stop ();
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.START;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Stops receiving the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public override void Stop ()
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStarted ();
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}", msg, _state));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _serviceHosts.Stop ();
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -322,14 +373,26 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Stop (ushort code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = code.CheckIfValidCloseStatusCode ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      byte [] data = null;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        Log.Error (String.Format ("{0}\ncode: {1}", msg, code));
 | 
			
		||||
        return;
 | 
			
		||||
        var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                  code.CheckIfValidCloseStatusCode () ??
 | 
			
		||||
                  (data = code.Append (reason)).CheckIfValidCloseData ();
 | 
			
		||||
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}\ncode: {2}\nreason: {3}", msg, _state, code, reason));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      stop (code, reason);
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _serviceHosts.Stop (data);
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -337,14 +400,33 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// and <see cref="string"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="code">
 | 
			
		||||
    /// A <see cref="CloseStatusCode"/> that contains a status code indicating the reason for stop.
 | 
			
		||||
    /// One of the <see cref="CloseStatusCode"/> values that represent the status codes indicating
 | 
			
		||||
    /// the reasons for stop.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="reason">
 | 
			
		||||
    /// A <see cref="string"/> that contains the reason for stop.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Stop (CloseStatusCode code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
      stop ((ushort) code, reason);
 | 
			
		||||
      byte [] data = null;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                  (data = ((ushort) code).Append (reason)).CheckIfValidCloseData ();
 | 
			
		||||
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}\nreason: {2}", msg, _state, reason));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _serviceHosts.Stop (data);
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    private IPAddress        _address;
 | 
			
		||||
    private X509Certificate2 _cert;
 | 
			
		||||
    private bool             _listening;
 | 
			
		||||
    private volatile bool    _listening;
 | 
			
		||||
    private Logger           _logger;
 | 
			
		||||
    private int              _port;
 | 
			
		||||
    private Thread           _receiveRequestThread;
 | 
			
		||||
@@ -339,8 +339,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
          _logger.Fatal (ex.ToString ());
 | 
			
		||||
          client.Close ();
 | 
			
		||||
          _logger.Fatal (ex.Message);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@@ -354,15 +354,18 @@ namespace WebSocketSharp.Server
 | 
			
		||||
        try {
 | 
			
		||||
          processRequestAsync (_listener.AcceptTcpClient ());
 | 
			
		||||
        }
 | 
			
		||||
        catch (SocketException) {
 | 
			
		||||
          _logger.Info ("TcpListener has been stopped.");
 | 
			
		||||
        catch (SocketException ex) {
 | 
			
		||||
          _logger.Warn (String.Format ("Receiving has been stopped.\nreason: {0}.", ex.Message));
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex) {
 | 
			
		||||
          _logger.Fatal (ex.Message);
 | 
			
		||||
          _logger.Fatal (ex.ToString ());
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (_listening)
 | 
			
		||||
        Abort ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startReceiveRequestThread ()
 | 
			
		||||
@@ -392,6 +395,14 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    #region Protected Methods
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Aborts receiving the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method is called when an exception occurs while receiving the WebSocket connection requests.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    protected abstract void Abort ();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Accepts a WebSocket connection request.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -400,6 +411,18 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    protected abstract void AcceptWebSocket (TcpListenerWebSocketContext context);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Stops the inner <see cref="TcpListener"/> used to receive the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    protected void StopListener ()
 | 
			
		||||
    {
 | 
			
		||||
      if (!_listening)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      _listening = false;
 | 
			
		||||
      _listener.Stop ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Public Methods
 | 
			
		||||
@@ -414,7 +437,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
      if (_secure && _cert == null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error ("Secure connection requires a server certificate.");
 | 
			
		||||
        _logger.Error ("The secure connection requires a server certificate.");
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -431,9 +454,9 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      if (!_selfHost || !_listening)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      _listening = false;
 | 
			
		||||
      _listener.Stop ();
 | 
			
		||||
      _receiveRequestThread.Join (5 * 1000);
 | 
			
		||||
      _listening = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 
 | 
			
		||||
@@ -54,6 +54,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    private string                  _servicePath;
 | 
			
		||||
    private WebSocketSessionManager _sessions;
 | 
			
		||||
    private volatile ServerState    _state;
 | 
			
		||||
    private object                  _sync;
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
@@ -63,6 +65,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      : base (logger)
 | 
			
		||||
    {
 | 
			
		||||
      _sessions = new WebSocketSessionManager (logger);
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
@@ -92,6 +96,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      : base (url)
 | 
			
		||||
    {
 | 
			
		||||
      _sessions = new WebSocketSessionManager (Log);
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -186,6 +192,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      : base (address, port, servicePath, secure)
 | 
			
		||||
    {
 | 
			
		||||
      _sessions = new WebSocketSessionManager (Log);
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
@@ -267,26 +275,30 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Private Methods
 | 
			
		||||
    #region Protected Methods
 | 
			
		||||
 | 
			
		||||
    private void stop (ushort code, string reason)
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Aborts receiving the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method is called when an exception occurs while receiving the WebSocket connection requests.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    protected override void Abort ()
 | 
			
		||||
    {
 | 
			
		||||
      var data = code.Append (reason);
 | 
			
		||||
      var msg = data.CheckIfValidCloseData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        Log.Error (String.Format ("{0}\ncode: {1}\nreason: {2}", msg, code, reason));
 | 
			
		||||
        return;
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          return;
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _sessions.Stop (data);
 | 
			
		||||
      StopListener ();
 | 
			
		||||
      _sessions.Stop (((ushort) CloseStatusCode.SERVER_ERROR).ToByteArray (ByteOrder.BIG));
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Protected Methods
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Accepts a WebSocket connection request.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -315,13 +327,54 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    #region Public Methods
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Starts to receive the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public override void Start ()
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStopped ();
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}", msg, _state));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _sessions.Start ();
 | 
			
		||||
 | 
			
		||||
        base.Start ();
 | 
			
		||||
        if (!IsListening)
 | 
			
		||||
        {
 | 
			
		||||
          _sessions.Stop ();
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.START;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Stops receiving the WebSocket connection requests.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public override void Stop ()
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStarted ();
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}", msg, _state));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _sessions.Stop ();
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -336,14 +389,26 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Stop (ushort code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = code.CheckIfValidCloseStatusCode ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      byte [] data = null;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        Log.Error (String.Format ("{0}\ncode: {1}", msg, code));
 | 
			
		||||
        return;
 | 
			
		||||
        var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                  code.CheckIfValidCloseStatusCode () ??
 | 
			
		||||
                  (data = code.Append (reason)).CheckIfValidCloseData ();
 | 
			
		||||
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}\ncode: {2}\nreason: {3}", msg, _state, code, reason));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      stop (code, reason);
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _sessions.Stop (data);
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -351,14 +416,33 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// and <see cref="string"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="code">
 | 
			
		||||
    /// A <see cref="CloseStatusCode"/> that contains a status code indicating the reason for stop.
 | 
			
		||||
    /// One of the <see cref="CloseStatusCode"/> values that represent the status codes indicating
 | 
			
		||||
    /// the reasons for stop.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="reason">
 | 
			
		||||
    /// A <see cref="string"/> that contains the reason for stop.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Stop (CloseStatusCode code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
      stop ((ushort) code, reason);
 | 
			
		||||
      byte [] data = null;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                  (data = ((ushort) code).Append (reason)).CheckIfValidCloseData ();
 | 
			
		||||
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          Log.Error (String.Format ("{0}\nstate: {1}\nreason: {2}", msg, _state, reason));
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      base.Stop ();
 | 
			
		||||
      _sessions.Stop (data);
 | 
			
		||||
 | 
			
		||||
      _state = ServerState.STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    private volatile bool                             _keepClean;
 | 
			
		||||
    private Logger                                    _logger;
 | 
			
		||||
    private Dictionary<string, IWebSocketServiceHost> _serviceHosts;
 | 
			
		||||
    private volatile ServerState                      _state;
 | 
			
		||||
    private object                                    _sync;
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
@@ -61,6 +62,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      _logger = logger;
 | 
			
		||||
      _keepClean = true;
 | 
			
		||||
      _serviceHosts = new Dictionary<string, IWebSocketServiceHost> ();
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +80,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      get {
 | 
			
		||||
        var count = 0;
 | 
			
		||||
        foreach (var host in ServiceHosts)
 | 
			
		||||
        {
 | 
			
		||||
          if (_state != ServerState.START)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          count += host.ConnectionCount;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return count;
 | 
			
		||||
      }
 | 
			
		||||
@@ -143,12 +150,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      internal set {
 | 
			
		||||
        lock (_sync)
 | 
			
		||||
        {
 | 
			
		||||
          if (_keepClean ^ value)
 | 
			
		||||
          {
 | 
			
		||||
            _keepClean = value;
 | 
			
		||||
            foreach (var host in _serviceHosts.Values)
 | 
			
		||||
              host.KeepClean = value;
 | 
			
		||||
          }
 | 
			
		||||
          if (!(value ^ _keepClean))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
          _keepClean = value;
 | 
			
		||||
          foreach (var host in _serviceHosts.Values)
 | 
			
		||||
            host.KeepClean = value;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -192,7 +199,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    {
 | 
			
		||||
      var result = new Dictionary<string, Dictionary<string, bool>> ();
 | 
			
		||||
      foreach (var host in ServiceHosts)
 | 
			
		||||
      {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        result.Add (host.ServicePath, host.Sessions.BroadpingInternally (data));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
@@ -214,6 +226,9 @@ namespace WebSocketSharp.Server
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (_state == ServerState.START)
 | 
			
		||||
          serviceHost.Sessions.Start ();
 | 
			
		||||
 | 
			
		||||
        _serviceHosts.Add (servicePath, serviceHost);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -234,18 +249,33 @@ namespace WebSocketSharp.Server
 | 
			
		||||
        _serviceHosts.Remove (servicePath);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      host.Sessions.Stop (((ushort) CloseStatusCode.AWAY).ToByteArray (ByteOrder.BIG));
 | 
			
		||||
      if (host.Sessions.State == ServerState.START)
 | 
			
		||||
        host.Sessions.Stop (((ushort) CloseStatusCode.AWAY).ToByteArray (ByteOrder.BIG));
 | 
			
		||||
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Start ()
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        foreach (var host in _serviceHosts.Values)
 | 
			
		||||
          host.Sessions.Start ();
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.START;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Stop ()
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
        foreach (var host in _serviceHosts.Values)
 | 
			
		||||
          host.Sessions.Stop ();
 | 
			
		||||
 | 
			
		||||
        _serviceHosts.Clear ();
 | 
			
		||||
        _state = ServerState.STOP;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -253,10 +283,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
        foreach (var host in _serviceHosts.Values)
 | 
			
		||||
          host.Sessions.Stop (data);
 | 
			
		||||
 | 
			
		||||
        _serviceHosts.Clear ();
 | 
			
		||||
        _state = ServerState.STOP;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -282,7 +314,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = data.CheckIfValidSendData ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -290,7 +322,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      foreach (var host in ServiceHosts)
 | 
			
		||||
      {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        host.Sessions.BroadcastInternally (data);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -302,7 +339,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (string data)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = data.CheckIfValidSendData ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -310,7 +347,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      foreach (var host in ServiceHosts)
 | 
			
		||||
      {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        host.Sessions.BroadcastInternally (data);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -328,7 +370,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool BroadcastTo (byte [] data, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = data.CheckIfValidSendData () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -361,7 +403,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool BroadcastTo (string data, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = data.CheckIfValidSendData () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -389,6 +431,13 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    public Dictionary<string, Dictionary<string, bool>> Broadping ()
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return broadping (new byte [] {});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -408,10 +457,10 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    public Dictionary<string, Dictionary<string, bool>> Broadping (string message)
 | 
			
		||||
    {
 | 
			
		||||
      if (message == null || message.Length == 0)
 | 
			
		||||
        return broadping (new byte [] {});
 | 
			
		||||
        return Broadping ();
 | 
			
		||||
 | 
			
		||||
      var data = Encoding.UTF8.GetBytes (message);
 | 
			
		||||
      var msg = data.CheckIfValidPingData ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidPingData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -434,7 +483,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public Dictionary<string, bool> BroadpingTo (string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -472,7 +521,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
        return BroadpingTo (servicePath);
 | 
			
		||||
 | 
			
		||||
      var data = Encoding.UTF8.GetBytes (message);
 | 
			
		||||
      var msg = data.CheckIfValidPingData () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidPingData () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -501,7 +550,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (string id, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -536,7 +585,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (ushort code, string reason, string id, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -571,7 +620,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (CloseStatusCode code, string reason, string id, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -604,7 +653,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool PingTo (string id, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -640,7 +689,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool PingTo (string message, string id, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -675,7 +724,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool SendTo (byte [] data, string id, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -710,7 +759,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool SendTo (string data, string id, string servicePath)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -744,7 +793,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool TryGetServiceHost (string servicePath, out IWebSocketServiceHost serviceHost)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? servicePath.CheckIfValidServicePath ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
 
 | 
			
		||||
@@ -42,9 +42,10 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    #region Private Fields
 | 
			
		||||
 | 
			
		||||
    private object                               _forSweep;
 | 
			
		||||
    private volatile bool                        _keepClean;
 | 
			
		||||
    private Logger                               _logger;
 | 
			
		||||
    private Dictionary<string, WebSocketService> _sessions;
 | 
			
		||||
    private volatile bool                        _stopped;
 | 
			
		||||
    private volatile ServerState                 _state;
 | 
			
		||||
    private volatile bool                        _sweeping;
 | 
			
		||||
    private Timer                                _sweepTimer;
 | 
			
		||||
    private object                               _sync;
 | 
			
		||||
@@ -62,21 +63,30 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    {
 | 
			
		||||
      _logger = logger;
 | 
			
		||||
      _forSweep = new object ();
 | 
			
		||||
      _keepClean = true;
 | 
			
		||||
      _sessions = new Dictionary<string, WebSocketService> ();
 | 
			
		||||
      _stopped = false;
 | 
			
		||||
      _state = ServerState.READY;
 | 
			
		||||
      _sweeping = false;
 | 
			
		||||
      _sync = new object ();
 | 
			
		||||
 | 
			
		||||
      setSweepTimer ();
 | 
			
		||||
      startSweepTimer ();
 | 
			
		||||
      setSweepTimer (60 * 1000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Internal Properties
 | 
			
		||||
 | 
			
		||||
    internal ServerState State {
 | 
			
		||||
      get {
 | 
			
		||||
        return _state;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal IEnumerable<WebSocketService> ServiceInstances {
 | 
			
		||||
      get {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          return new List<WebSocketService> ();
 | 
			
		||||
 | 
			
		||||
        lock (_sync)
 | 
			
		||||
        {
 | 
			
		||||
          return _sessions.Values.ToList ();
 | 
			
		||||
@@ -158,7 +168,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public IWebSocketSession this [string id] {
 | 
			
		||||
      get {
 | 
			
		||||
        var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
        var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
        if (msg != null)
 | 
			
		||||
        {
 | 
			
		||||
          _logger.Error (msg);
 | 
			
		||||
@@ -182,17 +192,16 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </value>
 | 
			
		||||
    public bool KeepClean {
 | 
			
		||||
      get {
 | 
			
		||||
        return _sweepTimer.Enabled;
 | 
			
		||||
        return _keepClean;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      internal set {
 | 
			
		||||
        if (value)
 | 
			
		||||
        {
 | 
			
		||||
          if (!_stopped)
 | 
			
		||||
            startSweepTimer ();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          stopSweepTimer ();
 | 
			
		||||
        if (!(value ^ _keepClean))
 | 
			
		||||
          return;
 | 
			
		||||
 | 
			
		||||
        _keepClean = value;
 | 
			
		||||
        if (_state == ServerState.START)
 | 
			
		||||
          _sweepTimer.Enabled = value;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -213,72 +222,20 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    #region Private Methods
 | 
			
		||||
 | 
			
		||||
    private void broadcast (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      foreach (var service in ServiceInstances)
 | 
			
		||||
        service.Send (data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void broadcast (string data)
 | 
			
		||||
    {
 | 
			
		||||
      foreach (var service in ServiceInstances)
 | 
			
		||||
        service.Send (data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void broadcastAsync (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      var services = ServiceInstances.GetEnumerator ();
 | 
			
		||||
      Action completed = null;
 | 
			
		||||
      completed = () =>
 | 
			
		||||
      {
 | 
			
		||||
        if (services.MoveNext ())
 | 
			
		||||
          services.Current.SendAsync (data, completed);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (services.MoveNext ())
 | 
			
		||||
        services.Current.SendAsync (data, completed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void broadcastAsync (string data)
 | 
			
		||||
    {
 | 
			
		||||
      var services = ServiceInstances.GetEnumerator ();
 | 
			
		||||
      Action completed = null;
 | 
			
		||||
      completed = () =>
 | 
			
		||||
      {
 | 
			
		||||
        if (services.MoveNext ())
 | 
			
		||||
          services.Current.SendAsync (data, completed);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (services.MoveNext ())
 | 
			
		||||
        services.Current.SendAsync (data, completed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static string createID ()
 | 
			
		||||
    {
 | 
			
		||||
      return Guid.NewGuid ().ToString ("N");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setSweepTimer ()
 | 
			
		||||
    private void setSweepTimer (double interval)
 | 
			
		||||
    {
 | 
			
		||||
      _sweepTimer = new Timer (60 * 1000);
 | 
			
		||||
      _sweepTimer = new Timer (interval);
 | 
			
		||||
      _sweepTimer.Elapsed += (sender, e) =>
 | 
			
		||||
      {
 | 
			
		||||
        Sweep ();
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startSweepTimer ()
 | 
			
		||||
    {
 | 
			
		||||
      if (!_sweepTimer.Enabled)
 | 
			
		||||
        _sweepTimer.Start ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void stopSweepTimer ()
 | 
			
		||||
    {
 | 
			
		||||
      if (_sweepTimer.Enabled)
 | 
			
		||||
        _sweepTimer.Stop ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Internal Methods
 | 
			
		||||
@@ -287,7 +244,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        if (_stopped)
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          return null;
 | 
			
		||||
 | 
			
		||||
        var id = createID ();
 | 
			
		||||
@@ -299,25 +256,42 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    internal void BroadcastInternally (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      if (_stopped)
 | 
			
		||||
        broadcast (data);
 | 
			
		||||
      else
 | 
			
		||||
        broadcastAsync (data);
 | 
			
		||||
      var services = ServiceInstances.GetEnumerator ();
 | 
			
		||||
      Action completed = null;
 | 
			
		||||
      completed = () =>
 | 
			
		||||
      {
 | 
			
		||||
        if (_state == ServerState.START && services.MoveNext ())
 | 
			
		||||
          services.Current.SendAsync (data, completed);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (_state == ServerState.START && services.MoveNext ())
 | 
			
		||||
        services.Current.SendAsync (data, completed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void BroadcastInternally (string data)
 | 
			
		||||
    {
 | 
			
		||||
      if (_stopped)
 | 
			
		||||
        broadcast (data);
 | 
			
		||||
      else
 | 
			
		||||
        broadcastAsync (data);
 | 
			
		||||
      var services = ServiceInstances.GetEnumerator ();
 | 
			
		||||
      Action completed = null;
 | 
			
		||||
      completed = () =>
 | 
			
		||||
      {
 | 
			
		||||
        if (_state == ServerState.START && services.MoveNext ())
 | 
			
		||||
          services.Current.SendAsync (data, completed);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (_state == ServerState.START && services.MoveNext ())
 | 
			
		||||
        services.Current.SendAsync (data, completed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal Dictionary<string, bool> BroadpingInternally (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      var result = new Dictionary<string, bool> ();
 | 
			
		||||
      foreach (var session in ServiceInstances)
 | 
			
		||||
      {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        result.Add (session.ID, session.Context.WebSocket.Ping (data));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
@@ -330,31 +304,37 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Start ()
 | 
			
		||||
    {
 | 
			
		||||
      _sweepTimer.Enabled = _keepClean;
 | 
			
		||||
      _state = ServerState.START;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Stop ()
 | 
			
		||||
    {
 | 
			
		||||
      stopSweepTimer ();
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        if (_stopped)
 | 
			
		||||
          return;
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
 | 
			
		||||
        _stopped = true;
 | 
			
		||||
        foreach (var session in ServiceInstances)
 | 
			
		||||
        _sweepTimer.Enabled = false;
 | 
			
		||||
        foreach (var session in _sessions.Values.ToList ())
 | 
			
		||||
          session.Context.WebSocket.Close ();
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.STOP;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Stop (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      stopSweepTimer ();
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        if (_stopped)
 | 
			
		||||
          return;
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
 | 
			
		||||
        _stopped = true;
 | 
			
		||||
        foreach (var session in ServiceInstances)
 | 
			
		||||
        _sweepTimer.Enabled = false;
 | 
			
		||||
        foreach (var session in _sessions.Values.ToList ())
 | 
			
		||||
          session.Context.WebSocket.Close (data);
 | 
			
		||||
 | 
			
		||||
        _state = ServerState.STOP;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -378,7 +358,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = data.CheckIfValidSendData ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -396,7 +376,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (string data)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = data.CheckIfValidSendData ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -415,6 +395,13 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    public Dictionary<string, bool> Broadping ()
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return BroadpingInternally (new byte [] {});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -431,10 +418,10 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    public Dictionary<string, bool> Broadping (string message)
 | 
			
		||||
    {
 | 
			
		||||
      if (message == null || message.Length == 0)
 | 
			
		||||
        return BroadpingInternally (new byte [] {});
 | 
			
		||||
        return Broadping ();
 | 
			
		||||
 | 
			
		||||
      var data = Encoding.UTF8.GetBytes (message);
 | 
			
		||||
      var msg = data.CheckIfValidPingData ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidPingData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -452,7 +439,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (string id)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -484,7 +471,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (ushort code, string reason, string id)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -516,7 +503,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (CloseStatusCode code, string reason, string id)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -545,7 +532,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool PingTo (string id)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -578,7 +565,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool PingTo (string message, string id)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -610,7 +597,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool SendTo (byte [] data, string id)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -643,7 +630,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool SendTo (string data, string id)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
@@ -666,7 +653,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public void Sweep ()
 | 
			
		||||
    {
 | 
			
		||||
      if (_stopped || _sweeping || Count == 0)
 | 
			
		||||
      if (_state != ServerState.START || _sweeping || Count == 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      lock (_forSweep)
 | 
			
		||||
@@ -674,11 +661,11 @@ namespace WebSocketSharp.Server
 | 
			
		||||
        _sweeping = true;
 | 
			
		||||
        foreach (var id in InactiveIDs)
 | 
			
		||||
        {
 | 
			
		||||
          if (_state != ServerState.START)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          lock (_sync)
 | 
			
		||||
          {
 | 
			
		||||
            if (_stopped)
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            WebSocketService session;
 | 
			
		||||
            if (_sessions.TryGetValue (id, out session))
 | 
			
		||||
            {
 | 
			
		||||
@@ -714,7 +701,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool TryGetSession (string id, out IWebSocketSession session)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = id.CheckIfValidSessionID ();
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,7 @@
 | 
			
		||||
    <Compile Include="WebSocketState.cs" />
 | 
			
		||||
    <Compile Include="Server\IWebSocketSession.cs" />
 | 
			
		||||
    <Compile Include="Server\WebSocketSessionManager.cs" />
 | 
			
		||||
    <Compile Include="Server\ServerState.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user