Added internal 'wait time' for the ping and close

This commit is contained in:
sta 2014-09-23 15:45:40 +09:00
parent b6b30e04d0
commit 14914787a6
8 changed files with 138 additions and 74 deletions

View File

@ -424,7 +424,7 @@ namespace WebSocketSharp.Server
_state = ServerState.ShuttingDown;
}
_services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true);
_services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true, false);
_listener.Abort ();
_state = ServerState.Stop;
@ -696,7 +696,7 @@ namespace WebSocketSharp.Server
_state = ServerState.ShuttingDown;
}
_services.Stop (new CloseEventArgs (), true);
_services.Stop (new CloseEventArgs (), true, true);
stopReceiving (5000);
_state = ServerState.Stop;
@ -729,7 +729,9 @@ namespace WebSocketSharp.Server
_state = ServerState.ShuttingDown;
}
_services.Stop (e, !code.IsReserved ());
var send = !code.IsReserved ();
_services.Stop (e, send, send);
stopReceiving (5000);
_state = ServerState.Stop;
@ -762,7 +764,9 @@ namespace WebSocketSharp.Server
_state = ServerState.ShuttingDown;
}
_services.Stop (e, !code.IsReserved ());
var send = !code.IsReserved ();
_services.Stop (e, send, send);
stopReceiving (5000);
_state = ServerState.Stop;

View File

@ -315,8 +315,9 @@ namespace WebSocketSharp.Server
_sessions = sessions;
_websocket = context.WebSocket;
_websocket.Protocol = _protocol;
_websocket.CustomHandshakeRequestChecker = checkIfValidConnectionRequest;
_websocket.Protocol = _protocol;
_websocket.WaitTime = sessions.WaitTime;
_websocket.OnOpen += onOpen;
_websocket.OnMessage += onMessage;

View File

@ -507,7 +507,7 @@ namespace WebSocketSharp.Server
}
_listener.Stop ();
_services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true);
_services.Stop (new CloseEventArgs (CloseStatusCode.ServerError), true, false);
_state = ServerState.Stop;
}
@ -793,7 +793,7 @@ namespace WebSocketSharp.Server
}
stopReceiving (5000);
_services.Stop (new CloseEventArgs (), true);
_services.Stop (new CloseEventArgs (), true, true);
_state = ServerState.Stop;
}
@ -826,7 +826,9 @@ namespace WebSocketSharp.Server
}
stopReceiving (5000);
_services.Stop (e, !code.IsReserved ());
var send = !code.IsReserved ();
_services.Stop (e, send, send);
_state = ServerState.Stop;
}
@ -859,7 +861,9 @@ namespace WebSocketSharp.Server
}
stopReceiving (5000);
_services.Stop (e, !code.IsReserved ());
var send = !code.IsReserved ();
_services.Stop (e, send, send);
_state = ServerState.Stop;
}

View File

@ -67,6 +67,16 @@ namespace WebSocketSharp.Server
}
}
internal TimeSpan WaitTime {
get {
return Sessions.WaitTime;
}
set {
Sessions.WaitTime = value;
}
}
#endregion
#region Public Properties
@ -122,11 +132,13 @@ namespace WebSocketSharp.Server
internal void Stop (ushort code, string reason)
{
var e = new CloseEventArgs (code, reason);
var bytes = !code.IsReserved ()
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null;
Sessions.Stop (e, bytes);
var send = !code.IsReserved ();
var bytes =
send ? WebSocketFrame.CreateCloseFrame (e.PayloadData, false).ToByteArray () : null;
var timeout = send ? WaitTime : TimeSpan.Zero;
Sessions.Stop (e, bytes, timeout);
}
#endregion

View File

