diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index fc8eabb9..34a87f29 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -167,7 +167,7 @@ namespace WebSocketSharp internal static string CheckIfValidCloseData (this byte [] data) { return data.Length > 125 - ? "The payload length of a Close frame must be 125 bytes or less." + ? "'reason' length must be less." : null; } @@ -178,10 +178,10 @@ namespace WebSocketSharp : null; } - internal static string CheckIfValidPingMessage (this string message) + internal static string CheckIfValidPingData (this byte [] data) { - return message != null && message.Length > 0 && Encoding.UTF8.GetBytes (message).Length > 125 - ? "The payload length of a Ping frame must be 125 bytes or less." + return data.Length > 125 + ? "'message' length must be less." : null; } diff --git a/websocket-sharp/Server/IWebSocketServiceHost.cs b/websocket-sharp/Server/IWebSocketServiceHost.cs index 85b8a206..3b5f68ab 100644 --- a/websocket-sharp/Server/IWebSocketServiceHost.cs +++ b/websocket-sharp/Server/IWebSocketServiceHost.cs @@ -89,17 +89,16 @@ namespace WebSocketSharp.Server Dictionary Broadping (); /// - /// Sends Pings with the specified to all clients of - /// the WebSocket service host. + /// Sends Pings with the specified to all clients of the WebSocket service host. /// /// /// A Dictionary<string, bool> that contains the collection of pairs of session ID and value /// indicating whether the WebSocket service host received a Pong from each client in a time. /// - /// - /// A that contains a message to send. + /// + /// An array of that contains a message data to send. /// - Dictionary Broadping (string message); + Dictionary Broadping (byte [] data); /// /// Close the WebSocket session with the specified . diff --git a/websocket-sharp/Server/WebSocketService.cs b/websocket-sharp/Server/WebSocketService.cs index 3b0ea584..e710723c 100644 --- a/websocket-sharp/Server/WebSocketService.cs +++ b/websocket-sharp/Server/WebSocketService.cs @@ -201,6 +201,11 @@ namespace WebSocketSharp.Server IsBound = true; } + internal bool Ping (byte [] data) + { + return _websocket.Ping (data); + } + internal void SendAsync (byte [] data, Action completed) { _websocket.SendAsync (data, completed); @@ -279,7 +284,7 @@ namespace WebSocketSharp.Server protected virtual Dictionary Broadping () { return IsBound - ? _sessions.Broadping () + ? _sessions.Broadping (new byte [] {}) : null; } @@ -299,7 +304,11 @@ namespace WebSocketSharp.Server if (!IsBound) return null; - var msg = message.CheckIfValidPingMessage (); + if (message == null || message.Length == 0) + return _sessions.Broadping (new byte [] {}); + + var data = Encoding.UTF8.GetBytes (message); + var msg = data.CheckIfValidPingData (); if (msg != null) { Log.Error (msg); @@ -308,7 +317,7 @@ namespace WebSocketSharp.Server return null; } - return _sessions.Broadping (message); + return _sessions.Broadping (data); } /// diff --git a/websocket-sharp/Server/WebSocketServiceHost.cs b/websocket-sharp/Server/WebSocketServiceHost.cs index b4472494..6fc7c843 100644 --- a/websocket-sharp/Server/WebSocketServiceHost.cs +++ b/websocket-sharp/Server/WebSocketServiceHost.cs @@ -360,7 +360,7 @@ namespace WebSocketSharp.Server /// public Dictionary Broadping () { - return _sessions.Broadping (); + return _sessions.Broadping (new byte [] {}); } /// @@ -375,14 +375,18 @@ namespace WebSocketSharp.Server /// public Dictionary Broadping (string message) { - var msg = message.CheckIfValidPingMessage (); + if (message == null || message.Length == 0) + return _sessions.Broadping (new byte [] {}); + + var data = Encoding.UTF8.GetBytes (message); + var msg = data.CheckIfValidPingData (); if (msg != null) { Log.Error (msg); return null; } - return _sessions.Broadping (message); + return _sessions.Broadping (data); } /// @@ -635,133 +639,18 @@ namespace WebSocketSharp.Server } /// - /// Sends Pings with the specified to all clients. + /// Sends Pings with the specified to all clients. /// /// /// A Dictionary<string, bool> that contains the collection of pairs of session ID and value - /// indicating whether the service host received the Pong from each client in a time. - /// - /// - /// A that contains a message to send. - /// - Dictionary IWebSocketServiceHost.Broadping (string message) - { - return _sessions.Broadping (message); - } - - /// - /// Close the WebSocket session with the specified . - /// - /// - /// A that contains a session ID to find. - /// - void IWebSocketServiceHost.CloseSession (string id) - { - _sessions.StopServiceInstance (id); - } - - /// - /// Close the WebSocket session with the specified , - /// and . - /// - /// - /// A that contains a status code indicating the reason for closure. - /// - /// - /// A that contains the reason for closure. - /// - /// - /// A that contains a session ID to find. - /// - void IWebSocketServiceHost.CloseSession (ushort code, string reason, string id) - { - _sessions.StopServiceInstance (code, reason, id); - } - - /// - /// Close the WebSocket session with the specified , - /// and . - /// - /// - /// A that contains a status code indicating the reason for closure. - /// - /// - /// A that contains the reason for closure. - /// - /// - /// A that contains a session ID to find. - /// - void IWebSocketServiceHost.CloseSession (CloseStatusCode code, string reason, string id) - { - _sessions.StopServiceInstance (code, reason, id); - } - - /// - /// Sends a Ping to the client associated with the specified . - /// - /// - /// true if the WebSocket service host receives a Pong from the client in a time; - /// otherwise, false. - /// - /// - /// A that contains a session ID that represents the destination for the Ping. - /// - bool IWebSocketServiceHost.PingTo (string id) - { - return _sessions.PingTo (id); - } - - /// - /// Sends a Ping with the specified to the client associated with - /// the specified . - /// - /// - /// true if the WebSocket service host receives a Pong from the client in a time; - /// otherwise, false. - /// - /// - /// A that contains a message to send. - /// - /// - /// A that contains a session ID that represents the destination for the Ping. - /// - bool IWebSocketServiceHost.PingTo (string message, string id) - { - return _sessions.PingTo (message, id); - } - - /// - /// Sends a binary data to the client associated with the specified . - /// - /// - /// true if is successfully sent; otherwise, false. - /// - /// - /// An array of that contains a binary data to send. - /// - /// - /// A that contains a session ID that represents the destination for the data. - /// - bool IWebSocketServiceHost.SendTo (byte [] data, string id) - { - return _sessions.SendTo (data, id); - } - - /// - /// Sends a text data to the client associated with the specified . - /// - /// - /// true if is successfully sent; otherwise, false. + /// indicating whether the WebSocket service host received a Pong from each client in a time. /// /// - /// A that contains a text data to send. + /// An array of that contains a message data to send. /// - /// - /// A that contains a session ID that represents the destination for the data. - /// - bool IWebSocketServiceHost.SendTo (string data, string id) + Dictionary IWebSocketServiceHost.Broadping (byte [] data) { - return _sessions.SendTo (data, id); + return _sessions.Broadping (data); } /// diff --git a/websocket-sharp/Server/WebSocketServiceHostManager.cs b/websocket-sharp/Server/WebSocketServiceHostManager.cs index 4a622bb5..79fefc6c 100644 --- a/websocket-sharp/Server/WebSocketServiceHostManager.cs +++ b/websocket-sharp/Server/WebSocketServiceHostManager.cs @@ -176,6 +176,15 @@ namespace WebSocketSharp.Server } } + internal Dictionary> Broadping (byte [] data) + { + var result = new Dictionary> (); + foreach (var service in copy ()) + result.Add (service.Key, service.Value.Broadping (data)); + + return result; + } + internal bool Remove (string servicePath) { servicePath = HttpUtility.UrlDecode (servicePath).TrimEndSlash (); @@ -348,11 +357,7 @@ namespace WebSocketSharp.Server /// public Dictionary> Broadping () { - var result = new Dictionary> (); - foreach (var service in copy ()) - result.Add (service.Key, service.Value.Broadping ()); - - return result; + return Broadping (new byte [] {}); } /// @@ -369,18 +374,18 @@ namespace WebSocketSharp.Server /// public Dictionary> Broadping (string message) { - var msg = message.CheckIfValidPingMessage (); + if (message == null || message.Length == 0) + return Broadping (new byte [] {}); + + var data = Encoding.UTF8.GetBytes (message); + var msg = data.CheckIfValidPingData (); if (msg != null) { _logger.Error (msg); return null; } - var result = new Dictionary> (); - foreach (var service in copy ()) - result.Add (service.Key, service.Value.Broadping (message)); - - return result; + return Broadping (data); } /// @@ -410,7 +415,7 @@ namespace WebSocketSharp.Server return null; } - return host.Broadping (); + return host.Broadping (new byte [] {}); } /// @@ -430,7 +435,11 @@ namespace WebSocketSharp.Server /// public Dictionary BroadpingTo (string message, string servicePath) { - var msg = message.CheckIfValidPingMessage () ?? servicePath.CheckIfValidServicePath (); + if (message == null || message.Length == 0) + return BroadpingTo (servicePath); + + var data = Encoding.UTF8.GetBytes (message); + var msg = data.CheckIfValidPingData () ?? servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); @@ -444,7 +453,7 @@ namespace WebSocketSharp.Server return null; } - return host.Broadping (message); + return host.Broadping (data); } /// @@ -459,7 +468,7 @@ namespace WebSocketSharp.Server /// public void CloseSession (string id, string servicePath) { - var msg = id.CheckIfValidSessionID () ?? servicePath.CheckIfValidServicePath (); + var msg = servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); @@ -494,7 +503,7 @@ namespace WebSocketSharp.Server /// public void CloseSession (ushort code, string reason, string id, string servicePath) { - var msg = id.CheckIfValidSessionID () ?? servicePath.CheckIfValidServicePath (); + var msg = servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); @@ -529,7 +538,7 @@ namespace WebSocketSharp.Server /// public void CloseSession (CloseStatusCode code, string reason, string id, string servicePath) { - var msg = id.CheckIfValidSessionID () ?? servicePath.CheckIfValidServicePath (); + var msg = servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); @@ -591,7 +600,7 @@ namespace WebSocketSharp.Server /// public bool PingTo (string id, string servicePath) { - var msg = id.CheckIfValidSessionID () ?? servicePath.CheckIfValidServicePath (); + var msg = servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); @@ -627,9 +636,7 @@ namespace WebSocketSharp.Server /// public bool PingTo (string message, string id, string servicePath) { - var msg = (message.CheckIfValidPingMessage () ?? id.CheckIfValidSessionID ()) ?? - servicePath.CheckIfValidServicePath (); - + var msg = servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); @@ -664,9 +671,7 @@ namespace WebSocketSharp.Server /// public bool SendTo (byte [] data, string id, string servicePath) { - var msg = (data.CheckIfValidSendData () ?? id.CheckIfValidSessionID ()) ?? - servicePath.CheckIfValidServicePath (); - + var msg = servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); @@ -701,9 +706,7 @@ namespace WebSocketSharp.Server /// public bool SendTo (string data, string id, string servicePath) { - var msg = (data.CheckIfValidSendData () ?? id.CheckIfValidSessionID ()) ?? - servicePath.CheckIfValidServicePath (); - + var msg = servicePath.CheckIfValidServicePath (); if (msg != null) { _logger.Error (msg); diff --git a/websocket-sharp/Server/WebSocketServiceManager.cs b/websocket-sharp/Server/WebSocketServiceManager.cs index 4e17fe96..ce39722d 100644 --- a/websocket-sharp/Server/WebSocketServiceManager.cs +++ b/websocket-sharp/Server/WebSocketServiceManager.cs @@ -84,7 +84,7 @@ namespace WebSocketSharp.Server /// public IEnumerable ActiveIDs { get { - return from result in Broadping () + return from result in Broadping (new byte [] {}) where result.Value select result.Key; } @@ -134,7 +134,7 @@ namespace WebSocketSharp.Server /// public IEnumerable InactiveIDs { get { - return from result in Broadping () + return from result in Broadping (new byte [] {}) where !result.Value select result.Key; } @@ -345,38 +345,21 @@ namespace WebSocketSharp.Server } /// - /// Sends Pings to the clients of every instances managed by - /// the . - /// - /// - /// A Dictionary<string, bool> that contains the collection of pairs of ID and value indicating - /// whether each instance received a Pong from the client in a time. - /// - internal Dictionary Broadping () - { - var result = new Dictionary (); - foreach (var session in copy ()) - result.Add (session.Key, session.Value.Ping ()); - - return result; - } - - /// - /// Sends Pings with the specified to the clients of every + /// Sends Pings with the specified to the clients of every /// instances managed by the . /// /// /// A Dictionary<string, bool> that contains the collection of pairs of ID and value indicating /// whether each instance received a Pong from the client in a time. /// - /// - /// A that contains a message to send. + /// + /// An array of that contains a message data to send. /// - internal Dictionary Broadping (string message) + internal Dictionary Broadping (byte [] data) { var result = new Dictionary (); foreach (var session in copy ()) - result.Add (session.Key, session.Value.Ping (message)); + result.Add (session.Key, session.Value.Ping (data)); return result; } diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index e4b843f0..1a071f30 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -320,7 +320,7 @@ namespace WebSocketSharp public bool IsAlive { get { return _readyState == WebSocketState.OPEN - ? ping (new byte [] {}) + ? Ping (new byte [] {}) : false; } } @@ -531,32 +531,21 @@ namespace WebSocketSharp return send (createHandshakeResponse ()); } - private void close (CloseEventArgs eventArgs) - { - if (!Thread.CurrentThread.IsBackground && _exitReceiving != null) - if (!_exitReceiving.WaitOne (5 * 1000)) - eventArgs.WasClean = false; - - if (!closeResources ()) - eventArgs.WasClean = false; - - _readyState = WebSocketState.CLOSED; - OnClose.Emit (this, eventArgs); - } - private void close (PayloadData data) { _logger.Debug ("Is this thread background?: " + Thread.CurrentThread.IsBackground); + CloseEventArgs args = null; lock (_forClose) { if (_readyState == WebSocketState.CLOSING || _readyState == WebSocketState.CLOSED) return; - var state = _readyState; + var current = _readyState; _readyState = WebSocketState.CLOSING; + args = new CloseEventArgs (data); - if (state == WebSocketState.CONNECTING) + if (current == WebSocketState.CONNECTING) { if (!_client) { @@ -571,7 +560,17 @@ namespace WebSocketSharp } } - close (args); + if (!Thread.CurrentThread.IsBackground && + _exitReceiving != null && + !_exitReceiving.WaitOne (5 * 1000)) + args.WasClean = false; + + if (!closeResources ()) + args.WasClean = false; + + _readyState = WebSocketState.CLOSED; + OnClose.Emit (this, args); + _logger.Trace ("Exit close method."); } @@ -579,7 +578,12 @@ namespace WebSocketSharp private void close (HttpStatusCode code) { send (createHandshakeResponse (code)); - closeResources (); + try { + closeServerResources (); + } + catch { + } + _readyState = WebSocketState.CLOSED; } @@ -635,12 +639,11 @@ namespace WebSocketSharp // As server private void closeServerResources () { - if (_context != null && _closeContext != null) - { + if (_closeContext != null) _closeContext (); - _stream = null; - _context = null; - } + + _stream = null; + _context = null; } private bool concatenateFragments (Stream dest) @@ -864,16 +867,6 @@ namespace WebSocketSharp OnOpen.Emit (this, EventArgs.Empty); } - private bool ping (byte [] data) - { - var frame = createControlFrame (Opcode.PING, new PayloadData (data), _client); - var timeOut = _client ? 5000 : 1000; - - return send (frame) - ? _receivePong.WaitOne (timeOut) - : false; - } - private void pong (PayloadData data) { var frame = createControlFrame (Opcode.PONG, data, _client); @@ -1327,6 +1320,16 @@ namespace WebSocketSharp close (code); } + internal bool Ping (byte [] data) + { + var frame = createControlFrame (Opcode.PING, new PayloadData (data), _client); + var timeOut = _client ? 5000 : 1000; + + return send (frame) + ? _receivePong.WaitOne (timeOut) + : false; + } + #endregion #region Public Methods @@ -1352,7 +1355,16 @@ namespace WebSocketSharp /// public void Close (ushort code) { - Close (code, ""); + var msg = code.CheckIfValidCloseStatusCode (); + if (msg != null) + { + _logger.Error (String.Format ("{0}\ncode: {1}", msg, code)); + error (msg); + + return; + } + + close (new PayloadData (code.ToByteArray (ByteOrder.BIG))); } /// @@ -1451,38 +1463,40 @@ namespace WebSocketSharp /// Sends a Ping using the WebSocket connection. /// /// - /// true if a instance receives a Pong in a time; otherwise, false. + /// true if the instance receives a Pong in a time; + /// otherwise, false. /// public bool Ping () { - return ping (new byte [] {}); + return Ping (new byte [] {}); } /// /// Sends a Ping with the specified using the WebSocket connection. /// /// - /// A that contains a message to send with a Ping. + /// A that contains a message to send. /// /// - /// true if a instance receives a Pong in a time; otherwise, false. + /// true if the instance receives a Pong in a time; + /// otherwise, false. /// public bool Ping (string message) { - if (message.IsNullOrEmpty ()) - return ping (new byte [] {}); + if (message == null || message.Length == 0) + return Ping (new byte [] {}); var data = Encoding.UTF8.GetBytes (message); - if (data.Length > 125) + var msg = data.CheckIfValidPingData (); + if (msg != null) { - var msg = "The payload length of a Ping frame must be 125 bytes or less."; _logger.Error (msg); error (msg); return false; } - return ping (data); + return Ping (data); } ///