Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added an indicator to the OnClose to determine if

has been a clean/unclean close.  Also added the same changes to the
WebSocketHandler and DefaultWebSocketHandler for consistencies sake.

#735
  • Loading branch information...
commit 6d03262faa167e8d3e0a89028c265fd6289683df 1 parent d75b17c
@NTaylorMullen NTaylorMullen authored
View
28 SignalR.Hosting.AspNet45/WebSockets/DefaultWebSocketHandler.cs
@@ -7,31 +7,17 @@ internal class DefaultWebSocketHandler : WebSocketHandler, IWebSocket
{
private bool _raiseEvent = true;
- public override void OnClose()
+ public override void OnClose(bool clean)
{
if (!_raiseEvent)
{
return;
}
- Action onClose = ((IWebSocket)this).OnClose;
+ Action<bool> onClose = ((IWebSocket)this).OnClose;
if (onClose != null)
{
- onClose();
- }
- }
-
- public override void OnUngracefulClose()
- {
- if (!_raiseEvent)
- {
- return;
- }
-
- Action onUngracefulClose = ((IWebSocket)this).OnUngracefulClose;
- if (onUngracefulClose != null)
- {
- onUngracefulClose();
+ onClose(clean);
}
}
@@ -65,13 +51,7 @@ Action<string> IWebSocket.OnMessage
set;
}
- Action IWebSocket.OnClose
- {
- get;
- set;
- }
-
- Action IWebSocket.OnUngracefulClose
+ Action<bool> IWebSocket.OnClose
{
get;
set;
View
21 SignalR.Hosting.AspNet45/WebSockets/WebSocketHandler.cs
@@ -32,11 +32,8 @@ internal class WebSocketHandler
// The developer can look at the Error property to get the exception
public virtual void OnError() { }
- // Called when the socket is closed gracefully; invoked 1 time per socket
- public virtual void OnClose() { }
-
- // Called when the socket is closed ungracefully
- public virtual void OnUngracefulClose() { }
+ // Called when the socket is closed; invoked 1 time per socket
+ public virtual void OnClose(bool clean) { }
/*
* NON-VIRTUAL HELPER METHODS
@@ -130,7 +127,7 @@ public Task ProcessWebSocketRequestAsync(WebSocketContext webSocketContext)
internal async Task ProcessWebSocketRequestAsync(WebSocketContext webSocketContext, Func<Task<WebSocketMessage>> messageRetriever)
{
- bool GracefulClose = true;
+ bool CleanClose = true;
try
{
// first, set primitives and initialize the object
@@ -167,22 +164,14 @@ await Task.WhenAny(CloseAsync(), Task.Delay(_closeTimeout))
{
Error = ex;
OnError();
- GracefulClose = false;
+ CleanClose = false;
}
}
finally
{
try
{
- if (GracefulClose)
- {
- // we're finished
- OnClose();
- }
- else
- {
- OnUngracefulClose();
- }
+ OnClose(CleanClose);
}
finally
{
View
10 SignalR.Server/ServerRequestWebSocket.cs
@@ -77,8 +77,7 @@ public Task Invoke(IDictionary<string, object> context)
}
public Action<string> OnMessage { get; set; }
- public Action OnClose { get; set; }
- public Action OnUngracefulClose { get; set; }
+ public Action<bool> OnClose { get; set; }
public Action<Exception> OnError { get; set; }
public Task Send(string value)
@@ -163,7 +162,7 @@ private void ContinueReceiving(WebSocketReceiveTuple receiveData)
{
if (OnClose != null)
{
- OnClose();
+ OnClose(true);
}
return;
@@ -192,11 +191,12 @@ private void ErrorReceiving(Exception error)
}
}
- if (OnUngracefulClose != null)
+ // Unclean disconnect
+ if (OnClose != null)
{
try
{
- OnUngracefulClose();
+ OnClose(false);
}
catch
{
View
7 SignalR/Hosting/IWebSocket.cs
@@ -16,12 +16,7 @@ public interface IWebSocket
/// <summary>
/// Invoked when the websocket gracefully closes
/// </summary>
- Action OnClose { get; set; }
-
- /// <summary>
- /// Invoked when the websocket ungracefully closes
- /// </summary>
- Action OnUngracefulClose { get; set; }
+ Action<bool> OnClose { get; set; }
/// <summary>
/// Invoked when there is an error
View
13 SignalR/Transports/WebSocketTransport.cs
@@ -47,16 +47,13 @@ public override Task ProcessRequest(ITransportConnection connection)
{
_socket = socket;
- socket.OnClose = () =>
+ socket.OnClose = clean =>
{
- OnDisconnect();
-
- _isAlive = false;
- };
+ if (clean)
+ {
+ OnDisconnect();
+ }
- socket.OnUngracefulClose = () =>
- {
- // Die but let the heartbeat clean up the connection
_isAlive = false;
};

4 comments on commit 6d03262

@davidfowl
Owner

So if it's an unclean disconnect Disconnect never fires? What's the idea behind that?

@NTaylorMullen
Collaborator

If it's an unclean disconnect we need to leave it for the Heartbeat to clean up. How it worked in the past is that it would disconnect and therefore be removed from the heartbeat before it was considered "timed out".

All of the other transports get cleaned up by the heartbeat when the client goes away. By not calling disconnect on an unclean disconnect we now make websockets like the other transports.

A pro to doing it this way is that if a client disconnects due to a network drop they are then allotted the 110 second (current config value) timeout period to reconnect to the server before their connection is removed from the connection pool.

@davidfowl
Owner

Can you add some comments to the code?

@NTaylorMullen
Collaborator

Doneski! fcd1641

Please sign in to comment.
Something went wrong with that request. Please try again.