Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ static class HubConnectionContextUtils
{
public static HubConnectionContext Create(ConnectionContext connection, IHubProtocol protocol = null, string userIdentifier = null)
{
return new HubConnectionContext(connection, TimeSpan.FromSeconds(15), NullLoggerFactory.Instance)
var contextOptions = new HubConnectionContextOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(15),
};

return new HubConnectionContext(connection, contextOptions, NullLoggerFactory.Instance)
{
Protocol = protocol ?? new JsonHubProtocol(),
UserIdentifier = userIdentifier,
Expand All @@ -29,15 +34,20 @@ public static HubConnectionContext Create(ConnectionContext connection, IHubProt

public static MockHubConnectionContext CreateMock(ConnectionContext connection)
{
return new MockHubConnectionContext(connection, TimeSpan.FromSeconds(15), NullLoggerFactory.Instance, TimeSpan.FromSeconds(15), streamBufferCapacity: 10);
var contextOptions = new HubConnectionContextOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(15),
ClientTimeoutInterval = TimeSpan.FromSeconds(15),
StreamBufferCapacity = 10,
};
return new MockHubConnectionContext(connection, contextOptions, NullLoggerFactory.Instance);
}

public class MockHubConnectionContext : HubConnectionContext
{
public MockHubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory, TimeSpan clientTimeoutInterval, int streamBufferCapacity)
: base(connectionContext, keepAliveInterval, loggerFactory, clientTimeoutInterval, streamBufferCapacity)
public MockHubConnectionContext(ConnectionContext connectionContext, HubConnectionContextOptions contextOptions, ILoggerFactory loggerFactory)
: base(connectionContext, contextOptions, loggerFactory)
{

}

public override ValueTask WriteAsync(HubMessage message, CancellationToken cancellationToken = default)
Expand Down
6 changes: 5 additions & 1 deletion src/SignalR/perf/Microbenchmarks/BroadcastBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ public void GlobalSetup()
{
var pair = DuplexPipe.CreateConnectionPair(options, options);
var connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), pair.Application, pair.Transport);
var hubConnection = new HubConnectionContext(connection, Timeout.InfiniteTimeSpan, NullLoggerFactory.Instance);
var contextOptions = new HubConnectionContextOptions()
{
KeepAliveInterval = Timeout.InfiniteTimeSpan,
};
var hubConnection = new HubConnectionContext(connection, contextOptions, NullLoggerFactory.Instance);
hubConnection.Protocol = protocol;
_hubLifetimeManager.OnConnectedAsync(hubConnection).GetAwaiter().GetResult();
_hubLifetimeManager.AddToGroupAsync(connection.ConnectionId, TestGroupName).GetAwaiter().GetResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
Expand Down Expand Up @@ -46,7 +44,11 @@ public void GlobalSetup()
var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
var connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), pair.Application, pair.Transport);

_connectionContext = new NoErrorHubConnectionContext(connection, TimeSpan.Zero, NullLoggerFactory.Instance);
var contextOptions = new HubConnectionContextOptions()
{
KeepAliveInterval = TimeSpan.Zero,
};
_connectionContext = new NoErrorHubConnectionContext(connection, contextOptions, NullLoggerFactory.Instance);

_connectionContext.Protocol = new FakeHubProtocol();
}
Expand Down Expand Up @@ -83,7 +85,8 @@ public class NoErrorHubConnectionContext : HubConnectionContext
{
public TaskCompletionSource<object> ReceivedCompleted = new TaskCompletionSource<object>();

public NoErrorHubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory) : base(connectionContext, keepAliveInterval, loggerFactory)
public NoErrorHubConnectionContext(ConnectionContext connectionContext, HubConnectionContextOptions contextOptions, ILoggerFactory loggerFactory)
: base(connectionContext, contextOptions, loggerFactory)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ public void GlobalSetup()
ConnectionId = connectionId,
Transport = new TestDuplexPipe(ForceAsync)
};
var hubConnectionContext = new HubConnectionContext(connectionContext, TimeSpan.Zero, NullLoggerFactory.Instance);
var contextOptions = new HubConnectionContextOptions()
{
KeepAliveInterval = TimeSpan.Zero,
};
var hubConnectionContext = new HubConnectionContext(connectionContext, contextOptions, NullLoggerFactory.Instance);
hubConnectionContext.UserIdentifier = userIdentifier;
hubConnectionContext.Protocol = jsonHubProtocol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.SignalR.Internal;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.AspNetCore.SignalR.Microbenchmarks.Shared;
Expand Down Expand Up @@ -44,7 +43,11 @@ public void GlobalSetup()
_pipe = new TestDuplexPipe();

var connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), _pipe, _pipe);
_hubConnectionContext = new HubConnectionContext(connection, Timeout.InfiniteTimeSpan, NullLoggerFactory.Instance);
var contextOptions = new HubConnectionContextOptions()
{
KeepAliveInterval = Timeout.InfiniteTimeSpan,
};
_hubConnectionContext = new HubConnectionContext(connection, contextOptions, NullLoggerFactory.Instance);

