Modified the Sweep method of WebSocketServiceManager class
This commit is contained in:
		| @@ -64,6 +64,16 @@ namespace WebSocketSharp.Server { | |||||||
|  |  | ||||||
|     #endregion |     #endregion | ||||||
|  |  | ||||||
|  |     #region Internal Properties | ||||||
|  |  | ||||||
|  |     internal WebSocket WebSocket { | ||||||
|  |       get { | ||||||
|  |         return _websocket; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #endregion | ||||||
|  |  | ||||||
|     #region Protected Properties |     #region Protected Properties | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|   | |||||||
| @@ -31,21 +31,21 @@ using System.Collections.Generic; | |||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Timers; | using System.Timers; | ||||||
|  |  | ||||||
| namespace WebSocketSharp.Server { | namespace WebSocketSharp.Server | ||||||
|  | { | ||||||
|   /// <summary> |   /// <summary> | ||||||
|   /// Manages the collection of <see cref="WebSocketService"/> objects. |   /// Manages the collection of <see cref="WebSocketService"/> instances. | ||||||
|   /// </summary> |   /// </summary> | ||||||
|   public class WebSocketServiceManager { |   public class WebSocketServiceManager | ||||||
|  |   { | ||||||
|     #region Private Fields |     #region Private Fields | ||||||
|  |  | ||||||
|     private object                               _forSweep; |     private object                               _forSweep; | ||||||
|     private volatile bool                        _isStopped; |  | ||||||
|     private volatile bool                        _isSweeping; |  | ||||||
|     private Dictionary<string, WebSocketService> _services; |     private Dictionary<string, WebSocketService> _services; | ||||||
|  |     private volatile bool                        _stopped; | ||||||
|  |     private volatile bool                        _sweeping; | ||||||
|     private Timer                                _sweepTimer; |     private Timer                                _sweepTimer; | ||||||
|     private object                               _syncRoot; |     private object                               _sync; | ||||||
|  |  | ||||||
|     #endregion |     #endregion | ||||||
|  |  | ||||||
| @@ -54,10 +54,10 @@ namespace WebSocketSharp.Server { | |||||||
|     internal WebSocketServiceManager () |     internal WebSocketServiceManager () | ||||||
|     { |     { | ||||||
|       _forSweep = new object (); |       _forSweep = new object (); | ||||||
|       _isStopped  = false; |  | ||||||
|       _isSweeping = false; |  | ||||||
|       _services = new Dictionary<string, WebSocketService> (); |       _services = new Dictionary<string, WebSocketService> (); | ||||||
|       _syncRoot   = new object(); |       _stopped = false; | ||||||
|  |       _sweeping = false; | ||||||
|  |       _sync = new object (); | ||||||
|  |  | ||||||
|       setSweepTimer (); |       setSweepTimer (); | ||||||
|       startSweepTimer (); |       startSweepTimer (); | ||||||
| @@ -68,11 +68,12 @@ namespace WebSocketSharp.Server { | |||||||
|     #region Public Properties |     #region Public Properties | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Gets the collection of IDs of active <see cref="WebSocketService"/> objects |     /// Gets the collection of IDs of active <see cref="WebSocketService"/> instances | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |     /// managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <value> |     /// <value> | ||||||
|     /// An IEnumerable<string> that contains the collection of IDs of active <see cref="WebSocketService"/> objects. |     /// An IEnumerable<string> that contains the collection of IDs | ||||||
|  |     /// of active <see cref="WebSocketService"/> instances. | ||||||
|     /// </value> |     /// </value> | ||||||
|     public IEnumerable<string> ActiveIDs { |     public IEnumerable<string> ActiveIDs { | ||||||
|       get { |       get { | ||||||
| @@ -83,16 +84,16 @@ namespace WebSocketSharp.Server { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Gets the number of <see cref="WebSocketService"/> objects |     /// Gets the number of <see cref="WebSocketService"/> instances | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |     /// managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <value> |     /// <value> | ||||||
|     /// An <see cref="int"/> that contains the number of <see cref="WebSocketService"/> objects |     /// An <see cref="int"/> that contains the number of <see cref="WebSocketService"/> instances | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |     /// managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|     /// </value> |     /// </value> | ||||||
|     public int Count { |     public int Count { | ||||||
|       get { |       get { | ||||||
|         lock (_syncRoot) |         lock (_sync) | ||||||
|         { |         { | ||||||
|           return _services.Count; |           return _services.Count; | ||||||
|         } |         } | ||||||
| @@ -100,11 +101,29 @@ namespace WebSocketSharp.Server { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Gets the collection of IDs of inactive <see cref="WebSocketService"/> objects |     /// Gets the collection of IDs of <see cref="WebSocketService"/> instances | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |     /// managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <value> |     /// <value> | ||||||
|     /// An IEnumerable<string> that contains the collection of IDs of inactive <see cref="WebSocketService"/> objects. |     /// An IEnumerable<string> that contains the collection of IDs | ||||||
|  |     /// of <see cref="WebSocketService"/> instances. | ||||||
|  |     /// </value> | ||||||
|  |     public IEnumerable<string> IDs { | ||||||
|  |       get { | ||||||
|  |         lock (_sync) | ||||||
|  |         { | ||||||
|  |           return _services.Keys; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Gets the collection of IDs of inactive <see cref="WebSocketService"/> instances | ||||||
|  |     /// managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|  |     /// </summary> | ||||||
|  |     /// <value> | ||||||
|  |     /// An IEnumerable<string> that contains the collection of IDs | ||||||
|  |     /// of inactive <see cref="WebSocketService"/> instances. | ||||||
|     /// </value> |     /// </value> | ||||||
|     public IEnumerable<string> InactiveIDs { |     public IEnumerable<string> InactiveIDs { | ||||||
|       get { |       get { | ||||||
| @@ -114,29 +133,13 @@ namespace WebSocketSharp.Server { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// Gets the collection of IDs of <see cref="WebSocketService"/> objects |  | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |  | ||||||
|     /// </summary> |  | ||||||
|     /// <value> |  | ||||||
|     /// An IEnumerable<string> that contains the collection of IDs of <see cref="WebSocketService"/> objects. |  | ||||||
|     /// </value> |  | ||||||
|     public IEnumerable<string> IDs { |  | ||||||
|       get { |  | ||||||
|         lock (_syncRoot) |  | ||||||
|         { |  | ||||||
|           return _services.Keys; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Gets a value indicating whether the <see cref="WebSocketServiceManager"/> cleans up |     /// Gets a value indicating whether the <see cref="WebSocketServiceManager"/> cleans up | ||||||
|     /// the inactive <see cref="WebSocketService"/> objects periodically. |     /// the inactive <see cref="WebSocketService"/> instances periodically. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <value> |     /// <value> | ||||||
|     /// <c>true</c> if the <see cref="WebSocketServiceManager"/> cleans up the inactive <see cref="WebSocketService"/> objects |     /// <c>true</c> if the <see cref="WebSocketServiceManager"/> cleans up | ||||||
|     /// every 60 seconds; otherwise, <c>false</c>. |     /// the inactive <see cref="WebSocketService"/> instances every 60 seconds; otherwise, <c>false</c>. | ||||||
|     /// </value> |     /// </value> | ||||||
|     public bool Sweeping { |     public bool Sweeping { | ||||||
|       get { |       get { | ||||||
| @@ -144,10 +147,12 @@ namespace WebSocketSharp.Server { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       internal set { |       internal set { | ||||||
|         if (value && !_isStopped) |         if (value) | ||||||
|  |         { | ||||||
|  |           if (!_stopped) | ||||||
|             startSweepTimer (); |             startSweepTimer (); | ||||||
|  |         } | ||||||
|         if (!value) |         else | ||||||
|           stopSweepTimer (); |           stopSweepTimer (); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -158,7 +163,7 @@ namespace WebSocketSharp.Server { | |||||||
|  |  | ||||||
|     private void broadcast (byte [] data) |     private void broadcast (byte [] data) | ||||||
|     { |     { | ||||||
|       lock (_syncRoot) |       lock (_sync) | ||||||
|       { |       { | ||||||
|         foreach (var service in _services.Values) |         foreach (var service in _services.Values) | ||||||
|           service.Send (data); |           service.Send (data); | ||||||
| @@ -167,7 +172,7 @@ namespace WebSocketSharp.Server { | |||||||
|  |  | ||||||
|     private void broadcast (string data) |     private void broadcast (string data) | ||||||
|     { |     { | ||||||
|       lock (_syncRoot) |       lock (_sync) | ||||||
|       { |       { | ||||||
|         foreach (var service in _services.Values) |         foreach (var service in _services.Values) | ||||||
|           service.Send (data); |           service.Send (data); | ||||||
| @@ -208,13 +213,13 @@ namespace WebSocketSharp.Server { | |||||||
|  |  | ||||||
|     private Dictionary<string, WebSocketService> copy () |     private Dictionary<string, WebSocketService> copy () | ||||||
|     { |     { | ||||||
|       lock (_syncRoot) |       lock (_sync) | ||||||
|       { |       { | ||||||
|         return new Dictionary<string, WebSocketService> (_services); |         return new Dictionary<string, WebSocketService> (_services); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private string createID() |     private static string createID () | ||||||
|     { |     { | ||||||
|       return Guid.NewGuid ().ToString ("N"); |       return Guid.NewGuid ().ToString ("N"); | ||||||
|     } |     } | ||||||
| @@ -237,12 +242,12 @@ namespace WebSocketSharp.Server { | |||||||
|     private void stop (ushort code, string reason, bool ignoreArgs) |     private void stop (ushort code, string reason, bool ignoreArgs) | ||||||
|     { |     { | ||||||
|       stopSweepTimer (); |       stopSweepTimer (); | ||||||
|       lock (_syncRoot) |       lock (_sync) | ||||||
|       { |       { | ||||||
|         if (_isStopped) |         if (_stopped) | ||||||
|           return; |           return; | ||||||
|  |  | ||||||
|         _isStopped = true; |         _stopped = true; | ||||||
|         foreach (var service in copy ().Values) |         foreach (var service in copy ().Values) | ||||||
|           if (ignoreArgs) |           if (ignoreArgs) | ||||||
|             service.Stop (); |             service.Stop (); | ||||||
| @@ -263,9 +268,9 @@ namespace WebSocketSharp.Server { | |||||||
|  |  | ||||||
|     internal string Add (WebSocketService service) |     internal string Add (WebSocketService service) | ||||||
|     { |     { | ||||||
|       lock (_syncRoot) |       lock (_sync) | ||||||
|       { |       { | ||||||
|         if (_isStopped) |         if (_stopped) | ||||||
|           return null; |           return null; | ||||||
|  |  | ||||||
|         var id = createID (); |         var id = createID (); | ||||||
| @@ -277,7 +282,7 @@ namespace WebSocketSharp.Server { | |||||||
|  |  | ||||||
|     internal bool Remove (string id) |     internal bool Remove (string id) | ||||||
|     { |     { | ||||||
|       lock (_syncRoot) |       lock (_sync) | ||||||
|       { |       { | ||||||
|         return _services.Remove (id); |         return _services.Remove (id); | ||||||
|       } |       } | ||||||
| @@ -303,45 +308,45 @@ namespace WebSocketSharp.Server { | |||||||
|     #region Public Methods |     #region Public Methods | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Broadcasts the specified array of <see cref="byte"/> to the clients of every <see cref="WebSocketService"/> |     /// Broadcasts the specified array of <see cref="byte"/> to the clients of every | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |     /// <see cref="WebSocketService"/> instances managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <param name="data"> |     /// <param name="data"> | ||||||
|     /// An array of <see cref="byte"/> to broadcast. |     /// An array of <see cref="byte"/> to broadcast. | ||||||
|     /// </param> |     /// </param> | ||||||
|     public void Broadcast (byte [] data) |     public void Broadcast (byte [] data) | ||||||
|     { |     { | ||||||
|       if (_isStopped) |       if (_stopped) | ||||||
|         broadcast (data); |         broadcast (data); | ||||||
|       else |       else | ||||||
|         broadcastAsync (data); |         broadcastAsync (data); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Broadcasts the specified <see cref="string"/> to the clients of every <see cref="WebSocketService"/> |     /// Broadcasts the specified <see cref="string"/> to the clients of every | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |     /// <see cref="WebSocketService"/> instances managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <param name="data"> |     /// <param name="data"> | ||||||
|     /// A <see cref="string"/> to broadcast. |     /// A <see cref="string"/> to broadcast. | ||||||
|     /// </param> |     /// </param> | ||||||
|     public void Broadcast (string data) |     public void Broadcast (string data) | ||||||
|     { |     { | ||||||
|       if (_isStopped) |       if (_stopped) | ||||||
|         broadcast (data); |         broadcast (data); | ||||||
|       else |       else | ||||||
|         broadcastAsync (data); |         broadcastAsync (data); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Pings with the specified <see cref="string"/> to the clients of every <see cref="WebSocketService"/> |     /// Sends Pings with the specified <see cref="string"/> to the clients of every | ||||||
|     /// managed by the <see cref="WebSocketServiceManager"/>. |     /// <see cref="WebSocketService"/> instances managed by the <see cref="WebSocketServiceManager"/>. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <returns> |     /// <returns> | ||||||
|     /// A Dictionary<string, bool> that contains the collection of IDs and values |     /// A Dictionary<string, bool> that contains the collection of IDs and values indicating | ||||||
|     /// indicating whether each <see cref="WebSocketService"/> received a Pong in a time. |     /// whether each <see cref="WebSocketService"/> instances received a Pong in a time. | ||||||
|     /// </returns> |     /// </returns> | ||||||
|     /// <param name="message"> |     /// <param name="message"> | ||||||
|     /// A <see cref="string"/> that contains a message. |     /// A <see cref="string"/> that contains a message to send. | ||||||
|     /// </param> |     /// </param> | ||||||
|     public Dictionary<string, bool> Broadping (string message) |     public Dictionary<string, bool> Broadping (string message) | ||||||
|     { |     { | ||||||
| @@ -353,51 +358,61 @@ namespace WebSocketSharp.Server { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Cleans up the inactive <see cref="WebSocketService"/> objects. |     /// Cleans up the inactive <see cref="WebSocketService"/> instances. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public void Sweep () |     public void Sweep () | ||||||
|     { |     { | ||||||
|       if (_isStopped || _isSweeping || Count == 0) |       if (_stopped || _sweeping || Count == 0) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|       lock (_forSweep) |       lock (_forSweep) | ||||||
|       { |       { | ||||||
|         _isSweeping = true; |         _sweeping = true; | ||||||
|         foreach (var id in InactiveIDs) |         foreach (var id in InactiveIDs) | ||||||
|         { |         { | ||||||
|           lock (_syncRoot) |           lock (_sync) | ||||||
|           { |           { | ||||||
|             if (_isStopped) |             if (_stopped) | ||||||
|             { |             { | ||||||
|               _isSweeping = false; |               _sweeping = false; | ||||||
|               return; |               return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             WebSocketService service; |             WebSocketService service; | ||||||
|             if (TryGetWebSocketService(id, out service)) |             if (_services.TryGetValue (id, out service)) | ||||||
|  |             { | ||||||
|  |               var state = service.WebSocket.ReadyState; | ||||||
|  |               if (state == WsState.OPEN) | ||||||
|                 service.Stop (CloseStatusCode.ABNORMAL, String.Empty); |                 service.Stop (CloseStatusCode.ABNORMAL, String.Empty); | ||||||
|  |               else if (state == WsState.CLOSING) | ||||||
|  |                 continue; | ||||||
|  |               else | ||||||
|  |                 _services.Remove (id); | ||||||
|  |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         _isSweeping = false; |         _sweeping = false; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Tries to get the <see cref="WebSocketService"/> associated with the specified <paramref name="id"/>. |     /// Tries to get the <see cref="WebSocketService"/> associated with the specified ID. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <returns> |     /// <returns> | ||||||
|     /// <c>true</c> if the <see cref="WebSocketServiceManager"/> manages the <see cref="WebSocketService"/> with the specified <paramref name="id"/>; otherwise, <c>false</c>. |     /// <c>true</c> if the <see cref="WebSocketServiceManager"/> manages the <see cref="WebSocketService"/> | ||||||
|  |     /// with <paramref name="id"/>; otherwise, <c>false</c>. | ||||||
|     /// </returns> |     /// </returns> | ||||||
|     /// <param name="id"> |     /// <param name="id"> | ||||||
|     /// A <see cref="string"/> that contains the ID to find. |     /// A <see cref="string"/> that contains an ID to find. | ||||||
|     /// </param> |     /// </param> | ||||||
|     /// <param name="service"> |     /// <param name="service"> | ||||||
|     /// When this method returns, contains the <see cref="WebSocketService"/> with the specified <paramref name="id"/>, if the <paramref name="id"/> is found; otherwise, <see langword="null"/>. |     /// When this method returns, contains a <see cref="WebSocketService"/> with <paramref name="id"/> | ||||||
|  |     /// if it is found; otherwise, <see langword="null"/>. | ||||||
|     /// </param> |     /// </param> | ||||||
|     public bool TryGetWebSocketService (string id, out WebSocketService service) |     public bool TryGetWebSocketService (string id, out WebSocketService service) | ||||||
|     { |     { | ||||||
|       lock (_syncRoot) |       lock (_sync) | ||||||
|       { |       { | ||||||
|         return _services.TryGetValue (id, out service); |         return _services.TryGetValue (id, out service); | ||||||
|       } |       } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user