-
Notifications
You must be signed in to change notification settings - Fork 10.3k
SignalR Stateful Reconnect API #49977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
API Review Notes:
We'll take a look at this again after we've made some of the suggested updates. |
Server APIs: namespace Microsoft.AspNetCore.Http.Connections;
public class HttpConnectionDispatcherOptions
{
+ public bool AllowStatefulReconnects { get; set; }
} namespace Microsoft.AspNetCore.SignalR;
public class HubOptions
{
+ public long StatefulReconnectBufferSize { get; set; } = 100_000;
} Client APIs: // TS Client
export interface IHttpConnectionOptions {
+ useStatefulReconnect?: boolean;
} // TS Client
export class HubConnectionBuilder {
+ public withStatefulReconnect(options?: StatefulReconnectOptions): HubConnectionBuilder;
}
+ export interface IStatefulReconnectOptions{
+ statefulReconnectBufferSize: number;
} namespace Microsoft.AspNetCore.Http.Connections.Client;
public class HttpConnectionOptions
{
+ public bool UseStatefulReconnect { get; set; }
} + public sealed class HubConnectionOptions
{
+ public long StatefulReconnectBufferSize { get; set; }
} namespace Microsoft.AspNetCore.SignalR.Client;
public static class HubConnectionBuilderHttpExtensions
{
+ public static IHubConnectionBuilder WithStatefulReconnect(this IHubConnectionBuilder hubConnectionBuilder, StatefulReconnectOptions? statefulReconnectOptions = null);
} namespace Microsoft.AspNetCore.SignalR.Client;
+ public sealed class StatefulReconnectOptions
{
+ public long StatefulReconnectBufferSize { get; set; }
} Common APIs: namespace Microsoft.AspNetCore.Http.Connections;
public class NegotiationResponse
{
+ public bool UseStatefulReconnect { get; set; }
} namespace Microsoft.AspNetCore.SignalR.Protocol;
public static class HubProtocolConstants
{
+ public const int AckMessageType = 8;
+ public const int SequenceMessageType = 9;
} namespace Microsoft.AspNetCore.SignalR.Protocol;
+ public sealed class AckMessage : HubMessage
{
+ public AckMessage(long sequenceId);
+ public long SequenceId { get; set; }
}
+ public sealed class SequenceMessage : HubMessage
{
+ public SequenceMessage(long sequenceId);
+ public long SequenceId { get; set; }
} namespace Microsoft.AspNetCore.Connections.Abstractions;
#if NET8_0_OR_GREATER
+ [RequiresPreviewFeatures("IStatefulReconnectFeature is a preview interface")]
#endif
+ public interface IStatefulReconnectFeature
{
+ public Action<PipeWriter> NotifyOnReconnect { get; set; }
+ void DisableReconnect();
} Usage Examples99% use case: // Client
var hubConnection = new HubConnectionBuilder()
.WithStatefulReconnect(new StatefulReconnectOptions() { StatefulReconnectBufferSize = 5000 })
.WithUrl("https://example.com")
.WithAutomaticReconnects()
.Build();
// Server
services.AddSignalR(o => o.StatefulReconnectBufferSize = 1500);
app.MapHub<MyHub>("/default", o => o.AllowStatefulReconnects = true); |
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
IStatefulReconnectFeature should be: public interface IStatefulReconnectFeature
{
public void OnReconnect(Action<PipeWriter> writer);
void DisableReconnect();
} Should it be |
StatefulReconnectOptions is missing in the API proposal. |
API Review Notes:
API Approved! Server APIs: namespace Microsoft.AspNetCore.Http.Connections;
public class HttpConnectionDispatcherOptions
{
+ public bool AllowStatefulReconnects { get; set; }
} namespace Microsoft.AspNetCore.SignalR;
public class HubOptions
{
+ public long StatefulReconnectBufferSize { get; set; } = 100_000;
} // TS Client
export class HubConnectionBuilder {
+ public withStatefulReconnect(options?: StatefulReconnectOptions): HubConnectionBuilder;
}
+ export interface IStatefulReconnectOptions {
+ bufferSize: number;
+ } namespace Microsoft.AspNetCore.Http.Connections.Client;
public class HttpConnectionOptions
{
+ public bool UseStatefulReconnect { get; set; }
} + public sealed class HubConnectionOptions
{
+ public long StatefulReconnectBufferSize { get; set; }
+ public TimeSpan ServerTimeout { get; set; }
+ public TimeSpan KeepAliveInterval { get; set; }
} namespace Microsoft.AspNetCore.SignalR.Client;
public static class HubConnectionBuilderHttpExtensions
{
+ public static IHubConnectionBuilder WithStatefulReconnect(this IHubConnectionBuilder hubConnectionBuilder);
} Common APIs: namespace Microsoft.AspNetCore.Http.Connections;
public class NegotiationResponse
{
+ public bool UseStatefulReconnect { get; set; }
} namespace Microsoft.AspNetCore.SignalR.Protocol;
public static class HubProtocolConstants
{
+ public const int AckMessageType = 8;
+ public const int SequenceMessageType = 9;
} namespace Microsoft.AspNetCore.SignalR.Protocol;
+ public sealed class AckMessage : HubMessage
{
+ public AckMessage(long sequenceId);
+ public long SequenceId { get; set; }
}
+ public sealed class SequenceMessage : HubMessage
{
+ public SequenceMessage(long sequenceId);
+ public long SequenceId { get; set; }
} namespace Microsoft.AspNetCore.Connections.Abstractions;
#if NET8_0_OR_GREATER
+ [RequiresPreviewFeatures("IStatefulReconnectFeature is a preview interface")]
#endif
+ public interface IStatefulReconnectFeature
{
+ public void OnReconnected(Func<PipeWriter, Task> notifyOnReconnect);
+ void DisableReconnect();
} |
Background and Motivation
These are the APIs to support SignalR Stateful Reconnect. The high level is; the low level connection layer needs to allow connections to reconnect, the high level SignalR layer needs to buffer and ack messages.
Proposed API
Server APIs:
namespace Microsoft.AspNetCore.Http.Connections; public class HttpConnectionDispatcherOptions { + public bool AllowReconnects { get; set; } }
namespace Microsoft.AspNetCore.SignalR; public class HubOptions { + public long MessageBufferSize { get; set; } = 100_000; }
namespace Microsoft.AspNetCore.SignalR; public class HubConnectionContextOptions { + public long MessageBufferSize { get; set; } = 100_000; }
Client APIs:
// TS Client export interface IHttpConnectionOptions { + useReconnects?: boolean; }
// TS Client export class HubConnectionBuilder { + public withMessageBufferSize(messageBufferSize: number): HubConnectionBuilder; }
namespace Microsoft.AspNetCore.Http.Connections.Client; public class HttpConnectionOptions { + public bool UseReconnects { get; set; } }
namespace Microsoft.AspNetCore.SignalR.Client; public static class HubConnectionBuilderExtensions { + public static IHubConnectionBuilder WithMessageBufferSize(this IHubConnectionBuilder hubConnectionBuilder, long messageBufferSize) }
Common APIs:
namespace Microsoft.AspNetCore.Http.Connections; public class NegotiationResponse { + public bool UseReconnects { get; set; } }
Usage Examples
99% use case:
Other use case:
Super rare use case:
Alternative Designs
AllowAcks
andUseAcks
are the current API, but that bleeds naming from the SignalR layer (where acks are used) to the connection layer.Risks
IReconnectFeature
is marked experimental because the interaction between the ConnectionHandler and SignalR layer is complex and we aren't sure this is the best way to communicate a reconnect occurred.MessageBufferSize
feels a bit generic. Additionally, we might add a limit on the number of messages (regardless of byte buffer limit) so naming could be very confusing with that limit too.UseReconnect
might want to be a number instead of bool to allow future changes, e.g. support long polling and sse. Also, this is a client API and it's asking to be allowed to use the reconnect feature, maybe the name should reflect that;NegotiateReconnect
The text was updated successfully, but these errors were encountered: