Refactored CloseEventArgs.cs

This commit is contained in:
sta 2014-09-21 17:33:07 +09:00
parent 25c103d51e
commit 56acccdda1
6 changed files with 178 additions and 98 deletions

View File

@ -48,27 +48,78 @@ namespace WebSocketSharp
{ {
#region Private Fields #region Private Fields
private bool _clean; private bool _clean;
private ushort _code; private ushort _code;
private string _reason; private PayloadData _payloadData;
private byte[] _rawData;
private string _reason;
#endregion #endregion
#region Internal Constructors #region Internal Constructors
internal CloseEventArgs (PayloadData payload) internal CloseEventArgs ()
{ {
var data = payload.ApplicationData; _code = (ushort) CloseStatusCode.NoStatusCode;
var len = data.Length; _reason = String.Empty;
_rawData = new byte[0];
}
internal CloseEventArgs (ushort code)
{
_code = code;
_reason = String.Empty;
_rawData = code.InternalToByteArray (ByteOrder.Big);
}
internal CloseEventArgs (CloseStatusCode code)
: this ((ushort) code)
{
}
internal CloseEventArgs (PayloadData payloadData)
{
_payloadData = payloadData;
_rawData = payloadData.ApplicationData;
var len = _rawData.Length;
_code = len > 1 _code = len > 1
? data.SubArray (0, 2).ToUInt16 (ByteOrder.Big) ? _rawData.SubArray (0, 2).ToUInt16 (ByteOrder.Big)
: (ushort) CloseStatusCode.NoStatusCode; : (ushort) CloseStatusCode.NoStatusCode;
_reason = len > 2 _reason = len > 2
? Encoding.UTF8.GetString (data.SubArray (2, len - 2)) ? Encoding.UTF8.GetString (_rawData.SubArray (2, len - 2))
: String.Empty; : String.Empty;
} }
internal CloseEventArgs (ushort code, string reason)
{
_code = code;
_reason = reason ?? String.Empty;
_rawData = code.Append (reason);
}
internal CloseEventArgs (CloseStatusCode code, string reason)
: this ((ushort) code, reason)
{
}
#endregion
#region Internal Properties
internal PayloadData PayloadData {
get {
return _payloadData ?? (_payloadData = new PayloadData (_rawData));
}
}
internal byte[] RawData {
get {
return _rawData;
}
}
#endregion #endregion
#region Public Properties #region Public Properties

View File

@ -424,10 +424,9 @@ namespace WebSocketSharp.Server
_state = ServerState.ShuttingDown; _state = ServerState.ShuttingDown;
} }
_services.Stop ( _services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true);
((ushort) CloseStatusCode.ServerError).InternalToByteArray (ByteOrder.Big), true);
_listener.Abort (); _listener.Abort ();
_state = ServerState.Stop; _state = ServerState.Stop;
} }
@ -611,7 +610,7 @@ namespace WebSocketSharp.Server
(initializer == null ? "'initializer' is null." : null); (initializer == null ? "'initializer' is null." : null);
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); _logger.Error (msg);
return; return;
} }
@ -656,7 +655,7 @@ namespace WebSocketSharp.Server
{ {
var msg = path.CheckIfValidServicePath (); var msg = path.CheckIfValidServicePath ();
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); _logger.Error (msg);
return false; return false;
} }
@ -671,7 +670,7 @@ namespace WebSocketSharp.Server
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStartable () ?? checkIfCertificateExists (); var msg = _state.CheckIfStartable () ?? checkIfCertificateExists ();
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nstate: {1}\nsecure: {2}", msg, _state, _secure)); _logger.Error (msg);
return; return;
} }
@ -690,14 +689,14 @@ namespace WebSocketSharp.Server
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStart (); var msg = _state.CheckIfStart ();
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nstate: {1}", msg, _state)); _logger.Error (msg);
return; return;
} }
_state = ServerState.ShuttingDown; _state = ServerState.ShuttingDown;
} }
_services.Stop (new byte[0], true); _services.Stop (new CloseEventArgs (), true);
stopReceiving (5000); stopReceiving (5000);
_state = ServerState.Stop; _state = ServerState.Stop;
@ -715,23 +714,22 @@ namespace WebSocketSharp.Server
/// </param> /// </param>
public void Stop (ushort code, string reason) public void Stop (ushort code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStart () ?? var msg =
code.CheckIfValidCloseStatusCode () ?? _state.CheckIfStart () ??
(data = code.Append (reason)).CheckIfValidControlData ("reason"); code.CheckIfValidCloseStatusCode () ??
(e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error ( _logger.Error (msg);
String.Format ("{0}\nstate: {1}\ncode: {2}\nreason: {3}", msg, _state, code, reason));
return; return;
} }
_state = ServerState.ShuttingDown; _state = ServerState.ShuttingDown;
} }
_services.Stop (data, !code.IsReserved ()); _services.Stop (e, !code.IsReserved ());
stopReceiving (5000); stopReceiving (5000);
_state = ServerState.Stop; _state = ServerState.Stop;
@ -750,20 +748,21 @@ namespace WebSocketSharp.Server
/// </param> /// </param>
public void Stop (CloseStatusCode code, string reason) public void Stop (CloseStatusCode code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStart () ?? var msg =
(data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); _state.CheckIfStart () ??
(e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nstate: {1}\nreason: {2}", msg, _state, reason)); _logger.Error (msg);
return; return;
} }
_state = ServerState.ShuttingDown; _state = ServerState.ShuttingDown;
} }
_services.Stop (data, !code.IsReserved ()); _services.Stop (e, !code.IsReserved ());
stopReceiving (5000); stopReceiving (5000);
_state = ServerState.Stop; _state = ServerState.Stop;

