Refactored WebSocketServiceHostManager.cs, WebSocketSessionManager.cs
This commit is contained in:
		@@ -104,10 +104,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    #region Public Properties
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Gets the collection of every ID of the active sessions to the Websocket service.
 | 
			
		||||
    /// Gets the collection of every ID of the active sessions to the Websocket
 | 
			
		||||
    /// service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <value>
 | 
			
		||||
    /// An IEnumerable<string> that contains the collection of every ID of the active sessions.
 | 
			
		||||
    /// An IEnumerable<string> that contains the collection of every ID of
 | 
			
		||||
    /// the active sessions.
 | 
			
		||||
    /// </value>
 | 
			
		||||
    public IEnumerable<string> ActiveIDs {
 | 
			
		||||
      get {
 | 
			
		||||
@@ -121,12 +123,11 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// Gets the number of the sessions to the Websocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <value>
 | 
			
		||||
    /// An <see cref="int"/> that contains the number of the sessions.
 | 
			
		||||
    /// An <see cref="int"/> that represents the number of the sessions.
 | 
			
		||||
    /// </value>
 | 
			
		||||
    public int Count {
 | 
			
		||||
      get {
 | 
			
		||||
        lock (_sync)
 | 
			
		||||
        {
 | 
			
		||||
        lock (_sync) {
 | 
			
		||||
          return _sessions.Count;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -136,22 +137,24 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// Gets the collection of every ID of the sessions to the Websocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <value>
 | 
			
		||||
    /// An IEnumerable<string> that contains the collection of every ID of the sessions.
 | 
			
		||||
    /// An IEnumerable<string> that contains the collection of every ID of
 | 
			
		||||
    /// the sessions.
 | 
			
		||||
    /// </value>
 | 
			
		||||
    public IEnumerable<string> IDs {
 | 
			
		||||
      get {
 | 
			
		||||
        lock (_sync)
 | 
			
		||||
        {
 | 
			
		||||
        lock (_sync) {
 | 
			
		||||
          return _sessions.Keys.ToList ();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Gets the collection of every ID of the inactive sessions to the Websocket service.
 | 
			
		||||
    /// Gets the collection of every ID of the inactive sessions to the Websocket
 | 
			
		||||
    /// service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <value>
 | 
			
		||||
    /// An IEnumerable<string> that contains the collection of every ID of the inactive sessions.
 | 
			
		||||
    /// An IEnumerable<string> that contains the collection of every ID of
 | 
			
		||||
    /// the inactive sessions.
 | 
			
		||||
    /// </value>
 | 
			
		||||
    public IEnumerable<string> InactiveIDs {
 | 
			
		||||
      get {
 | 
			
		||||
@@ -165,11 +168,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// Gets a WebSocket session information with the specified <paramref name="id"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <value>
 | 
			
		||||
    /// A <see cref="IWebSocketSession"/> instance that contains the session information
 | 
			
		||||
    /// if the session is successfully found; otherwise, <see langword="null"/>.
 | 
			
		||||
    /// A <see cref="IWebSocketSession"/> instance that represents the session if
 | 
			
		||||
    /// it's successfully found; otherwise, <see langword="null"/>.
 | 
			
		||||
    /// </value>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that contains an ID of the session to find.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the WebSocket session to
 | 
			
		||||
    /// get.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public IWebSocketSession this [string id] {
 | 
			
		||||
      get {
 | 
			
		||||
@@ -181,11 +185,12 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Gets a value indicating whether the manager cleans up the inactive sessions periodically.
 | 
			
		||||
    /// Gets a value indicating whether the manager cleans up the inactive
 | 
			
		||||
    /// sessions periodically.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <value>
 | 
			
		||||
    /// <c>true</c> if the manager cleans up the inactive sessions every 60 seconds;
 | 
			
		||||
    /// otherwise, <c>false</c>.
 | 
			
		||||
    /// <c>true</c> if the manager cleans up the inactive sessions every 60
 | 
			
		||||
    /// seconds; otherwise, <c>false</c>.
 | 
			
		||||
    /// </value>
 | 
			
		||||
    public bool KeepClean {
 | 
			
		||||
      get {
 | 
			
		||||
@@ -206,15 +211,15 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// Gets the collection of the session informations to the Websocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <value>
 | 
			
		||||
    /// An IEnumerable<IWebSocketSession> that contains the collection of the session informations.
 | 
			
		||||
    /// An IEnumerable<IWebSocketSession> that contains the collection of
 | 
			
		||||
    /// the session informations to the Websocket service.
 | 
			
		||||
    /// </value>
 | 
			
		||||
    public IEnumerable<IWebSocketSession> Sessions {
 | 
			
		||||
      get {
 | 
			
		||||
        if (_state == ServerState.SHUTDOWN)
 | 
			
		||||
          return _emptySessions;
 | 
			
		||||
 | 
			
		||||
        lock (_sync)
 | 
			
		||||
        {
 | 
			
		||||
        lock (_sync) {
 | 
			
		||||
          return _sessions.Values.ToList ();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -224,53 +229,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    #region Private Methods
 | 
			
		||||
 | 
			
		||||
    private static string createID ()
 | 
			
		||||
    {
 | 
			
		||||
      return Guid.NewGuid ().ToString ("N");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setSweepTimer (double interval)
 | 
			
		||||
    {
 | 
			
		||||
      _sweepTimer = new System.Timers.Timer (interval);
 | 
			
		||||
      _sweepTimer.Elapsed += (sender, e) =>
 | 
			
		||||
      {
 | 
			
		||||
        Sweep ();
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private bool tryGetSession (string id, out IWebSocketSession session)
 | 
			
		||||
    {
 | 
			
		||||
      bool result;
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        result = _sessions.TryGetValue (id, out session);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!result)
 | 
			
		||||
        _logger.Error ("A WebSocket session with the specified ID not found.\nID: " + id);
 | 
			
		||||
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Internal Methods
 | 
			
		||||
 | 
			
		||||
    internal string Add (IWebSocketSession session)
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          return null;
 | 
			
		||||
 | 
			
		||||
        var id = createID ();
 | 
			
		||||
        _sessions.Add (id, session);
 | 
			
		||||
 | 
			
		||||
        return id;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Broadcast (Opcode opcode, byte [] data, Action completed)
 | 
			
		||||
    private void broadcast (Opcode opcode, byte [] data, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      var cache = new Dictionary<CompressionMethod, byte []> ();
 | 
			
		||||
      try {
 | 
			
		||||
@@ -286,7 +245,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Broadcast (Opcode opcode, Stream stream, Action completed)
 | 
			
		||||
    private void broadcast (Opcode opcode, Stream stream, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      var cache = new Dictionary <CompressionMethod, Stream> ();
 | 
			
		||||
      try {
 | 
			
		||||
@@ -305,11 +264,64 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void broadcastAsync (Opcode opcode, byte [] data, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      ThreadPool.QueueUserWorkItem (
 | 
			
		||||
        state => broadcast (opcode, data, completed));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void broadcastAsync (Opcode opcode, Stream stream, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      ThreadPool.QueueUserWorkItem (
 | 
			
		||||
        state => broadcast (opcode, stream, completed));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static string createID ()
 | 
			
		||||
    {
 | 
			
		||||
      return Guid.NewGuid ().ToString ("N");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setSweepTimer (double interval)
 | 
			
		||||
    {
 | 
			
		||||
      _sweepTimer = new System.Timers.Timer (interval);
 | 
			
		||||
      _sweepTimer.Elapsed += (sender, e) => Sweep ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private bool tryGetSession (string id, out IWebSocketSession session)
 | 
			
		||||
    {
 | 
			
		||||
      bool result;
 | 
			
		||||
      lock (_sync) {
 | 
			
		||||
        result = _sessions.TryGetValue (id, out session);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!result)
 | 
			
		||||
        _logger.Error (
 | 
			
		||||
          "A WebSocket session with the specified ID not found.\nID: " + id);
 | 
			
		||||
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Internal Methods
 | 
			
		||||
 | 
			
		||||
    internal string Add (IWebSocketSession session)
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync) {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          return null;
 | 
			
		||||
 | 
			
		||||
        var id = createID ();
 | 
			
		||||
        _sessions.Add (id, session);
 | 
			
		||||
 | 
			
		||||
        return id;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Broadcast (
 | 
			
		||||
      Opcode opcode, byte [] data, Dictionary<CompressionMethod, byte []> cache)
 | 
			
		||||
    {
 | 
			
		||||
      foreach (var session in Sessions)
 | 
			
		||||
      {
 | 
			
		||||
      foreach (var session in Sessions) {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
@@ -320,8 +332,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    internal void Broadcast (
 | 
			
		||||
      Opcode opcode, Stream stream, Dictionary <CompressionMethod, Stream> cache)
 | 
			
		||||
    {
 | 
			
		||||
      foreach (var session in Sessions)
 | 
			
		||||
      {
 | 
			
		||||
      foreach (var session in Sessions) {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
@@ -329,35 +340,16 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void BroadcastAsync (Opcode opcode, byte [] data, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      WaitCallback callback = state =>
 | 
			
		||||
      {
 | 
			
		||||
        Broadcast (opcode, data, completed);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      ThreadPool.QueueUserWorkItem (callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void BroadcastAsync (Opcode opcode, Stream stream, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      WaitCallback callback = state =>
 | 
			
		||||
      {
 | 
			
		||||
        Broadcast (opcode, stream, completed);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      ThreadPool.QueueUserWorkItem (callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal Dictionary<string, bool> Broadping (byte [] frameAsBytes, int timeOut)
 | 
			
		||||
    internal Dictionary<string, bool> Broadping (
 | 
			
		||||
      byte [] frameAsBytes, int timeOut)
 | 
			
		||||
    {
 | 
			
		||||
      var result = new Dictionary<string, bool> ();
 | 
			
		||||
      foreach (var session in Sessions)
 | 
			
		||||
      {
 | 
			
		||||
      foreach (var session in Sessions) {
 | 
			
		||||
        if (_state != ServerState.START)
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        result.Add (session.ID, session.Context.WebSocket.Ping (frameAsBytes, timeOut));
 | 
			
		||||
        result.Add (
 | 
			
		||||
          session.ID, session.Context.WebSocket.Ping (frameAsBytes, timeOut));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return result;
 | 
			
		||||
@@ -365,8 +357,7 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    internal bool Remove (string id)
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
      lock (_sync) {
 | 
			
		||||
        return _sessions.Remove (id);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -381,17 +372,17 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    {
 | 
			
		||||
      var payload = new PayloadData (data);
 | 
			
		||||
      var args = new CloseEventArgs (payload);
 | 
			
		||||
      var frameAsBytes = send
 | 
			
		||||
                       ? WsFrame.CreateCloseFrame (Mask.UNMASK, payload).ToByteArray ()
 | 
			
		||||
                       : null;
 | 
			
		||||
      var frameAsBytes =
 | 
			
		||||
        send
 | 
			
		||||
        ? WsFrame.CreateCloseFrame (Mask.UNMASK, payload).ToByteArray ()
 | 
			
		||||
        : null;
 | 
			
		||||
 | 
			
		||||
      Stop (args, frameAsBytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal void Stop (CloseEventArgs args, byte [] frameAsBytes)
 | 
			
		||||
    {
 | 
			
		||||
      lock (_sync)
 | 
			
		||||
      {
 | 
			
		||||
      lock (_sync) {
 | 
			
		||||
        _state = ServerState.SHUTDOWN;
 | 
			
		||||
 | 
			
		||||
        _sweepTimer.Enabled = false;
 | 
			
		||||
@@ -407,177 +398,170 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    #region Public Methods
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a binary <paramref name="data"/> to all clients of a WebSocket service.
 | 
			
		||||
    /// Broadcasts a binary <paramref name="data"/> to all clients of the
 | 
			
		||||
    /// WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method does not wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// An array of <see cref="byte"/> that contains a binary data to broadcast.
 | 
			
		||||
    /// An array of <see cref="byte"/> that contains the binary data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (byte [] data)
 | 
			
		||||
    {
 | 
			
		||||
      Broadcast (data, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a text <paramref name="data"/> to all clients of a WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method does not wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// A <see cref="string"/> that contains a text data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (string data)
 | 
			
		||||
    {
 | 
			
		||||
      Broadcast (data, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a binary <paramref name="data"/> to all clients of a WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method does not wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// An array of <see cref="byte"/> that contains a binary data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="completed">
 | 
			
		||||
    /// A <see cref="Action"/> delegate that references the method(s) called when
 | 
			
		||||
    /// the broadcast is complete.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (byte [] data, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (data.LongLength <= WebSocket.FragmentLength)
 | 
			
		||||
        BroadcastAsync (Opcode.BINARY, data, completed);
 | 
			
		||||
        broadcast (Opcode.BINARY, data, null);
 | 
			
		||||
      else
 | 
			
		||||
        BroadcastAsync (Opcode.BINARY, new MemoryStream (data), completed);
 | 
			
		||||
        broadcast (Opcode.BINARY, new MemoryStream (data), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a text <paramref name="data"/> to all clients of a WebSocket service.
 | 
			
		||||
    /// Broadcasts a text <paramref name="data"/> to all clients of the WebSocket
 | 
			
		||||
    /// service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method does not wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// A <see cref="string"/> that contains a text data to broadcast.
 | 
			
		||||
    /// A <see cref="string"/> that represents the text data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="completed">
 | 
			
		||||
    /// A <see cref="Action"/> delegate that references the method(s) called when
 | 
			
		||||
    /// the broadcast is complete.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (string data, Action completed)
 | 
			
		||||
    public void Broadcast (string data)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var rawData = Encoding.UTF8.GetBytes (data);
 | 
			
		||||
      if (rawData.LongLength <= WebSocket.FragmentLength)
 | 
			
		||||
        BroadcastAsync (Opcode.TEXT, rawData, completed);
 | 
			
		||||
        broadcast (Opcode.TEXT, rawData, null);
 | 
			
		||||
      else
 | 
			
		||||
        BroadcastAsync (Opcode.TEXT, new MemoryStream (rawData), completed);
 | 
			
		||||
        broadcast (Opcode.TEXT, new MemoryStream (rawData), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a binary data from the specified <see cref="Stream"/>
 | 
			
		||||
    /// to all clients of a WebSocket service.
 | 
			
		||||
    /// Broadcasts a binary <paramref name="data"/> asynchronously to all clients
 | 
			
		||||
    /// of the WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method does not wait for the broadcast to be complete.
 | 
			
		||||
    /// This method doesn't wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="stream">
 | 
			
		||||
    /// A <see cref="Stream"/> object from which contains a binary data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="length">
 | 
			
		||||
    /// An <see cref="int"/> that contains the number of bytes to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (Stream stream, int length)
 | 
			
		||||
    {
 | 
			
		||||
      Broadcast (stream, length, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a binary data from the specified <see cref="Stream"/>
 | 
			
		||||
    /// to all clients of a WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method does not wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="stream">
 | 
			
		||||
    /// A <see cref="Stream"/> object from which contains a binary data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="length">
 | 
			
		||||
    /// An <see cref="int"/> that contains the number of bytes to broadcast.
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// An array of <see cref="byte"/> that contains the binary data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="completed">
 | 
			
		||||
    /// A <see cref="Action"/> delegate that references the method(s) called when
 | 
			
		||||
    /// the broadcast is complete.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void Broadcast (Stream stream, int length, Action completed)
 | 
			
		||||
    public void BroadcastAsync (byte [] data, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (data.LongLength <= WebSocket.FragmentLength)
 | 
			
		||||
        broadcastAsync (Opcode.BINARY, data, completed);
 | 
			
		||||
      else
 | 
			
		||||
        broadcastAsync (Opcode.BINARY, new MemoryStream (data), completed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a text <paramref name="data"/> asynchronously to all clients of
 | 
			
		||||
    /// the WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method doesn't wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// A <see cref="string"/> that represents the text data to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="completed">
 | 
			
		||||
    /// A <see cref="Action"/> delegate that references the method(s) called when
 | 
			
		||||
    /// the broadcast is complete.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void BroadcastAsync (string data, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? data.CheckIfValidSendData ();
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var rawData = Encoding.UTF8.GetBytes (data);
 | 
			
		||||
      if (rawData.LongLength <= WebSocket.FragmentLength)
 | 
			
		||||
        broadcastAsync (Opcode.TEXT, rawData, completed);
 | 
			
		||||
      else
 | 
			
		||||
        broadcastAsync (Opcode.TEXT, new MemoryStream (rawData), completed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Broadcasts a binary data from the specified <see cref="Stream"/>
 | 
			
		||||
    /// asynchronously to all clients of the WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// This method doesn't wait for the broadcast to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="stream">
 | 
			
		||||
    /// A <see cref="Stream"/> object from which contains the binary data to
 | 
			
		||||
    /// broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="length">
 | 
			
		||||
    /// An <see cref="int"/> that represents the number of bytes to broadcast.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="completed">
 | 
			
		||||
    /// A <see cref="Action"/> delegate that references the method(s) called when
 | 
			
		||||
    /// the broadcast is complete.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void BroadcastAsync (Stream stream, int length, Action completed)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                stream.CheckIfCanRead () ??
 | 
			
		||||
                (length < 1 ? "'length' must be greater than 0." : null);
 | 
			
		||||
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      stream.ReadBytesAsync (
 | 
			
		||||
        length,
 | 
			
		||||
        data =>
 | 
			
		||||
        {
 | 
			
		||||
        data => {
 | 
			
		||||
          var len = data.Length;
 | 
			
		||||
          if (len == 0)
 | 
			
		||||
          {
 | 
			
		||||
          if (len == 0) {
 | 
			
		||||
            _logger.Error ("A data cannot be read from 'stream'.");
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (len < length)
 | 
			
		||||
            _logger.Warn (String.Format (
 | 
			
		||||
              "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}",
 | 
			
		||||
              length,
 | 
			
		||||
              len));
 | 
			
		||||
            _logger.Warn (
 | 
			
		||||
              String.Format (
 | 
			
		||||
                "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}",
 | 
			
		||||
                length,
 | 
			
		||||
                len));
 | 
			
		||||
 | 
			
		||||
          if (len <= WebSocket.FragmentLength)
 | 
			
		||||
            Broadcast (Opcode.BINARY, data, completed);
 | 
			
		||||
            broadcast (Opcode.BINARY, data, completed);
 | 
			
		||||
          else
 | 
			
		||||
            Broadcast (Opcode.BINARY, new MemoryStream (data), completed);
 | 
			
		||||
            broadcast (Opcode.BINARY, new MemoryStream (data), completed);
 | 
			
		||||
        },
 | 
			
		||||
        ex =>
 | 
			
		||||
        {
 | 
			
		||||
          _logger.Fatal (ex.ToString ());
 | 
			
		||||
        });
 | 
			
		||||
        ex => _logger.Fatal (ex.ToString ()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Sends Pings to all clients of a WebSocket service.
 | 
			
		||||
    /// Sends Pings to all clients of the WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>
 | 
			
		||||
    /// A Dictionary<string, bool> that contains the collection of pairs of session ID and
 | 
			
		||||
    /// value indicating whether the WebSocket service received a Pong from each client in a time.
 | 
			
		||||
    /// A Dictionary<string, bool> that contains the collection of pairs of
 | 
			
		||||
    /// session ID and value indicating whether the WebSocket service received a
 | 
			
		||||
    /// Pong from each client in a time.
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    public Dictionary<string, bool> Broadping ()
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
@@ -587,14 +571,15 @@ namespace WebSocketSharp.Server
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Sends Pings with the specified <paramref name="message"/> to all clients
 | 
			
		||||
    /// of a WebSocket service.
 | 
			
		||||
    /// of the WebSocket service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>
 | 
			
		||||
    /// A Dictionary<string, bool> that contains the collection of pairs of session ID and
 | 
			
		||||
    /// value indicating whether the WebSocket service received a Pong from each client in a time.
 | 
			
		||||
    /// A Dictionary<string, bool> that contains the collection of pairs of
 | 
			
		||||
    /// session ID and value indicating whether the WebSocket service received a
 | 
			
		||||
    /// Pong from each client in a time.
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    /// <param name="message">
 | 
			
		||||
    /// A <see cref="string"/> that contains a message to send.
 | 
			
		||||
    /// A <see cref="string"/> that represents the message to send.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public Dictionary<string, bool> Broadping (string message)
 | 
			
		||||
    {
 | 
			
		||||
@@ -605,20 +590,20 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      var msg = _state.CheckIfStarted () ??
 | 
			
		||||
                (data = Encoding.UTF8.GetBytes (message)).CheckIfValidPingData ();
 | 
			
		||||
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return Broadping (WsFrame.CreatePingFrame (Mask.UNMASK, data).ToByteArray (), 1000);
 | 
			
		||||
      return Broadping (
 | 
			
		||||
        WsFrame.CreatePingFrame (Mask.UNMASK, data).ToByteArray (), 1000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Closes the session with the specified <paramref name="id"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that contains a session ID to find.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to close.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (string id)
 | 
			
		||||
    {
 | 
			
		||||
@@ -628,17 +613,17 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Closes the session with the specified <paramref name="id"/>, <paramref name="code"/>
 | 
			
		||||
    /// and <paramref name="reason"/>.
 | 
			
		||||
    /// Closes the session with the specified <paramref name="id"/>,
 | 
			
		||||
    /// <paramref name="code"/> and <paramref name="reason"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that contains a session ID to find.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to close.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="code">
 | 
			
		||||
    /// A <see cref="ushort"/> that contains a status code indicating the reason for closure.
 | 
			
		||||
    /// A <see cref="ushort"/> that represents the status code for closure.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="reason">
 | 
			
		||||
    /// A <see cref="string"/> that contains the reason for closure.
 | 
			
		||||
    /// A <see cref="string"/> that represents the reason for closure.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (string id, ushort code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
@@ -648,17 +633,18 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Closes the session with the specified <paramref name="id"/>, <paramref name="code"/>
 | 
			
		||||
    /// and <paramref name="reason"/>.
 | 
			
		||||
    /// Closes the session with the specified <paramref name="id"/>,
 | 
			
		||||
    /// <paramref name="code"/> and <paramref name="reason"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that contains a session ID to find.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to close.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="code">
 | 
			
		||||
    /// One of the <see cref="CloseStatusCode"/> values that indicate the status codes for closure.
 | 
			
		||||
    /// One of the <see cref="CloseStatusCode"/> values that indicate the status
 | 
			
		||||
    /// codes for closure.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="reason">
 | 
			
		||||
    /// A <see cref="string"/> that contains the reason for closure.
 | 
			
		||||
    /// A <see cref="string"/> that represents the reason for closure.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public void CloseSession (string id, CloseStatusCode code, string reason)
 | 
			
		||||
    {
 | 
			
		||||
@@ -668,20 +654,22 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Sends a Ping to the client associated with the specified <paramref name="id"/>.
 | 
			
		||||
    /// Sends a Ping to the client associated with the specified
 | 
			
		||||
    /// <paramref name="id"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>
 | 
			
		||||
    /// <c>true</c> if the WebSocket service receives a Pong from the client in a time;
 | 
			
		||||
    /// otherwise, <c>false</c>.
 | 
			
		||||
    /// <c>true</c> if the WebSocket service receives a Pong from the client in a
 | 
			
		||||
    /// time; otherwise, <c>false</c>.
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that contains a session ID that represents the destination
 | 
			
		||||
    /// for the Ping.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to send the
 | 
			
		||||
    /// Ping to.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool PingTo (string id)
 | 
			
		||||
    {
 | 
			
		||||
      IWebSocketSession session;
 | 
			
		||||
      return TryGetSession (id, out session) && session.Context.WebSocket.Ping ();
 | 
			
		||||
      return TryGetSession (id, out session) &&
 | 
			
		||||
             session.Context.WebSocket.Ping ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -689,20 +677,21 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// associated with the specified <paramref name="id"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>
 | 
			
		||||
    /// <c>true</c> if the WebSocket service receives a Pong from the client in a time;
 | 
			
		||||
    /// otherwise, <c>false</c>.
 | 
			
		||||
    /// <c>true</c> if the WebSocket service receives a Pong from the client in a
 | 
			
		||||
    /// time; otherwise, <c>false</c>.
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that contains a session ID that represents the destination
 | 
			
		||||
    /// for the Ping.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to send the
 | 
			
		||||
    /// Ping to.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="message">
 | 
			
		||||
    /// A <see cref="string"/> that contains a message to send.
 | 
			
		||||
    /// A <see cref="string"/> that represents the message to send.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool PingTo (string id, string message)
 | 
			
		||||
    {
 | 
			
		||||
      IWebSocketSession session;
 | 
			
		||||
      return TryGetSession (id, out session) && session.Context.WebSocket.Ping (message);
 | 
			
		||||
      return TryGetSession (id, out session) &&
 | 
			
		||||
             session.Context.WebSocket.Ping (message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -710,8 +699,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// specified <paramref name="id"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that represents the session ID that represents the
 | 
			
		||||
    /// destination for the data.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to send the
 | 
			
		||||
    /// data to.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// An array of <see cref="byte"/> that contains the binary data to send.
 | 
			
		||||
@@ -728,8 +717,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// specified <paramref name="id"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that represents the session ID that represents the
 | 
			
		||||
    /// destination for the data.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to send the
 | 
			
		||||
    /// data to.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// A <see cref="string"/> that represents the text data to send.
 | 
			
		||||
@@ -749,8 +738,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// This method doesn't wait for the send to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that represents the session ID that represents the
 | 
			
		||||
    /// destination for the data.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to send the
 | 
			
		||||
    /// data to.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// An array of <see cref="byte"/> that contains the binary data to send.
 | 
			
		||||
@@ -776,8 +765,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// This method doesn't wait for the send to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that represents the session ID that represents the
 | 
			
		||||
    /// destination for the data.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to send the
 | 
			
		||||
    /// data to.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="data">
 | 
			
		||||
    /// A <see cref="string"/> that represents the text data to send.
 | 
			
		||||
@@ -803,8 +792,8 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    /// This method doesn't wait for the send to be complete.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that represents the session ID that represents the
 | 
			
		||||
    /// destination for the data.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to send the
 | 
			
		||||
    /// data to.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="stream">
 | 
			
		||||
    /// A <see cref="Stream"/> object from which contains the binary data to send.
 | 
			
		||||
@@ -834,19 +823,15 @@ namespace WebSocketSharp.Server
 | 
			
		||||
      if (_state != ServerState.START || _sweeping || Count == 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      lock (_forSweep)
 | 
			
		||||
      {
 | 
			
		||||
      lock (_forSweep) {
 | 
			
		||||
        _sweeping = true;
 | 
			
		||||
        foreach (var id in InactiveIDs)
 | 
			
		||||
        {
 | 
			
		||||
        foreach (var id in InactiveIDs) {
 | 
			
		||||
          if (_state != ServerState.START)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          lock (_sync)
 | 
			
		||||
          {
 | 
			
		||||
          lock (_sync) {
 | 
			
		||||
            IWebSocketSession session;
 | 
			
		||||
            if (_sessions.TryGetValue (id, out session))
 | 
			
		||||
            {
 | 
			
		||||
            if (_sessions.TryGetValue (id, out session)) {
 | 
			
		||||
              var state = session.State;
 | 
			
		||||
              if (state == WebSocketState.OPEN)
 | 
			
		||||
                session.Context.WebSocket.Close (CloseStatusCode.ABNORMAL);
 | 
			
		||||
@@ -863,24 +848,24 @@ namespace WebSocketSharp.Server
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Tries to get a WebSocket session information with the specified <paramref name="id"/>.
 | 
			
		||||
    /// Tries to get a WebSocket session information with the specified
 | 
			
		||||
    /// <paramref name="id"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>
 | 
			
		||||
    /// <c>true</c> if the session is successfully found; otherwise, <c>false</c>.
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    /// <param name="id">
 | 
			
		||||
    /// A <see cref="string"/> that contains an ID of the session to find.
 | 
			
		||||
    /// A <see cref="string"/> that represents the ID of the session to get.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="session">
 | 
			
		||||
    /// When this method returns, a <see cref="IWebSocketSession"/> instance that contains
 | 
			
		||||
    /// the session information if the session is successfully found; otherwise, <see langword="null"/>.
 | 
			
		||||
    /// This parameter is passed uninitialized.
 | 
			
		||||
    /// When this method returns, a <see cref="IWebSocketSession"/> instance that
 | 
			
		||||
    /// represents the session if it's successfully found; otherwise,
 | 
			
		||||
    /// <see langword="null"/>. This parameter is passed uninitialized.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    public bool TryGetSession (string id, out IWebSocketSession session)
 | 
			
		||||
    {
 | 
			
		||||
      var msg = _state.CheckIfStarted () ?? id.CheckIfValidSessionID ();
 | 
			
		||||
      if (msg != null)
 | 
			
		||||
      {
 | 
			
		||||
      if (msg != null) {
 | 
			
		||||
        _logger.Error (msg);
 | 
			
		||||
        session = null;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user