Skip to content
Browse files

Fixed race condition where connection could start sending before the

message bus is subscribed.
Fixes #552.
  • Loading branch information...
1 parent 8464514 commit 7dcdc8f23ab236c33304305c19c9a88aeec703db @davidfowl davidfowl committed Jul 22, 2012
Showing with 32 additions and 8 deletions.
  1. +29 −6 SignalR.Client/Transports/LongPollingTransport.cs
  2. +3 −2 SignalR/Transports/ForeverTransport.cs
View
35 SignalR.Client/Transports/LongPollingTransport.cs
@@ -1,18 +1,29 @@
using System;
using System.Diagnostics;
using System.IO;
-using System.Threading;
using SignalR.Client.Http;
using SignalR.Client.Infrastructure;
namespace SignalR.Client.Transports
{
public class LongPollingTransport : HttpBasedTransport
{
- private static readonly TimeSpan _errorDelay = TimeSpan.FromSeconds(2);
-
+ /// <summary>
+ /// The time to wait after a connection drops to try reconnecting.
+ /// </summary>
public TimeSpan ReconnectDelay { get; set; }
+ /// <summary>
+ /// The time to wait after an error happens to continue polling.
+ /// </summary>
+ public TimeSpan ErrorDelay { get; set; }
+
+ /// <summary>
+ /// The time to wait after the initial connect http request before it is considered
+ /// open.
+ /// </summary>
+ public TimeSpan ConnectDelay { get; set; }
+
public LongPollingTransport()
: this(new DefaultHttpClient())
{
@@ -22,6 +33,8 @@ public LongPollingTransport(IHttpClient httpClient)
: base(httpClient, "longPolling")
{
ReconnectDelay = TimeSpan.FromSeconds(5);
+ ErrorDelay = TimeSpan.FromSeconds(2);
+ ConnectDelay = TimeSpan.FromSeconds(2);
}
protected override void OnStart(IConnection connection, string data, Action initializeCallback, Action<Exception> errorCallback)
@@ -78,6 +91,13 @@ private void PollingLoop(IConnection connection, string data, Action initializeC
reconnectInvoker.Invoke((conn) => FireReconnected(conn), connection);
}
+ if (initializeCallback != null)
+ {
+ // If the timeout for connect hasn't fired as yet then just fire
+ // the event before any incoming messages are processed
+ callbackInvoker.Invoke(initializeCallback);
+ }
+
// Get the response
var raw = task.Result.ReadAsString();
@@ -106,7 +126,7 @@ private void PollingLoop(IConnection connection, string data, Action initializeC
// Raise the reconnect event if we successfully reconnect after failing
shouldRaiseReconnect = true;
-
+
// Get the underlying exception
Exception exception = task.Exception.Unwrap();
@@ -129,7 +149,7 @@ private void PollingLoop(IConnection connection, string data, Action initializeC
// If the connection is still active after raising the error event wait for 2 seconds
// before polling again so we aren't hammering the server
- TaskAsyncHelper.Delay(_errorDelay).Then(() =>
+ TaskAsyncHelper.Delay(ErrorDelay).Then(() =>
{
if (connection.State != ConnectionState.Disconnected)
{
@@ -161,7 +181,10 @@ private void PollingLoop(IConnection connection, string data, Action initializeC
if (initializeCallback != null)
{
- callbackInvoker.Invoke(initializeCallback);
+ TaskAsyncHelper.Delay(ConnectDelay).Then(() =>
+ {
+ callbackInvoker.Invoke(initializeCallback);
+ });
}
if (raiseReconnect)
View
5 SignalR/Transports/ForeverTransport.cs
@@ -181,10 +181,11 @@ private Task ProcessReceiveRequestWithoutTracking(ITransportConnection connectio
{
postReceive();
}
+
+ InitializeResponse(connection).Catch();
};
- return InitializeResponse(connection)
- .Then((c, pr) => ProcessMessages(c, pr), connection, afterReceive);
+ return ProcessMessages(connection, afterReceive);
}
private Task ProcessMessages(ITransportConnection connection, Action postReceive = null)

0 comments on commit 7dcdc8f

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