View File

@ -507,8 +507,7 @@ namespace WebSocketSharp.Server
} }
_listener.Stop (); _listener.Stop ();
_services.Stop ( _services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true);
((ushort) CloseStatusCode.ServerError).InternalToByteArray (ByteOrder.Big), true);
_state = ServerState.Stop; _state = ServerState.Stop;
} }
@ -728,7 +727,7 @@ namespace WebSocketSharp.Server
(initializer == null ? "'initializer' is null." : null); (initializer == null ? "'initializer' is null." : null);
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); _logger.Error (msg);
return; return;
} }
@ -752,7 +751,7 @@ namespace WebSocketSharp.Server
{ {
var msg = path.CheckIfValidServicePath (); var msg = path.CheckIfValidServicePath ();
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nservice path: {1}", msg, path)); _logger.Error (msg);
return false; return false;
} }
@ -767,7 +766,7 @@ namespace WebSocketSharp.Server
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStartable () ?? checkIfCertificateExists (); var msg = _state.CheckIfStartable () ?? checkIfCertificateExists ();
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nstate: {1}\nsecure: {2}", msg, _state, _secure)); _logger.Error (msg);
return; return;
} }
@ -786,7 +785,7 @@ namespace WebSocketSharp.Server
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStart (); var msg = _state.CheckIfStart ();
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nstate: {1}", msg, _state)); _logger.Error (msg);
return; return;
} }
@ -794,7 +793,7 @@ namespace WebSocketSharp.Server
} }
stopReceiving (5000); stopReceiving (5000);
_services.Stop (new byte[0], true); _services.Stop (new CloseEventArgs (), true);
_state = ServerState.Stop; _state = ServerState.Stop;
} }
@ -811,16 +810,15 @@ namespace WebSocketSharp.Server
/// </param> /// </param>
public void Stop (ushort code, string reason) public void Stop (ushort code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStart () ?? var msg =
code.CheckIfValidCloseStatusCode () ?? _state.CheckIfStart () ??
(data = code.Append (reason)).CheckIfValidControlData ("reason"); code.CheckIfValidCloseStatusCode () ??
(e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error ( _logger.Error (msg);
String.Format ("{0}\nstate: {1}\ncode: {2}\nreason: {3}", msg, _state, code, reason));
return; return;
} }
@ -828,7 +826,7 @@ namespace WebSocketSharp.Server
} }
stopReceiving (5000); stopReceiving (5000);
_services.Stop (data, !code.IsReserved ()); _services.Stop (e, !code.IsReserved ());
_state = ServerState.Stop; _state = ServerState.Stop;
} }
@ -846,13 +844,14 @@ namespace WebSocketSharp.Server
/// </param> /// </param>
public void Stop (CloseStatusCode code, string reason) public void Stop (CloseStatusCode code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
lock (_sync) { lock (_sync) {
var msg = _state.CheckIfStart () ?? var msg =
(data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); _state.CheckIfStart () ??
(e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\nstate: {1}\nreason: {2}", msg, _state, reason)); _logger.Error (msg);
return; return;
} }
@ -860,7 +859,7 @@ namespace WebSocketSharp.Server
} }
stopReceiving (5000); stopReceiving (5000);
_services.Stop (data, !code.IsReserved ()); _services.Stop (e, !code.IsReserved ());
_state = ServerState.Stop; _state = ServerState.Stop;
} }

