diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs
index 1eb0a1ff..6ddef92b 100644
--- a/websocket-sharp/Ext.cs
+++ b/websocket-sharp/Ext.cs
@@ -180,12 +180,10 @@ namespace WebSocketSharp
internal static byte [] Append (this ushort code, string reason)
{
- using (var buffer = new MemoryStream ())
- {
+ using (var buffer = new MemoryStream ()) {
var tmp = code.ToByteArrayInternally (ByteOrder.BIG);
buffer.Write (tmp, 0, 2);
- if (reason != null && reason.Length > 0)
- {
+ if (reason != null && reason.Length > 0) {
tmp = Encoding.UTF8.GetBytes (reason);
buffer.Write (tmp, 0, tmp.Length);
}
@@ -195,6 +193,13 @@ namespace WebSocketSharp
}
}
+ internal static string CheckIfCanClose (this WebSocketState state)
+ {
+ return state == WebSocketState.CLOSING || state == WebSocketState.CLOSED
+ ? "While closing the WebSocket connection, or already closed."
+ : null;
+ }
+
internal static string CheckIfCanRead (this Stream stream)
{
return stream == null
@@ -1149,8 +1154,8 @@ namespace WebSocketSharp
}
///
- /// Determines whether the specified is in the allowable range of
- /// the WebSocket close status code.
+ /// Determines whether the specified is in the allowable
+ /// range of the WebSocket close status code.
///
///
/// Not allowable ranges are the followings.
@@ -1162,14 +1167,15 @@ namespace WebSocketSharp
///
/// -
///
- /// Numbers which are greater than 4999 are out of the reserved close status code ranges.
+ /// Numbers which are greater than 4999 are out of the reserved close
+ /// status code ranges.
///
///
///
///
///
- /// true if is in the allowable range of the WebSocket close status code;
- /// otherwise, false.
+ /// true if is in the allowable range of the
+ /// WebSocket close status code; otherwise, false.
///
///
/// A to test.
diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs
index 430b9cf4..e22b11a2 100644
--- a/websocket-sharp/WebSocket.cs
+++ b/websocket-sharp/WebSocket.cs
@@ -557,34 +557,49 @@ namespace WebSocketSharp
private void close (CloseStatusCode code, string reason, bool wait)
{
- close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait);
+ close (
+ new PayloadData (((ushort) code).Append (reason)),
+ !code.IsReserved (),
+ wait);
}
private void close (PayloadData payload, bool send, bool wait)
{
- lock (_forClose)
- {
- if (_readyState == WebSocketState.CLOSING || _readyState == WebSocketState.CLOSED)
+ lock (_forClose) {
+ var msg = _readyState.CheckIfCanClose ();
+ if (msg != null) {
+ _logger.Info (String.Format ("{0}\nstate: {1}", msg, _readyState));
+
return;
+ }
_readyState = WebSocketState.CLOSING;
}
_logger.Trace ("Start closing handshake.");
- var args = new CloseEventArgs (payload);
- args.WasClean = _client
- ? close (
- send ? WsFrame.CreateCloseFrame (Mask.MASK, payload).ToByteArray () : null,
- wait ? 5000 : 0,
- closeClientResources)
- : close (
- send ? WsFrame.CreateCloseFrame (Mask.UNMASK, payload).ToByteArray () : null,
- wait ? 1000 : 0,
- closeServerResources);
+ try {
+ var args = new CloseEventArgs (payload);
+ args.WasClean =
+ _client
+ ? close (
+ send ? WsFrame.CreateCloseFrame (Mask.MASK, payload).ToByteArray ()
+ : null,
+ wait ? 5000 : 0,
+ closeClientResources)
+ : close (
+ send ? WsFrame.CreateCloseFrame (Mask.UNMASK, payload).ToByteArray ()
+ : null,
+ wait ? 1000 : 0,
+ closeServerResources);
- _readyState = WebSocketState.CLOSED;
- OnClose.Emit (this, args);
+ _readyState = WebSocketState.CLOSED;
+ OnClose.Emit (this, args);
+ }
+ catch (Exception ex) {
+ _logger.Fatal (ex.ToString ());
+ error ("An exception has occurred while closing.");
+ }
_logger.Trace ("End closing handshake.");
}
@@ -592,11 +607,17 @@ namespace WebSocketSharp
private bool close (byte [] frameAsBytes, int timeOut, Func release)
{
var sent = frameAsBytes != null && _stream.Write (frameAsBytes);
- var received = timeOut == 0 || (sent && _exitReceiving.WaitOne (timeOut));
+ var received = timeOut == 0 ||
+ (sent && _exitReceiving != null && _exitReceiving.WaitOne (timeOut));
var released = release ();
var result = sent && received && released;
- _logger.Debug (String.Format (
- "Was clean?: {0}\nsent: {1} received: {2} released: {3}", result, sent, received, released));
+ _logger.Debug (
+ String.Format (
+ "Was clean?: {0}\nsent: {1} received: {2} released: {3}",
+ result,
+ sent,
+ received,
+ released));
return result;
}
@@ -605,14 +626,12 @@ namespace WebSocketSharp
private bool closeClientResources ()
{
try {
- if (_stream != null)
- {
+ if (_stream != null) {
_stream.Dispose ();
_stream = null;
}
- if (_tcpClient != null)
- {
+ if (_tcpClient != null) {
_tcpClient.Close ();
_tcpClient = null;
}
@@ -621,10 +640,10 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occurred.");
-
- return false;
+ error ("An exception has occurred while releasing resources.");
}
+
+ return false;
}
// As server
@@ -641,10 +660,10 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occurred.");
-
- return false;
+ error ("An exception has occurred while releasing resources.");
}
+
+ return false;
}
private bool concatenateFragmentsInto (Stream dest)
@@ -886,21 +905,18 @@ namespace WebSocketSharp
{
var code = CloseStatusCode.ABNORMAL;
var msg = reason;
- if (exception.GetType () == typeof (WebSocketException))
- {
+ if (exception is WebSocketException) {
var wsex = (WebSocketException) exception;
code = wsex.Code;
reason = wsex.Message;
}
if (code == CloseStatusCode.ABNORMAL ||
- code == CloseStatusCode.TLS_HANDSHAKE_FAILURE)
- {
+ code == CloseStatusCode.TLS_HANDSHAKE_FAILURE) {
_logger.Fatal (exception.ToString ());
reason = msg;
}
- else
- {
+ else {
_logger.Error (reason);
msg = null;
}
@@ -1365,21 +1381,28 @@ namespace WebSocketSharp
}
// As server
- internal void Close (CloseEventArgs args, byte [] frameAsBytes, int waitTimeOut)
+ internal void Close (
+ CloseEventArgs args, byte [] frameAsBytes, int waitTimeOut)
{
- lock (_forClose)
- {
- if (_readyState == WebSocketState.CLOSING || _readyState == WebSocketState.CLOSED)
+ lock (_forClose) {
+ var msg = _readyState.CheckIfCanClose ();
+ if (msg != null) {
+ _logger.Info (String.Format ("{0}\nstate: {1}", msg, _readyState));
+
return;
+ }
_readyState = WebSocketState.CLOSING;
}
- args.WasClean = close (frameAsBytes, waitTimeOut, closeServerResources);
-
- _readyState = WebSocketState.CLOSED;
-
- OnClose.Emit (this, args);
+ try {
+ args.WasClean = close (frameAsBytes, waitTimeOut, closeServerResources);
+ _readyState = WebSocketState.CLOSED;
+ OnClose.Emit (this, args);
+ }
+ catch (Exception ex) {
+ _logger.Fatal (ex.ToString ());
+ }
}
// As server
@@ -1480,11 +1503,20 @@ namespace WebSocketSharp
#region Public Methods
///
- /// Closes the WebSocket connection and releases all associated resources.
+ /// Closes the WebSocket connection, and releases all associated resources.
///
public void Close ()
{
- close (new PayloadData (), _readyState == WebSocketState.OPEN, true);
+ var msg = _readyState.CheckIfCanClose ();
+ if (msg != null) {
+ _logger.Error (String.Format ("{0}\nstate: {1}", msg, _readyState));
+ error (msg);
+
+ return;
+ }
+
+ var send = _readyState == WebSocketState.OPEN;
+ close (new PayloadData (), send, send);
}
///
@@ -1492,25 +1524,15 @@ namespace WebSocketSharp
/// and releases all associated resources.
///
///
- /// This method emits a event if is not
- /// in the allowable range of the WebSocket close status code.
+ /// This method emits a event if
+ /// isn't in the allowable range of the WebSocket close status code.
///
///
/// A that indicates the status code for closure.
///
public void Close (ushort code)
{
- var msg = code.CheckIfValidCloseStatusCode ();
- if (msg != null)
- {
- _logger.Error (String.Format ("{0}\ncode: {1}", msg, code));
- error (msg);
-
- return;
- }
-
- var send = _readyState == WebSocketState.OPEN && !code.IsReserved ();
- close (new PayloadData (code.ToByteArrayInternally (ByteOrder.BIG)), send, true);
+ Close (code, null);
}
///
@@ -1518,75 +1540,81 @@ namespace WebSocketSharp
/// and releases all associated resources.
///
///
- /// One of the values that indicate the status codes for closure.
+ /// One of the values that indicate the status
+ /// codes for closure.
///
public void Close (CloseStatusCode code)
{
- var send = _readyState == WebSocketState.OPEN && !code.IsReserved ();
- close (new PayloadData (((ushort) code).ToByteArrayInternally (ByteOrder.BIG)), send, true);
+ Close (code, null);
}
///
- /// Closes the WebSocket connection with the specified and ,
- /// and releases all associated resources.
+ /// Closes the WebSocket connection with the specified
+ /// and , and releases all associated resources.
///
///
- /// This method emits a event if is not
- /// in the allowable range of the WebSocket close status code
- /// or the length of is greater than 123 bytes.
+ /// This method emits a event if
+ /// isn't in the allowable range of the WebSocket close status code or the
+ /// length of is greater than 123 bytes.
///
///
/// A that indicates the status code for closure.
///
///
- /// A that contains the reason for closure.
+ /// A that represents the reason for closure.
///
public void Close (ushort code, string reason)
{
byte [] data = null;
- var msg = code.CheckIfValidCloseStatusCode () ??
+ var msg = _readyState.CheckIfCanClose () ??
+ code.CheckIfValidCloseStatusCode () ??
(data = code.Append (reason)).CheckIfValidCloseData ();
- if (msg != null)
- {
- _logger.Error (String.Format ("{0}\ncode: {1}\nreason: {2}", msg, code, reason));
+ if (msg != null) {
+ _logger.Error (
+ String.Format (
+ "{0}\nstate: {1} code: {2} reason: {3}", msg, _readyState, code, reason));
error (msg);
return;
}
var send = _readyState == WebSocketState.OPEN && !code.IsReserved ();
- close (new PayloadData (data), send, true);
+ close (new PayloadData (data), send, send);
}
///
- /// Closes the WebSocket connection with the specified and
- /// , and releases all associated resources.
+ /// Closes the WebSocket connection with the specified
+ /// and , and releases all associated resources.
///
///
- /// This method emits a event if the length of
- /// is greater than 123 bytes.
+ /// This method emits a event if the length of
+ /// is greater than 123 bytes.
///
///
- /// One of the values that indicate the status codes for closure.
+ /// One of the values that indicate the status
+ /// codes for closure.
///
///
- /// A that contains the reason for closure.
+ /// A that represents the reason for closure.
///
public void Close (CloseStatusCode code, string reason)
{
- var data = ((ushort) code).Append (reason);
- var msg = data.CheckIfValidCloseData ();
- if (msg != null)
- {
- _logger.Error (String.Format ("{0}\nreason: {1}", msg, reason));
+ byte [] data = null;
+ var msg = _readyState.CheckIfCanClose () ??
+ (data = ((ushort) code).Append (reason)).CheckIfValidCloseData ();
+
+ if (msg != null) {
+ _logger.Error (
+ String.Format (
+ "{0}\nstate: {1} reason: {2}", msg, _readyState, reason));
error (msg);
return;
}
var send = _readyState == WebSocketState.OPEN && !code.IsReserved ();
- close (new PayloadData (data), send, true);
+ close (new PayloadData (data), send, send);
}
///
@@ -1642,14 +1670,15 @@ namespace WebSocketSharp
}
///
- /// Closes the WebSocket connection and releases all associated resources.
+ /// Closes the WebSocket connection, and releases all associated resources.
///
///
- /// This method closes the WebSocket connection with the .
+ /// This method closes the WebSocket connection with the
+ /// .
///
public void Dispose ()
{
- Close (CloseStatusCode.AWAY);
+ Close (CloseStatusCode.AWAY, null);
}
///