_successHubProtocolResolver = new TestHubProtocolResolver(new NewtonsoftJsonHubProtocol());
_failureHubProtocolResolver = new TestHubProtocolResolver(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,7 @@ public static partial class HubClientsExtensions
}
public partial class HubConnectionContext
{
public HubConnectionContext(Microsoft.AspNetCore.Connections.ConnectionContext connectionContext, System.TimeSpan keepAliveInterval, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
public HubConnectionContext(Microsoft.AspNetCore.Connections.ConnectionContext connectionContext, System.TimeSpan keepAliveInterval, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, System.TimeSpan clientTimeoutInterval) { }
public HubConnectionContext(Microsoft.AspNetCore.Connections.ConnectionContext connectionContext, System.TimeSpan keepAliveInterval, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, System.TimeSpan clientTimeoutInterval, int streamBufferCapacity) { }
public HubConnectionContext(Microsoft.AspNetCore.Connections.ConnectionContext connectionContext, Microsoft.AspNetCore.SignalR.HubConnectionContextOptions contextOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
public virtual System.Threading.CancellationToken ConnectionAborted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public virtual string ConnectionId { get { throw null; } }
public virtual Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get { throw null; } }
Expand All @@ -141,6 +139,13 @@ public virtual void Abort() { }
public virtual System.Threading.Tasks.ValueTask WriteAsync(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.ValueTask WriteAsync(Microsoft.AspNetCore.SignalR.SerializedHubMessage message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
public partial class HubConnectionContextOptions
{
public HubConnectionContextOptions() { }
public System.TimeSpan ClientTimeoutInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public int StreamBufferCapacity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
}
public partial class HubConnectionHandler<THub> : Microsoft.AspNetCore.Connections.ConnectionHandler where THub : Microsoft.AspNetCore.SignalR.Hub
{
public HubConnectionHandler(Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub> lifetimeManager, Microsoft.AspNetCore.SignalR.IHubProtocolResolver protocolResolver, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.HubOptions> globalHubOptions, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.HubOptions<THub>> hubOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.SignalR.IUserIdProvider userIdProvider, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory) { }
Expand Down
32 changes: 6 additions & 26 deletions src/SignalR/server/Core/src/HubConnectionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,37 +48,17 @@ public class HubConnectionContext
/// Initializes a new instance of the <see cref="HubConnectionContext"/> class.
/// </summary>
/// <param name="connectionContext">The underlying <see cref="ConnectionContext"/>.</param>
/// <param name="keepAliveInterval">The keep alive interval. If no messages are sent by the server in this interval, a Ping message will be sent.</param>
/// <param name="loggerFactory">The logger factory.</param>
public HubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Should we keep the 2 old constructors so this isn't a breaking change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meh.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anurse Do we need to make an announcement?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure do!

: this(connectionContext, keepAliveInterval, loggerFactory, HubOptionsSetup.DefaultClientTimeoutInterval, HubOptionsSetup.DefaultStreamBufferCapacity) { }

/// <summary>
/// Initializes a new instance of the <see cref="HubConnectionContext"/> class.
/// </summary>
/// <param name="connectionContext">The underlying <see cref="ConnectionContext"/>.</param>
/// <param name="keepAliveInterval">The keep alive interval. If no messages are sent by the server in this interval, a Ping message will be sent.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="clientTimeoutInterval">Clients we haven't heard from in this interval are assumed to have disconnected.</param>
public HubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory, TimeSpan clientTimeoutInterval)
: this(connectionContext, keepAliveInterval, loggerFactory, clientTimeoutInterval, HubOptionsSetup.DefaultStreamBufferCapacity) { }

/// <summary>
/// Initializes a new instance of the <see cref="HubConnectionContext"/> class.
/// </summary>
/// <param name="connectionContext">The underlying <see cref="ConnectionContext"/>.</param>
/// <param name="keepAliveInterval">The keep alive interval. If no messages are sent by the server in this interval, a Ping message will be sent.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="clientTimeoutInterval">Clients we haven't heard from in this interval are assumed to have disconnected.</param>
/// <param name="streamBufferCapacity">The buffer size for client upload streams</param>
public HubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory, TimeSpan clientTimeoutInterval, int streamBufferCapacity)
/// <param name="contextOptions">The options to configure the HubConnectionContext.</param>
public HubConnectionContext(ConnectionContext connectionContext, HubConnectionContextOptions contextOptions, ILoggerFactory loggerFactory)
{
_keepAliveInterval = contextOptions.KeepAliveInterval.Ticks;
_clientTimeoutInterval = contextOptions.ClientTimeoutInterval.Ticks;
_streamBufferCapacity = contextOptions.StreamBufferCapacity;

_connectionContext = connectionContext;
_logger = loggerFactory.CreateLogger<HubConnectionContext>();
ConnectionAborted = _connectionAbortedTokenSource.Token;
_keepAliveInterval = keepAliveInterval.Ticks;
_clientTimeoutInterval = clientTimeoutInterval.Ticks;
_streamBufferCapacity = streamBufferCapacity;
}

internal StreamTracker StreamTracker
Expand Down
28 changes: 28 additions & 0 deletions src/SignalR/server/Core/src/HubConnectionContextOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

namespace Microsoft.AspNetCore.SignalR
{
/// <summary>
/// Options used to configure <see cref="HubConnectionContext"/>.
/// </summary>
public class HubConnectionContextOptions
{
/// <summary>
/// Gets or sets the interval used to send keep alive pings to connected clients.
/// </summary>
public TimeSpan KeepAliveInterval { get; set; }

/// <summary>
/// Gets or sets the time window clients have to send a message before the server closes the connection.
/// </summary>
public TimeSpan ClientTimeoutInterval { get; set; }

/// <summary>
/// Gets or sets the max buffer size for client upload streams.
/// </summary>
public int StreamBufferCapacity { get; set; }
}
}
22 changes: 13 additions & 9 deletions src/SignalR/server/Core/src/HubConnectionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.SignalR
Expand Down Expand Up @@ -75,21 +74,26 @@ IServiceScopeFactory serviceScopeFactory
public override async Task OnConnectedAsync(ConnectionContext connection)
{
// We check to see if HubOptions<THub> are set because those take precedence over global hub options.
// Then set the keepAlive and handshakeTimeout values to the defaults in HubOptionsSetup incase they were explicitly set to null.
var keepAlive = _hubOptions.KeepAliveInterval ?? _globalHubOptions.KeepAliveInterval ?? HubOptionsSetup.DefaultKeepAliveInterval;
var clientTimeout = _hubOptions.ClientTimeoutInterval ?? _globalHubOptions.ClientTimeoutInterval ?? HubOptionsSetup.DefaultClientTimeoutInterval;
var handshakeTimeout = _hubOptions.HandshakeTimeout ?? _globalHubOptions.HandshakeTimeout ?? HubOptionsSetup.DefaultHandshakeTimeout;
var streamBufferCapacity = _hubOptions.StreamBufferCapacity ?? _globalHubOptions.StreamBufferCapacity ?? HubOptionsSetup.DefaultStreamBufferCapacity;
var supportedProtocols = _hubOptions.SupportedProtocols ?? _globalHubOptions.SupportedProtocols;
// Then set the keepAlive and handshakeTimeout values to the defaults in HubOptionsSetup when they were explicitly set to null.

if (supportedProtocols != null && supportedProtocols.Count == 0)
var supportedProtocols = _hubOptions.SupportedProtocols ?? _globalHubOptions.SupportedProtocols;
if (supportedProtocols == null || supportedProtocols.Count == 0)
{
throw new InvalidOperationException("There are no supported protocols");
}

var handshakeTimeout = _hubOptions.HandshakeTimeout ?? _globalHubOptions.HandshakeTimeout ?? HubOptionsSetup.DefaultHandshakeTimeout;

var contextOptions = new HubConnectionContextOptions()
{
KeepAliveInterval = _hubOptions.KeepAliveInterval ?? _globalHubOptions.KeepAliveInterval ?? HubOptionsSetup.DefaultKeepAliveInterval,
ClientTimeoutInterval = _hubOptions.ClientTimeoutInterval ?? _globalHubOptions.ClientTimeoutInterval ?? HubOptionsSetup.DefaultClientTimeoutInterval,
StreamBufferCapacity = _hubOptions.StreamBufferCapacity ?? _globalHubOptions.StreamBufferCapacity ?? HubOptionsSetup.DefaultStreamBufferCapacity,
};

Log.ConnectedStarting(_logger);

var connectionContext = new HubConnectionContext(connection, keepAlive, _loggerFactory, clientTimeout, streamBufferCapacity);
var connectionContext = new HubConnectionContext(connection, contextOptions, _loggerFactory);

var resolvedSupportedProtocols = (supportedProtocols as IReadOnlyList<string>) ?? supportedProtocols.ToList();
if (!await connectionContext.HandshakeAsync(handshakeTimeout, resolvedSupportedProtocols, _protocolResolver, _userIdProvider, _enableDetailedErrors))
Expand Down
2 changes: 1 addition & 1 deletion src/SignalR/server/Core/src/HubOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class HubOptions
// for all available protocols.

/// <summary>
/// Gets or sets the interval used by the server to timeout incoming handshake requests by clients. The default timeout is 15 seconds
/// Gets or sets the interval used by the server to timeout incoming handshake requests by clients. The default timeout is 15 seconds.
/// </summary>
public TimeSpan? HandshakeTimeout { get; set; } = null;

Expand Down
Loading