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
private bool _clean;
private ushort _code;
private string _reason;
private bool _clean;
private ushort _code;
private PayloadData _payloadData;
private byte[] _rawData;
private string _reason;
#endregion
#region Internal Constructors
internal CloseEventArgs (PayloadData payload)
internal CloseEventArgs ()
{
var data = payload.ApplicationData;
var len = data.Length;
_code = (ushort) CloseStatusCode.NoStatusCode;
_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
? data.SubArray (0, 2).ToUInt16 (ByteOrder.Big)
? _rawData.SubArray (0, 2).ToUInt16 (ByteOrder.Big)
: (ushort) CloseStatusCode.NoStatusCode;
_reason = len > 2
? Encoding.UTF8.GetString (data.SubArray (2, len - 2))
? Encoding.UTF8.GetString (_rawData.SubArray (2, len - 2))
: 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
#region Public Properties

View File

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

View File

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

View File

@ -121,10 +121,9 @@ namespace WebSocketSharp.Server
internal void Stop (ushort code, string reason)
{
var payload = new PayloadData (code.Append (reason));
var e = new CloseEventArgs (payload);
var e = new CloseEventArgs (code, reason);
var bytes = !code.IsReserved ()
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray ()
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null;
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) {
_state = ServerState.ShuttingDown;
var payload = new PayloadData (data);
var e = new CloseEventArgs (payload);
var bytes = send
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, payload).ToByteArray ()
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null;
foreach (var host in _hosts.Values)

View File

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