@ -49,6 +49,7 @@ namespace WebSocketSharp.Server
private Logger _logger;
private volatile ServerState _state;
private object _sync;
private TimeSpan _waitTime;
#endregion
@ -67,6 +68,28 @@ namespace WebSocketSharp.Server
_hosts = new Dictionary<string, WebSocketServiceHost> ();
_state = ServerState.Ready;
_sync = ((ICollection) _hosts).SyncRoot;
_waitTime = TimeSpan.FromSeconds (1);
}
#endregion
#region Internal Properties
internal TimeSpan WaitTime {
get {
return _waitTime;
}
set {
lock (_sync) {
if (value == _waitTime)
return;
_waitTime = value;
foreach (var host in _hosts.Values)
host.WaitTime = value;
}
}
}
#endregion
@ -240,14 +263,14 @@ namespace WebSocketSharp.Server
}
private Dictionary<string, Dictionary<string, bool>> broadping (
byte[] frameAsBytes, int millisecondsTimeout)
byte[] frameAsBytes, TimeSpan timeout)
{
var res = new Dictionary<string, Dictionary<string, bool>> ();
foreach (var host in Hosts) {
if (_state != ServerState.Start)
break;
res.Add (host.Path, host.Sessions.Broadping (frameAsBytes, millisecondsTimeout));
res.Add (host.Path, host.Sessions.Broadping (frameAsBytes, timeout));
}
return res;
@ -275,6 +298,9 @@ namespace WebSocketSharp.Server
if (!_clean)
host.KeepClean = false;
if (_waitTime != host.WaitTime)
host.WaitTime = _waitTime;
if (_state == ServerState.Start)
host.Start ();
@ -325,16 +351,17 @@ namespace WebSocketSharp.Server
}
}
internal void Stop (CloseEventArgs e, bool send)
internal void Stop (CloseEventArgs e, bool send, bool wait)
{
lock (_sync) {
_state = ServerState.ShuttingDown;
var bytes = send
? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null;
var bytes =
send ? WebSocketFrame.CreateCloseFrame (e.PayloadData, false).ToByteArray () : null;
var timeout = wait ? _waitTime : TimeSpan.Zero;
foreach (var host in _hosts.Values)
host.Sessions.Stop (e, bytes);
host.Sessions.Stop (e, bytes, timeout);
_hosts.Clear ();
_state = ServerState.Stop;
@ -512,7 +539,7 @@ namespace WebSocketSharp.Server
return null;
}
return broadping (WebSocketFrame.EmptyUnmaskPingData, 1000);
return broadping (WebSocketFrame.EmptyUnmaskPingData, _waitTime);
}
/// <summary>
@ -543,7 +570,7 @@ namespace WebSocketSharp.Server
return null;
}
return broadping (WebSocketFrame.CreatePingFrame (Mask.Unmask, data).ToByteArray (), 1000);
return broadping (WebSocketFrame.CreatePingFrame (data, false).ToByteArray (), _waitTime);
}
/// <summary>

View File

@ -51,6 +51,7 @@ namespace WebSocketSharp.Server
private volatile bool _sweeping;
private System.Timers.Timer _sweepTimer;
private object _sync;
private TimeSpan _waitTime;
#endregion
@ -70,6 +71,7 @@ namespace WebSocketSharp.Server
_sessions = new Dictionary<string, IWebSocketSession> ();
_state = ServerState.Ready;
_sync = ((ICollection) _sessions).SyncRoot;
_waitTime = TimeSpan.FromSeconds (1);
setSweepTimer (60000);
}
@ -84,6 +86,21 @@ namespace WebSocketSharp.Server
}
}
internal TimeSpan WaitTime {
get {
return _waitTime;
}
set {
if (value == _waitTime)
return;
_waitTime = value;
foreach (var session in Sessions)
session.Context.WebSocket.WaitTime = value;
}
}
#endregion
#region Public Properties
@ -97,7 +114,7 @@ namespace WebSocketSharp.Server
/// </value>
public IEnumerable<string> ActiveIDs {
get {
foreach (var res in Broadping (WebSocketFrame.EmptyUnmaskPingData, 1000))
foreach (var res in Broadping (WebSocketFrame.EmptyUnmaskPingData, _waitTime))
if (res.Value)
yield return res.Key;
}
@ -142,7 +159,7 @@ namespace WebSocketSharp.Server
/// </value>
public IEnumerable<string> InactiveIDs {
get {
foreach (var res in Broadping (WebSocketFrame.EmptyUnmaskPingData, 1000))
foreach (var res in Broadping (WebSocketFrame.EmptyUnmaskPingData, _waitTime))
if (!res.Value)
yield return res.Key;
}
@ -318,14 +335,14 @@ namespace WebSocketSharp.Server
}
}
internal Dictionary<string, bool> Broadping (byte[] frameAsBytes, int millisecondsTimeout)
internal Dictionary<string, bool> Broadping (byte[] frameAsBytes, TimeSpan timeout)
{
var res = new Dictionary<string, bool> ();
foreach (var session in Sessions) {
if (_state != ServerState.Start)
break;
res.Add (session.ID, session.Context.WebSocket.Ping (frameAsBytes, millisecondsTimeout));
res.Add (session.ID, session.Context.WebSocket.Ping (frameAsBytes, timeout));
}
return res;
@ -345,14 +362,14 @@ namespace WebSocketSharp.Server
}
}
internal void Stop (CloseEventArgs e, byte[] frameAsBytes)
internal void Stop (CloseEventArgs e, byte[] frameAsBytes, TimeSpan timeout)
{
lock (_sync) {
_state = ServerState.ShuttingDown;
_sweepTimer.Enabled = false;
foreach (var session in _sessions.Values.ToList ())
session.Context.WebSocket.Close (e, frameAsBytes, 1000);
session.Context.WebSocket.Close (e, frameAsBytes, timeout);
_state = ServerState.Stop;
}
@ -528,7 +545,7 @@ namespace WebSocketSharp.Server
return null;
}
return Broadping (WebSocketFrame.EmptyUnmaskPingData, 1000);
return Broadping (WebSocketFrame.EmptyUnmaskPingData, _waitTime);
}
/// <summary>
@ -557,7 +574,7 @@ namespace WebSocketSharp.Server
return null;
}
return Broadping (WebSocketFrame.CreatePingFrame (Mask.Unmask, data).ToByteArray (), 1000);
return Broadping (WebSocketFrame.CreatePingFrame (data, false).ToByteArray (), _waitTime);
}
/// <summary>

