Skip to content

Commit

Permalink
Invert logic to raise long polling reconnects on the server
Browse files Browse the repository at this point in the history
- Checking for "/poll" to suppress reconnects does not work since 1.0.*
  clients do not append anything to the URL of poll requests.
- Raising reconnects only  for long polling requests ending with
  "/reconnect" preserves the old server behavior
- This prevents 1.0.* clients from causing a reconnect per poll

#3044
  • Loading branch information
halter73 committed May 21, 2014
1 parent 6108a5d commit cf659b4
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 4 deletions.
Expand Up @@ -196,7 +196,7 @@ private Task ProcessReceiveRequest(ITransportConnection connection)
};
}
}
else if (!IsPollRequest)
else if (!SuppressReconnect)
{
initialize = Reconnected;
_counters.ConnectionsReconnected.Increment();
Expand Down
Expand Up @@ -86,11 +86,11 @@ protected override int MaxMessages
}
}

protected override bool IsPollRequest
protected override bool SuppressReconnect
{
get
{
return Context.Request.LocalPath.EndsWith("/poll", StringComparison.OrdinalIgnoreCase);
return !Context.Request.LocalPath.EndsWith("/reconnect", StringComparison.OrdinalIgnoreCase);
}
}

Expand Down
Expand Up @@ -211,7 +211,7 @@ protected bool IsAbortRequest
}
}

protected virtual bool IsPollRequest
protected virtual bool SuppressReconnect
{
get
{
Expand Down
Expand Up @@ -114,6 +114,7 @@
<Compile Include="Server\TopicFacts.cs" />
<Compile Include="Server\Transports\ForeverTransportFacts.cs" />
<Compile Include="Owin\WebSocketFacts.cs" />
<Compile Include="Server\Transports\LongPollingTransportFacts.cs" />
<Compile Include="Server\Transports\WebsocketTransportFacts.cs" />
<Compile Include="SipHashBasedStringEqualityComparerFacts.cs" />
<Compile Include="StringMinifierFacts.cs" />
Expand Down
@@ -0,0 +1,112 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Configuration;
using Microsoft.AspNet.SignalR.Hosting;
using Microsoft.AspNet.SignalR.Infrastructure;
using Microsoft.AspNet.SignalR.Json;
using Microsoft.AspNet.SignalR.Tests.Common.Infrastructure;
using Microsoft.AspNet.SignalR.Tracing;
using Microsoft.AspNet.SignalR.Transports;
using Moq;
using Newtonsoft.Json;
using Xunit;

namespace Microsoft.AspNet.SignalR.Tests.Server.Transports
{
public class LongPollingTransportFacts
{
[Fact]
public void SupressReconnectsForRequestsNotEndingInReconnect()
{
// Arrange transports while specifying request paths
var reconnectTransport = TestLongPollingTransport.Create("/reconnect");
var pollTransport = TestLongPollingTransport.Create("/poll");
var emptyPathTransport = TestLongPollingTransport.Create("/");

// Assert
Assert.False(reconnectTransport.TestSuppressReconnect);
Assert.True(pollTransport.TestSuppressReconnect);
Assert.True(emptyPathTransport.TestSuppressReconnect);
}

[Fact]
public void EmptyPathDoesntTriggerReconnects()
{
// Arrange
var transport = TestLongPollingTransport.Create(requestPath: "/");

var connected = false;
var reconnected = false;

transport.Connected = () =>
{
connected = true;
return TaskAsyncHelper.Empty;
};

transport.Reconnected = () =>
{
reconnected = true;
return TaskAsyncHelper.Empty;
};

var transportConnection = new Mock<ITransportConnection>();
transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
It.IsAny<int>(),
It.IsAny<object>())).Returns(DisposableAction.Empty);

// Act
transport.ProcessRequest(transportConnection.Object);

// Assert
Assert.True(transport.ConnectTask.Wait(TimeSpan.FromSeconds(2)), "ConnectTask task not tripped");
Assert.False(connected, "The Connected event should not be raised");
Assert.False(reconnected, "The Reconnected event should not be raised");
}

private class TestLongPollingTransport : LongPollingTransport
{
private TestLongPollingTransport(
HostContext context,
JsonSerializer json,
ITransportHeartbeat heartBeat,
IPerformanceCounterManager counters,
ITraceManager traceManager,
IConfigurationManager configuarionManager)
: base(context, json, heartBeat, counters, traceManager, configuarionManager)
{
}

public static TestLongPollingTransport Create(string requestPath)
{
var request = new Mock<IRequest>();
request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper());
request.Setup(m => m.LocalPath).Returns(requestPath);

var response = new Mock<IResponse>();
response.Setup(m => m.Flush()).Returns(TaskAsyncHelper.Empty);

var hostContext = new HostContext(request.Object, response.Object);
var json = JsonUtility.CreateDefaultSerializer();
var heartBeat = new Mock<ITransportHeartbeat>();
var counters = new Mock<IPerformanceCounterManager>();
var traceManager = new Mock<ITraceManager>();
var configuarionManager = new Mock<IConfigurationManager>();

return new TestLongPollingTransport(
hostContext,
json,
heartBeat.Object,
counters.Object,
traceManager.Object,
configuarionManager.Object);
}

public bool TestSuppressReconnect
{
get { return SuppressReconnect; }
}
}
}
}

0 comments on commit cf659b4

Please sign in to comment.