From e84caebfa818ee75db467f550e7cb7fbf6aa019d Mon Sep 17 00:00:00 2001 From: sta Date: Thu, 18 Sep 2014 20:52:38 +0900 Subject: [PATCH] Refactored WebSocketServiceManager.cs --- websocket-sharp/Server/HttpServer.cs | 8 +- websocket-sharp/Server/WebSocketServer.cs | 8 +- .../Server/WebSocketServiceHost.cs | 2 +- .../Server/WebSocketServiceManager.cs | 222 +++++++++--------- 4 files changed, 116 insertions(+), 124 deletions(-) diff --git a/websocket-sharp/Server/HttpServer.cs b/websocket-sharp/Server/HttpServer.cs index 24d615ef..9dfb6842 100644 --- a/websocket-sharp/Server/HttpServer.cs +++ b/websocket-sharp/Server/HttpServer.cs @@ -491,7 +491,7 @@ namespace WebSocketSharp.Server private void processWebSocketRequest (HttpListenerWebSocketContext context) { WebSocketServiceHost host; - if (!_services.TryGetServiceHostInternally (context.RequestUri.AbsolutePath, out host)) { + if (!_services.InternalTryGetServiceHost (context.RequestUri.AbsolutePath, out host)) { context.Close (HttpStatusCode.NotImplemented); return; } @@ -615,11 +615,7 @@ namespace WebSocketSharp.Server return; } - var host = new WebSocketServiceHost (path, initializer, _logger); - if (!KeepClean) - host.KeepClean = false; - - _services.Add (host.Path, host); + _services.Add (path, initializer); } /// diff --git a/websocket-sharp/Server/WebSocketServer.cs b/websocket-sharp/Server/WebSocketServer.cs index 88d20bb8..9d8377ca 100644 --- a/websocket-sharp/Server/WebSocketServer.cs +++ b/websocket-sharp/Server/WebSocketServer.cs @@ -594,7 +594,7 @@ namespace WebSocketSharp.Server } WebSocketServiceHost host; - if (!_services.TryGetServiceHostInternally (uri.AbsolutePath, out host)) { + if (!_services.InternalTryGetServiceHost (uri.AbsolutePath, out host)) { context.Close (HttpStatusCode.NotImplemented); return; } @@ -732,11 +732,7 @@ namespace WebSocketSharp.Server return; } - var host = new WebSocketServiceHost (path, initializer, _logger); - if (!KeepClean) - host.KeepClean = false; - - _services.Add (host.Path, host); + _services.Add (path, initializer); } /// diff --git a/websocket-sharp/Server/WebSocketServiceHost.cs b/websocket-sharp/Server/WebSocketServiceHost.cs index 8515ad2f..57d9e6a6 100644 --- a/websocket-sharp/Server/WebSocketServiceHost.cs +++ b/websocket-sharp/Server/WebSocketServiceHost.cs @@ -134,7 +134,7 @@ namespace WebSocketSharp.Server internal WebSocketServiceHost (string path, Func initializer, Logger logger) { - _path = HttpUtility.UrlDecode (path).TrimEndSlash (); + _path = path; _initializer = initializer; _sessions = new WebSocketSessionManager (logger); } diff --git a/websocket-sharp/Server/WebSocketServiceManager.cs b/websocket-sharp/Server/WebSocketServiceManager.cs index 73c587ea..04b47123 100644 --- a/websocket-sharp/Server/WebSocketServiceManager.cs +++ b/websocket-sharp/Server/WebSocketServiceManager.cs @@ -27,6 +27,7 @@ #endregion using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; @@ -43,8 +44,8 @@ namespace WebSocketSharp.Server { #region Private Fields + private volatile bool _clean; private Dictionary _hosts; - private volatile bool _keepClean; private Logger _logger; private volatile ServerState _state; private object _sync; @@ -62,10 +63,10 @@ namespace WebSocketSharp.Server { _logger = logger; + _clean = true; _hosts = new Dictionary (); - _keepClean = true; _state = ServerState.Ready; - _sync = new object (); + _sync = ((ICollection) _hosts).SyncRoot; } #endregion @@ -73,45 +74,43 @@ namespace WebSocketSharp.Server #region Public Properties /// - /// Gets the number of the WebSocket services provided by the server. + /// Gets the number of the WebSocket services. /// /// - /// An that represents the number of the WebSocket services. + /// An that represents the number of the services. /// public int Count { get { - lock (_sync) { + lock (_sync) return _hosts.Count; - } } } /// - /// Gets the collection of every information in the Websocket services provided by the server. + /// Gets the host instances for the Websocket services. /// /// - /// An IEnumerable<WebSocketServiceHost> that contains the collection of every - /// information in the Websocket services. + /// An IEnumerable<WebSocketServiceHost> instance that provides an enumerator + /// which supports the iteration over the collection of the host instances for the services. /// public IEnumerable Hosts { get { - lock (_sync) { + lock (_sync) return _hosts.Values.ToList (); - } } } /// - /// Gets the information in a WebSocket service with the specified . + /// Gets the WebSocket service host with the specified . /// /// - /// A instance that provides the access to the WebSocket - /// service if it's successfully found; otherwise, . + /// A instance that provides the access to + /// the information for the service, or if it's not found. /// /// - /// A that represents the absolute path to the WebSocket service to find. + /// A that represents the absolute path to the service to find. /// - public WebSocketServiceHost this [string path] { + public WebSocketServiceHost this[string path] { get { WebSocketServiceHost host; TryGetServiceHost (path, out host); @@ -121,24 +120,24 @@ namespace WebSocketSharp.Server } /// - /// Gets a value indicating whether the manager cleans up the inactive sessions in the - /// WebSocket services provided by the server periodically. + /// Gets a value indicating whether the manager cleans up the inactive sessions + /// in the WebSocket services periodically. /// /// - /// true if the manager cleans up the inactive sessions every 60 seconds; otherwise, - /// false. + /// true if the manager cleans up the inactive sessions every 60 seconds; + /// otherwise, false. /// public bool KeepClean { get { - return _keepClean; + return _clean; } internal set { lock (_sync) { - if (!(value ^ _keepClean)) + if (!(value ^ _clean)) return; - _keepClean = value; + _clean = value; foreach (var host in _hosts.Values) host.KeepClean = value; } @@ -146,37 +145,36 @@ namespace WebSocketSharp.Server } /// - /// Gets the collection of every path to the WebSocket services provided by the server. + /// Gets the paths for the WebSocket services. /// /// - /// An IEnumerable<string> that contains the collection of every path to the WebSocket - /// services. + /// An IEnumerable<string> instance that provides an enumerator which supports + /// the iteration over the collection of the paths for the services. /// public IEnumerable Paths { get { - lock (_sync) { + lock (_sync) return _hosts.Keys.ToList (); - } } } /// - /// Gets the number of the sessions in the WebSocket services provided by the server. + /// Gets the total number of the sessions in the WebSocket services. /// /// - /// An that represents the number of the sessions. + /// An that represents the total number of the sessions in the services. /// public int SessionCount { get { - var count = 0; + var cnt = 0; foreach (var host in Hosts) { if (_state != ServerState.Start) break; - count += host.Sessions.Count; + cnt += host.Sessions.Count; } - return count; + return cnt; } } @@ -184,9 +182,9 @@ namespace WebSocketSharp.Server #region Private Methods - private void broadcast (Opcode opcode, byte [] data, Action completed) + private void broadcast (Opcode opcode, byte[] data, Action completed) { - var cache = new Dictionary (); + var cache = new Dictionary (); try { foreach (var host in Hosts) { if (_state != ServerState.Start) @@ -231,47 +229,52 @@ namespace WebSocketSharp.Server } } - private void broadcastAsync (Opcode opcode, byte [] data, Action completed) + private void broadcastAsync (Opcode opcode, byte[] data, Action completed) { - ThreadPool.QueueUserWorkItem ( - state => broadcast (opcode, data, completed)); + ThreadPool.QueueUserWorkItem (state => broadcast (opcode, data, completed)); } private void broadcastAsync (Opcode opcode, Stream stream, Action completed) { - ThreadPool.QueueUserWorkItem ( - state => broadcast (opcode, stream, completed)); + ThreadPool.QueueUserWorkItem (state => broadcast (opcode, stream, completed)); } private Dictionary> broadping ( - byte [] frame, int millisecondsTimeout) + byte[] frameAsBytes, int millisecondsTimeout) { - var result = new Dictionary> (); + var res = new Dictionary> (); foreach (var host in Hosts) { if (_state != ServerState.Start) break; - result.Add (host.Path, host.Sessions.Broadping (frame, millisecondsTimeout)); + res.Add (host.Path, host.Sessions.Broadping (frameAsBytes, millisecondsTimeout)); } - return result; + return res; } #endregion #region Internal Methods - internal void Add (string path, WebSocketServiceHost host) + internal void Add (string path, Func initializer) + where TBehavior : WebSocketBehavior { lock (_sync) { - WebSocketServiceHost find; - if (_hosts.TryGetValue (path, out find)) { + path = HttpUtility.UrlDecode (path).TrimEndSlash (); + + WebSocketServiceHost host; + if (_hosts.TryGetValue (path, out host)) { _logger.Error ( "A WebSocket service with the specified path already exists.\npath: " + path); return; } + host = new WebSocketServiceHost (path, initializer, _logger); + if (!_clean) + host.KeepClean = false; + if (_state == ServerState.Start) host.Sessions.Start (); @@ -279,14 +282,27 @@ namespace WebSocketSharp.Server } } - internal bool Remove (string path) + internal bool InternalTryGetServiceHost (string path, out WebSocketServiceHost host) { - path = HttpUtility.UrlDecode (path).TrimEndSlash (); + bool res; + lock (_sync) { + path = HttpUtility.UrlDecode (path).TrimEndSlash (); + res = _hosts.TryGetValue (path, out host); + } + + if (!res) + _logger.Error ("A WebSocket service with the specified path isn't found.\npath: " + path); + return res; + } + + internal bool Remove (string path) + { WebSocketServiceHost host; lock (_sync) { + path = HttpUtility.UrlDecode (path).TrimEndSlash (); if (!_hosts.TryGetValue (path, out host)) { - _logger.Error ("A WebSocket service with the specified path not found.\npath: " + path); + _logger.Error ("A WebSocket service with the specified path isn't found.\npath: " + path); return false; } @@ -310,51 +326,36 @@ namespace WebSocketSharp.Server } } - internal void Stop (byte [] data, bool send) + internal void Stop (byte[] data, bool send) { lock (_sync) { _state = ServerState.ShuttingDown; var payload = new PayloadData (data); var args = new CloseEventArgs (payload); - var frameAsBytes = - send ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () : null; + var bytes = send + ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () + : null; foreach (var host in _hosts.Values) - host.Sessions.Stop (args, frameAsBytes); + host.Sessions.Stop (args, bytes); _hosts.Clear (); _state = ServerState.Stop; } } - internal bool TryGetServiceHostInternally (string path, out WebSocketServiceHost host) - { - path = HttpUtility.UrlDecode (path).TrimEndSlash (); - - bool result; - lock (_sync) { - result = _hosts.TryGetValue (path, out host); - } - - if (!result) - _logger.Error ("A WebSocket service with the specified path not found.\npath: " + path); - - return result; - } - #endregion #region Public Methods /// - /// Broadcasts a binary to every client in the WebSocket services - /// provided by the server. + /// Broadcasts a binary to every client in the WebSocket services. /// /// /// An array of that represents the binary data to broadcast. /// - public void Broadcast (byte [] data) + public void Broadcast (byte[] data) { var msg = _state.CheckIfStart () ?? data.CheckIfValidSendData (); if (msg != null) { @@ -369,8 +370,7 @@ namespace WebSocketSharp.Server } /// - /// Broadcasts a text to every client in the WebSocket services - /// provided by the server. + /// Broadcasts a text to every client in the WebSocket services. /// /// /// A that represents the text data to broadcast. @@ -391,8 +391,8 @@ namespace WebSocketSharp.Server } /// - /// Broadcasts a binary asynchronously to every client in the WebSocket - /// services provided by the server. + /// Broadcasts a binary asynchronously to every client + /// in the WebSocket services. /// /// /// This method doesn't wait for the broadcast to be complete. @@ -401,10 +401,10 @@ namespace WebSocketSharp.Server /// An array of that represents the binary data to broadcast. /// /// - /// A delegate that references the method(s) called when the broadcast is - /// complete. + /// A delegate that references the method(s) called when + /// the broadcast is complete. /// - public void BroadcastAsync (byte [] data, Action completed) + public void BroadcastAsync (byte[] data, Action completed) { var msg = _state.CheckIfStart () ?? data.CheckIfValidSendData (); if (msg != null) { @@ -419,8 +419,8 @@ namespace WebSocketSharp.Server } /// - /// Broadcasts a text asynchronously to every client in the WebSocket - /// services provided by the server. + /// Broadcasts a text asynchronously to every client + /// in the WebSocket services. /// /// /// This method doesn't wait for the broadcast to be complete. @@ -429,8 +429,8 @@ namespace WebSocketSharp.Server /// A that represents the text data to broadcast. /// /// - /// A delegate that references the method(s) called when the broadcast is - /// complete. + /// A delegate that references the method(s) called when + /// the broadcast is complete. /// public void BroadcastAsync (string data, Action completed) { @@ -448,8 +448,8 @@ namespace WebSocketSharp.Server } /// - /// Broadcasts a binary data from the specified asynchronously to every - /// client in the WebSocket services provided by the server. + /// Broadcasts a binary data from the specified asynchronously + /// to every client in the WebSocket services. /// /// /// This method doesn't wait for the broadcast to be complete. @@ -461,14 +461,14 @@ namespace WebSocketSharp.Server /// An that represents the number of bytes to broadcast. /// /// - /// A delegate that references the method(s) called when the broadcast is - /// complete. + /// A delegate that references the method(s) called when + /// the broadcast is complete. /// public void BroadcastAsync (Stream stream, int length, Action completed) { var msg = _state.CheckIfStart () ?? stream.CheckIfCanRead () ?? - (length < 1 ? "'length' must be greater than 0." : null); + (length < 1 ? "'length' is less than 1." : null); if (msg != null) { _logger.Error (msg); @@ -480,14 +480,14 @@ namespace WebSocketSharp.Server data => { var len = data.Length; if (len == 0) { - _logger.Error ("A data cannot be read from 'stream'."); + _logger.Error ("The 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}", + "The data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}", length, len)); @@ -500,13 +500,13 @@ namespace WebSocketSharp.Server } /// - /// Sends a Ping to every client in the WebSocket services provided by the server. + /// Sends a Ping to every client in the WebSocket services. /// /// - /// A Dictionary<string, Dictionary<string, bool>> that contains the collection of - /// pairs of service path and collection of pairs of session ID and value indicating whether - /// the manager received a Pong from every client in a time. If this method isn't available, - /// returns . + /// A Dictionary<string, Dictionary<string, bool>> that contains + /// a collection of pairs of a service path and a collection of pairs of a session ID + /// and a value indicating whether the manager received a Pong from each client in a time, + /// or if this method isn't available. /// public Dictionary> Broadping () { @@ -520,14 +520,15 @@ namespace WebSocketSharp.Server } /// - /// Sends a Ping with the specified to every client in the WebSocket - /// services provided by the server. + /// Sends a Ping with the specified to every client + /// in the WebSocket services. /// /// - /// A Dictionary<string, Dictionary<string, bool>> that contains the collection of - /// pairs of service path and collection of pairs of session ID and value indicating whether - /// the manager received a Pong from every client in a time. If this method isn't available or - /// is invalid, returns . + /// A Dictionary<string, Dictionary<string, bool>> that contains + /// a collection of pairs of a service path and a collection of pairs of a session ID + /// and a value indicating whether the manager received a Pong from each client in a time, + /// or if this method isn't available or + /// is invalid. /// /// /// A that represents the message to send. @@ -537,7 +538,7 @@ namespace WebSocketSharp.Server if (message == null || message.Length == 0) return Broadping (); - byte [] data = null; + byte[] data = null; var msg = _state.CheckIfStart () ?? (data = Encoding.UTF8.GetBytes (message)).CheckIfValidControlData ("message"); @@ -550,19 +551,18 @@ namespace WebSocketSharp.Server } /// - /// Tries to get the information in a WebSocket service with the specified - /// . + /// Tries to get the WebSocket service host with the specified . /// /// - /// true if the WebSocket service is successfully found; otherwise, false. + /// true if the service is successfully found; otherwise, false. /// /// - /// A that represents the absolute path to the WebSocket service to find. + /// A that represents the absolute path to the service to find. /// /// - /// When this method returns, a instance that - /// provides the access to the WebSocket service if it's successfully found; - /// otherwise, . This parameter is passed uninitialized. + /// When this method returns, a instance that provides + /// the access to the information for the service, or if it's not found. + /// This parameter is passed uninitialized. /// public bool TryGetServiceHost (string path, out WebSocketServiceHost host) { @@ -574,7 +574,7 @@ namespace WebSocketSharp.Server return false; } - return TryGetServiceHostInternally (path, out host); + return InternalTryGetServiceHost (path, out host); } #endregion