View File

@ -101,6 +101,7 @@ namespace WebSocketSharp
private TcpClient _tcpClient;
private Uri _uri;
private const string _version = "13";
private TimeSpan _waitTime;
#endregion
@ -122,6 +123,7 @@ namespace WebSocketSharp
_closeContext = context.Close;
_secure = context.IsSecureConnection;
_stream = context.Stream;
_waitTime = TimeSpan.FromSeconds (1);
init ();
}
@ -136,6 +138,7 @@ namespace WebSocketSharp
_closeContext = context.Close;
_secure = context.IsSecureConnection;
_stream = context.Stream;
_waitTime = TimeSpan.FromSeconds (1);
init ();
}
@ -191,6 +194,7 @@ namespace WebSocketSharp
_client = true;
_logger = new Logger ();
_secure = _uri.Scheme == "wss";
_waitTime = TimeSpan.FromSeconds (5);
init ();
}
@ -222,6 +226,16 @@ namespace WebSocketSharp
}
}
internal TimeSpan WaitTime {
get {
return _waitTime;
}
set {
_waitTime = value;
}
}
#endregion
#region Public Properties
@ -596,18 +610,10 @@ namespace WebSocketSharp
_logger.Trace ("Start closing the connection.");
e.WasClean =
_client
? closeHandshake (
send ? WebSocketFrame.CreateCloseFrame (Mask.Mask, e.PayloadData).ToByteArray ()
: null,
wait ? 5000 : 0,
releaseClientResources)
: closeHandshake (
send ? WebSocketFrame.CreateCloseFrame (Mask.Unmask, e.PayloadData).ToByteArray ()
: null,
wait ? 1000 : 0,
releaseServerResources);
e.WasClean = closeHandshake (
WebSocketFrame.CreateCloseFrame (e.PayloadData, _client).ToByteArray (),
wait ? _waitTime : TimeSpan.Zero,
_client ? (Action) releaseClientResources : releaseServerResources);
_logger.Trace ("End closing the connection.");
@ -627,13 +633,11 @@ namespace WebSocketSharp
closer.BeginInvoke (e, send, wait, ar => closer.EndInvoke (ar), null);
}
private bool closeHandshake (byte[] frameAsBytes, int millisecondsTimeout, Action release)
private bool closeHandshake (byte[] frameAsBytes, TimeSpan timeout, Action release)
{
var sent = frameAsBytes != null && sendBytes (frameAsBytes);
var received = millisecondsTimeout == 0 ||
(sent &&
_exitReceiving != null &&
_exitReceiving.WaitOne (millisecondsTimeout));
var received = timeout == TimeSpan.Zero ||
(sent && _exitReceiving != null && _exitReceiving.WaitOne (timeout));
release ();
if (_receivePong != null) {
@ -1412,7 +1416,7 @@ namespace WebSocketSharp
}
// As server
internal void Close (CloseEventArgs e, byte[] frameAsBytes, int millisecondsTimeout)
internal void Close (CloseEventArgs e, byte[] frameAsBytes, TimeSpan timeout)
{
lock (_forConn) {
if (_readyState == WebSocketState.Closing || _readyState == WebSocketState.Closed) {
@ -1423,7 +1427,7 @@ namespace WebSocketSharp
_readyState = WebSocketState.Closing;
}
e.WasClean = closeHandshake (frameAsBytes, millisecondsTimeout, releaseServerResources);
e.WasClean = closeHandshake (frameAsBytes, timeout, releaseServerResources);
_readyState = WebSocketState.Closed;
try {
@ -1468,14 +1472,14 @@ namespace WebSocketSharp
return Convert.ToBase64String (src);
}
internal bool Ping (byte[] frameAsBytes, int millisecondsTimeout)
internal bool Ping (byte[] frameAsBytes, TimeSpan timeout)
{
try {
AutoResetEvent pong;
return _readyState == WebSocketState.Open &&
send (frameAsBytes) &&
(pong = _receivePong) != null &&
pong.WaitOne (millisecondsTimeout);
pong.WaitOne (timeout);
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
@ -1879,9 +1883,11 @@ namespace WebSocketSharp
/// </returns>
public bool Ping ()
{
return _client
? Ping (WebSocketFrame.CreatePingFrame (Mask.Mask).ToByteArray (), 5000)
: Ping (WebSocketFrame.EmptyUnmaskPingData, 1000);
var bytes = _client
? WebSocketFrame.CreatePingFrame (true).ToByteArray ()
: WebSocketFrame.EmptyUnmaskPingData;
return Ping (bytes, _waitTime);
}
/// <summary>
@ -1908,9 +1914,7 @@ namespace WebSocketSharp
return false;
}
return _client
? Ping (WebSocketFrame.CreatePingFrame (Mask.Mask, data).ToByteArray (), 5000)
: Ping (WebSocketFrame.CreatePingFrame (Mask.Unmask, data).ToByteArray (), 1000);
return Ping (WebSocketFrame.CreatePingFrame (data, _client).ToByteArray (), _waitTime);
}
/// <summary>

View File

@ -61,7 +61,7 @@ namespace WebSocketSharp
static WebSocketFrame ()
{
EmptyUnmaskPingData = CreatePingFrame (Mask.Unmask).ToByteArray ();
EmptyUnmaskPingData = CreatePingFrame (false).ToByteArray ();
}
#endregion
@ -523,30 +523,25 @@ Extended Payload Length: {7}
#region Internal Methods
internal static WebSocketFrame CreateCloseFrame (Mask mask, byte[] data)
internal static WebSocketFrame CreateCloseFrame (byte[] data, bool mask)
{
return new WebSocketFrame (Opcode.Close, mask, new PayloadData (data));
return CreateCloseFrame (new PayloadData (data), mask);
}
internal static WebSocketFrame CreateCloseFrame (Mask mask, PayloadData payload)
internal static WebSocketFrame CreateCloseFrame (PayloadData payloadData, bool mask)
{
return new WebSocketFrame (Opcode.Close, mask, payload);
return new WebSocketFrame (Opcode.Close, mask ? Mask.Mask : Mask.Unmask, payloadData);
}
internal static WebSocketFrame CreateCloseFrame (Mask mask, CloseStatusCode code, string reason)
internal static WebSocketFrame CreatePingFrame (bool mask)
{
return new WebSocketFrame (Opcode.Ping, mask ? Mask.Mask : Mask.Unmask, new PayloadData ());
}
internal static WebSocketFrame CreatePingFrame (byte[] data, bool mask)
{
return new WebSocketFrame (
Opcode.Close, mask, new PayloadData (((ushort) code).Append (reason)));
}
internal static WebSocketFrame CreatePingFrame (Mask mask)
{
return new WebSocketFrame (Opcode.Ping, mask, new PayloadData ());
}
internal static WebSocketFrame CreatePingFrame (Mask mask, byte[] data)
{
return new WebSocketFrame (Opcode.Ping, mask, new PayloadData (data));
Opcode.Ping, mask ? Mask.Mask : Mask.Unmask, new PayloadData (data));
}
internal static WebSocketFrame CreatePongFrame (Mask mask, PayloadData payload)