Modified closing
This commit is contained in:
parent
7147cde22c
commit
e03f9eb631
@ -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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="ushort"/> is in the allowable range of
|
||||
/// the WebSocket close status code.
|
||||
/// Determines whether the specified <see cref="ushort"/> is in the allowable
|
||||
/// range of the WebSocket close status code.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Not allowable ranges are the followings.
|
||||
@ -1162,14 +1167,15 @@ namespace WebSocketSharp
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>
|
||||
/// 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.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="value"/> is in the allowable range of the WebSocket close status code;
|
||||
/// otherwise, <c>false</c>.
|
||||
/// <c>true</c> if <paramref name="value"/> is in the allowable range of the
|
||||
/// WebSocket close status code; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <param name="value">
|
||||
/// A <see cref="ushort"/> to test.
|
||||
|
@ -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<bool> 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
|
||||
|
||||
/// <summary>
|
||||
/// Closes the WebSocket connection and releases all associated resources.
|
||||
/// Closes the WebSocket connection, and releases all associated resources.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1492,25 +1524,15 @@ namespace WebSocketSharp
|
||||
/// and releases all associated resources.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method emits a <see cref="OnError"/> event if <paramref name="code"/> is not
|
||||
/// in the allowable range of the WebSocket close status code.
|
||||
/// This method emits a <see cref="OnError"/> event if <paramref name="code"/>
|
||||
/// isn't in the allowable range of the WebSocket close status code.
|
||||
/// </remarks>
|
||||
/// <param name="code">
|
||||
/// A <see cref="ushort"/> that indicates the status code for closure.
|
||||
/// </param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1518,75 +1540,81 @@ namespace WebSocketSharp
|
||||
/// and releases all associated resources.
|
||||
/// </summary>
|
||||
/// <param name="code">
|
||||
/// One of the <see cref="CloseStatusCode"/> values that indicate the status codes for closure.
|
||||
/// One of the <see cref="CloseStatusCode"/> values that indicate the status
|
||||
/// codes for closure.
|
||||
/// </param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the WebSocket connection with the specified <see cref="ushort"/> and <see cref="string"/>,
|
||||
/// and releases all associated resources.
|
||||
/// Closes the WebSocket connection with the specified <see cref="ushort"/>
|
||||
/// and <see cref="string"/>, and releases all associated resources.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method emits a <see cref="OnError"/> event if <paramref name="code"/> is not
|
||||
/// in the allowable range of the WebSocket close status code
|
||||
/// or the length of <paramref name="reason"/> is greater than 123 bytes.
|
||||
/// This method emits a <see cref="OnError"/> event if <paramref name="code"/>
|
||||
/// isn't in the allowable range of the WebSocket close status code or the
|
||||
/// length of <paramref name="reason"/> is greater than 123 bytes.
|
||||
/// </remarks>
|
||||
/// <param name="code">
|
||||
/// A <see cref="ushort"/> that indicates the status code for closure.
|
||||
/// </param>
|
||||
/// <param name="reason">
|
||||
/// A <see cref="string"/> that contains the reason for closure.
|
||||
/// A <see cref="string"/> that represents the reason for closure.
|
||||
/// </param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the WebSocket connection with the specified <see cref="CloseStatusCode"/> and
|
||||
/// <see cref="string"/>, and releases all associated resources.
|
||||
/// Closes the WebSocket connection with the specified <see cref="CloseStatusCode"/>
|
||||
/// and <see cref="string"/>, and releases all associated resources.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method emits a <see cref="OnError"/> event if the length of <paramref name="reason"/>
|
||||
/// is greater than 123 bytes.
|
||||
/// This method emits a <see cref="OnError"/> event if the length of
|
||||
/// <paramref name="reason"/> is greater than 123 bytes.
|
||||
/// </remarks>
|
||||
/// <param name="code">
|
||||
/// One of the <see cref="CloseStatusCode"/> values that indicate the status codes for closure.
|
||||
/// One of the <see cref="CloseStatusCode"/> values that indicate the status
|
||||
/// codes for closure.
|
||||
/// </param>
|
||||
/// <param name="reason">
|
||||
/// A <see cref="string"/> that contains the reason for closure.
|
||||
/// A <see cref="string"/> that represents the reason for closure.
|
||||
/// </param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1642,14 +1670,15 @@ namespace WebSocketSharp
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the WebSocket connection and releases all associated resources.
|
||||
/// Closes the WebSocket connection, and releases all associated resources.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method closes the WebSocket connection with the <see cref="CloseStatusCode.AWAY"/>.
|
||||
/// This method closes the WebSocket connection with the
|
||||
/// <see cref="CloseStatusCode.AWAY"/>.
|
||||
/// </remarks>
|
||||
public void Dispose ()
|
||||
{
|
||||
Close (CloseStatusCode.AWAY);
|
||||
Close (CloseStatusCode.AWAY, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user