View File

@ -121,10 +121,9 @@ namespace WebSocketSharp.Server
internal void Stop (ushort code, string reason) internal void Stop (ushort code, string reason)
{ {
var payload = new PayloadData (code.Append (reason)); var e = new CloseEventArgs (code, reason);
var e = new CloseEventArgs (payload);
var bytes = !code.IsReserved () var bytes = !code.IsReserved ()
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null; : null;
Sessions.Stop (e, bytes); Sessions.Stop (e, bytes);

View File

@ -325,15 +325,12 @@ namespace WebSocketSharp.Server
} }
} }
internal void Stop (byte[] data, bool send) internal void Stop (CloseEventArgs e, bool send)
{ {
lock (_sync) { lock (_sync) {
_state = ServerState.ShuttingDown; _state = ServerState.ShuttingDown;
var payload = new PayloadData (data);
var e = new CloseEventArgs (payload);
var bytes = send var bytes = send
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null; : null;
foreach (var host in _hosts.Values) foreach (var host in _hosts.Values)

View File

@ -583,12 +583,7 @@ namespace WebSocketSharp
: null; : null;
} }
private void close (CloseStatusCode code, string reason, bool wait) private void close (CloseEventArgs e, bool send, bool wait)
{
close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait);
}
private void close (PayloadData payload, bool send, bool wait)
{ {
lock (_forConn) { lock (_forConn) {
if (_readyState == WebSocketState.Closing || _readyState == WebSocketState.Closed) { if (_readyState == WebSocketState.Closing || _readyState == WebSocketState.Closed) {
@ -601,15 +596,16 @@ namespace WebSocketSharp
_logger.Trace ("Start closing the connection."); _logger.Trace ("Start closing the connection.");
var e = new CloseEventArgs (payload);
e.WasClean = e.WasClean =
_client _client
? closeHandshake ( ? closeHandshake (
send ? WebSocketFrame.CreateCloseFrame (Mask.Mask, payload).ToByteArray () : null, send ? WebSocketFrame.CreateCloseFrame (Mask.Mask, e.PayloadData).ToByteArray ()
: null,
wait ? 5000 : 0, wait ? 5000 : 0,
releaseClientResources) releaseClientResources)
: closeHandshake ( : closeHandshake (
send ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray () : null, send ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null,
wait ? 1000 : 0, wait ? 1000 : 0,
releaseServerResources); releaseServerResources);
@ -625,10 +621,10 @@ namespace WebSocketSharp
} }
} }
private void closeAsync (PayloadData payload, bool send, bool wait) private void closeAsync (CloseEventArgs e, bool send, bool wait)
{ {
Action<PayloadData, bool, bool> closer = close; Action<CloseEventArgs, bool, bool> closer = close;
closer.BeginInvoke (payload, send, wait, ar => closer.EndInvoke (ar), null); closer.BeginInvoke (e, send, wait, ar => closer.EndInvoke (ar), null);
} }
private bool closeHandshake (byte[] frameAsBytes, int millisecondsTimeout, Action release) private bool closeHandshake (byte[] frameAsBytes, int millisecondsTimeout, Action release)
@ -836,7 +832,7 @@ namespace WebSocketSharp
msg = "An error has occurred while connecting."; msg = "An error has occurred while connecting.";
error (msg, null); error (msg, null);
close (CloseStatusCode.Abnormal, msg, false); close (new CloseEventArgs (CloseStatusCode.Abnormal, msg), false, false);
return false; return false;
} }
@ -898,7 +894,7 @@ namespace WebSocketSharp
private bool processCloseFrame (WebSocketFrame frame) private bool processCloseFrame (WebSocketFrame frame)
{ {
var payload = frame.PayloadData; var payload = frame.PayloadData;
close (payload, !payload.IncludesReservedCloseStatusCode, false); close (new CloseEventArgs (payload), !payload.IncludesReservedCloseStatusCode, false);
return false; return false;
} }
@ -935,7 +931,7 @@ namespace WebSocketSharp
return; return;
} }
close (code, reason ?? code.GetMessage (), false); close (new CloseEventArgs (code, reason ?? code.GetMessage ()), !code.IsReserved (), false);
} }
private bool processFragmentedFrame (WebSocketFrame frame) private bool processFragmentedFrame (WebSocketFrame frame)
@ -1560,7 +1556,7 @@ namespace WebSocketSharp
} }
var send = _readyState == WebSocketState.Open; var send = _readyState == WebSocketState.Open;
close (new PayloadData (), send, send); close (new CloseEventArgs (), send, send);
} }
/// <summary> /// <summary>
@ -1577,7 +1573,18 @@ namespace WebSocketSharp
/// </param> /// </param>
public void Close (ushort code) public void Close (ushort code)
{ {
Close (code, null); var msg = _readyState.CheckIfClosable () ??
code.CheckIfValidCloseStatusCode ();
if (msg != null) {
_logger.Error (msg);
error ("An error has occurred in closing the connection.", null);
return;
}
var send = _readyState == WebSocketState.Open && !code.IsReserved ();
close (new CloseEventArgs (code), send, send);
} }
/// <summary> /// <summary>
@ -1590,7 +1597,16 @@ namespace WebSocketSharp
/// </param> /// </param>
public void Close (CloseStatusCode code) public void Close (CloseStatusCode code)
{ {
Close (code, null); var msg = _readyState.CheckIfClosable ();
if (msg != null) {
_logger.Error (msg);
error ("An error has occurred in closing the connection.", null);
return;
}
var send = _readyState == WebSocketState.Open && !code.IsReserved ();
close (new CloseEventArgs (code), send, send);
} }
/// <summary> /// <summary>
@ -1599,7 +1615,7 @@ namespace WebSocketSharp
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method emits a <see cref="OnError"/> event if <paramref name="code"/> /// This method emits a <see cref="OnError"/> event if <paramref name="code"/>
/// isn't in the allowable range of the close status code, or the size of /// isn't in the allowable range of the close status code or the size of
/// <paramref name="reason"/> is greater than 123 bytes. /// <paramref name="reason"/> is greater than 123 bytes.
/// </remarks> /// </remarks>
/// <param name="code"> /// <param name="code">
@ -1611,20 +1627,20 @@ namespace WebSocketSharp
/// </param> /// </param>
public void Close (ushort code, string reason) public void Close (ushort code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
var msg = _readyState.CheckIfClosable () ?? var msg = _readyState.CheckIfClosable () ??
code.CheckIfValidCloseStatusCode () ?? code.CheckIfValidCloseStatusCode () ??
(data = code.Append (reason)).CheckIfValidControlData ("reason"); (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); _logger.Error (msg);
error ("An error has occurred in closing the connection.", null); error ("An error has occurred in closing the connection.", null);
return; return;
} }
var send = _readyState == WebSocketState.Open && !code.IsReserved (); var send = _readyState == WebSocketState.Open && !code.IsReserved ();
close (new PayloadData (data), send, send); close (e, send, send);
} }
/// <summary> /// <summary>
@ -1644,19 +1660,19 @@ namespace WebSocketSharp
/// </param> /// </param>
public void Close (CloseStatusCode code, string reason) public void Close (CloseStatusCode code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
var msg = _readyState.CheckIfClosable () ?? var msg = _readyState.CheckIfClosable () ??
(data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); _logger.Error (msg);
error ("An error has occurred in closing the connection.", null); error ("An error has occurred in closing the connection.", null);
return; return;
} }
var send = _readyState == WebSocketState.Open && !code.IsReserved (); var send = _readyState == WebSocketState.Open && !code.IsReserved ();
close (new PayloadData (data), send, send); close (e, send, send);
} }
/// <summary> /// <summary>
@ -1676,7 +1692,7 @@ namespace WebSocketSharp
} }
var send = _readyState == WebSocketState.Open; var send = _readyState == WebSocketState.Open;
closeAsync (new PayloadData (), send, send); closeAsync (new CloseEventArgs (), send, send);
} }
/// <summary> /// <summary>
@ -1697,7 +1713,18 @@ namespace WebSocketSharp
/// </param> /// </param>
public void CloseAsync (ushort code) public void CloseAsync (ushort code)
{ {
CloseAsync (code, null); var msg = _readyState.CheckIfClosable () ??
code.CheckIfValidCloseStatusCode ();
if (msg != null) {
_logger.Error (msg);
error ("An error has occurred in closing the connection.", null);
return;
}
var send = _readyState == WebSocketState.Open && !code.IsReserved ();
closeAsync (new CloseEventArgs (code), send, send);
} }
/// <summary> /// <summary>
@ -1713,7 +1740,16 @@ namespace WebSocketSharp
/// </param> /// </param>
public void CloseAsync (CloseStatusCode code) public void CloseAsync (CloseStatusCode code)
{ {
CloseAsync (code, null); var msg = _readyState.CheckIfClosable ();
if (msg != null) {
_logger.Error (msg);
error ("An error has occurred in closing the connection.", null);
return;
}
var send = _readyState == WebSocketState.Open && !code.IsReserved ();
closeAsync (new CloseEventArgs (code), send, send);
} }
/// <summary> /// <summary>
@ -1726,7 +1762,7 @@ namespace WebSocketSharp
/// </para> /// </para>
/// <para> /// <para>
/// This method emits a <see cref="OnError"/> event if <paramref name="code"/> isn't in /// This method emits a <see cref="OnError"/> event if <paramref name="code"/> isn't in
/// the allowable range of the close status code, or the size of <paramref name="reason"/> /// the allowable range of the close status code or the size of <paramref name="reason"/>
/// is greater than 123 bytes. /// is greater than 123 bytes.
/// </para> /// </para>
/// </remarks> /// </remarks>
@ -1738,20 +1774,20 @@ namespace WebSocketSharp
/// </param> /// </param>
public void CloseAsync (ushort code, string reason) public void CloseAsync (ushort code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
var msg = _readyState.CheckIfClosable () ?? var msg = _readyState.CheckIfClosable () ??
code.CheckIfValidCloseStatusCode () ?? code.CheckIfValidCloseStatusCode () ??
(data = code.Append (reason)).CheckIfValidControlData ("reason"); (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); _logger.Error (msg);
error ("An error has occurred in closing the connection.", null); error ("An error has occurred in closing the connection.", null);
return; return;
} }
var send = _readyState == WebSocketState.Open && !code.IsReserved (); var send = _readyState == WebSocketState.Open && !code.IsReserved ();
closeAsync (new PayloadData (data), send, send); closeAsync (e, send, send);
} }
/// <summary> /// <summary>
@ -1777,19 +1813,19 @@ namespace WebSocketSharp
/// </param> /// </param>
public void CloseAsync (CloseStatusCode code, string reason) public void CloseAsync (CloseStatusCode code, string reason)
{ {
byte[] data = null; CloseEventArgs e = null;
var msg = _readyState.CheckIfClosable () ?? var msg = _readyState.CheckIfClosable () ??
(data = ((ushort) code).Append (reason)).CheckIfValidControlData ("reason"); (e = new CloseEventArgs (code, reason)).RawData.CheckIfValidControlData ("reason");
if (msg != null) { if (msg != null) {
_logger.Error (String.Format ("{0}\ncode: {1} reason: {2}", msg, code, reason)); _logger.Error (msg);
error ("An error has occurred in closing the connection.", null); error ("An error has occurred in closing the connection.", null);
return; return;
} }
var send = _readyState == WebSocketState.Open && !code.IsReserved (); var send = _readyState == WebSocketState.Open && !code.IsReserved ();
closeAsync (new PayloadData (data), send, send); closeAsync (e, send, send);
} }
/// <summary> /// <summary>
@ -2224,9 +2260,8 @@ namespace WebSocketSharp
/// </remarks> /// </remarks>
void IDisposable.Dispose () void IDisposable.Dispose ()
{ {
var data = ((ushort) CloseStatusCode.Away).InternalToByteArray (ByteOrder.Big);
var send = _readyState == WebSocketState.Open; var send = _readyState == WebSocketState.Open;
close (new PayloadData (data), send, send); close (new CloseEventArgs (CloseStatusCode.Away), send, send);
} }
#endregion #endregion