diff --git a/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs b/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs index c6e2878f2f..eeb1ede973 100644 --- a/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs +++ b/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs @@ -35,8 +35,19 @@ namespace Microsoft.AspNetCore.SignalR.Client /// public partial class HubConnection : IAsyncDisposable { + /// + /// The default timeout which specifies how long to wait for a message before closing the connection. Default is 30 seconds. + /// public static readonly TimeSpan DefaultServerTimeout = TimeSpan.FromSeconds(30); // Server ping rate is 15 sec, this is 2 times that. + + /// + /// The default timeout which specifies how long to wait for the handshake to respond before closing the connection. Default is 15 seconds. + /// public static readonly TimeSpan DefaultHandshakeTimeout = TimeSpan.FromSeconds(15); + + /// + /// The default interval that the client will send keep alive messages to let the server know to not close the connection. Default is 15 second interval. + /// public static readonly TimeSpan DefaultKeepAliveInterval = TimeSpan.FromSeconds(15); // This lock protects the connection state. diff --git a/src/SignalR/clients/csharp/Client.Core/src/HubConnectionBuilder.cs b/src/SignalR/clients/csharp/Client.Core/src/HubConnectionBuilder.cs index a63f6c9a80..2eb2641dd2 100644 --- a/src/SignalR/clients/csharp/Client.Core/src/HubConnectionBuilder.cs +++ b/src/SignalR/clients/csharp/Client.Core/src/HubConnectionBuilder.cs @@ -80,6 +80,9 @@ namespace Microsoft.AspNetCore.SignalR.Client } // Prevents from being displayed in intellisense + /// + /// Gets the of the current instance. + /// [EditorBrowsable(EditorBrowsableState.Never)] public new Type GetType() { diff --git a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj index 504f2e4549..127e14f180 100644 --- a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj +++ b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj @@ -4,6 +4,7 @@ Client for ASP.NET Core SignalR $(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1 Microsoft.AspNetCore.SignalR.Client + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj b/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj index 47444465b4..dc5ad7348f 100644 --- a/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj +++ b/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj @@ -1,8 +1,9 @@ - + Client for ASP.NET Core SignalR $(DefaultNetFxTargetFramework);netstandard2.0 + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj b/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj index bae3bab800..789795e1bd 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj @@ -1,8 +1,9 @@ - + Client for ASP.NET Core Connection Handlers $(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1 + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/NoTransportSupportedException.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/NoTransportSupportedException.cs index 9009ac3c03..8b72127916 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/NoTransportSupportedException.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/NoTransportSupportedException.cs @@ -10,6 +10,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Client /// public class NoTransportSupportedException : Exception { + /// + /// Constructs the exception with the provided . + /// + /// Message of the exception. public NoTransportSupportedException(string message) : base(message) { diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/TransportFailedException.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/TransportFailedException.cs index 4de0804637..b12e7e2173 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/TransportFailedException.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/TransportFailedException.cs @@ -10,8 +10,17 @@ namespace Microsoft.AspNetCore.Http.Connections.Client /// public class TransportFailedException : Exception { + /// + /// The name of the transport that failed to connect. + /// public string TransportType { get; } + /// + /// Constructs a . + /// + /// The name of the transport that failed to connect. + /// The reason the transport failed. + /// An optional extra exception if one was thrown while trying to connect. public TransportFailedException(string transportType, string message, Exception innerException = null) : base($"{transportType} failed: {message}", innerException) { diff --git a/src/SignalR/common/Http.Connections.Common/src/AvailableTransport.cs b/src/SignalR/common/Http.Connections.Common/src/AvailableTransport.cs index 92d5fe16b4..ec186fac25 100644 --- a/src/SignalR/common/Http.Connections.Common/src/AvailableTransport.cs +++ b/src/SignalR/common/Http.Connections.Common/src/AvailableTransport.cs @@ -5,9 +5,19 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.Http.Connections { + /// + /// Part of the that represents an individual transport and the trasfer formats the transport supports. + /// public class AvailableTransport { + /// + /// A transport available on the server. + /// public string Transport { get; set; } + + /// + /// A list of formats supported by the transport. Examples include "Text" and "Binary". + /// public IList TransferFormats { get; set; } } } diff --git a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj index 02f97edfb6..7ea14568e6 100644 --- a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj +++ b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj @@ -7,6 +7,7 @@ true Microsoft.AspNetCore.Http.Connections true + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs b/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs index ae69b56cdd..fb022eef54 100644 --- a/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs +++ b/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs @@ -11,6 +11,9 @@ using Microsoft.AspNetCore.Internal; namespace Microsoft.AspNetCore.Http.Connections { + /// + /// The protocol for reading and writing negotiate requests and responses. + /// public static class NegotiateProtocol { private const string ConnectionIdPropertyName = "connectionId"; @@ -36,6 +39,11 @@ namespace Microsoft.AspNetCore.Http.Connections // Used to detect ASP.NET SignalR Server connection attempt private static ReadOnlySpan ProtocolVersionPropertyNameBytes => new byte[] { (byte)'P', (byte)'r', (byte)'o', (byte)'t', (byte)'o', (byte)'c', (byte)'o', (byte)'l', (byte)'V', (byte)'e', (byte)'r', (byte)'s', (byte)'i', (byte)'o', (byte)'n' }; + /// + /// Writes the to the . + /// + /// The negotiation response generated in response to a negotiation request. + /// Where the is written to as Json. public static void WriteResponse(NegotiationResponse response, IBufferWriter output) { var reusableWriter = ReusableUtf8JsonWriter.Get(output); @@ -124,6 +132,11 @@ namespace Microsoft.AspNetCore.Http.Connections } } + /// + /// Parses a from the as Json. + /// + /// The bytes of a Json payload that represents a . + /// The parsed . public static NegotiationResponse ParseResponse(ReadOnlySpan content) { try diff --git a/src/SignalR/common/Http.Connections.Common/src/NegotiationResponse.cs b/src/SignalR/common/Http.Connections.Common/src/NegotiationResponse.cs index 69810a5a71..a972e68d4e 100644 --- a/src/SignalR/common/Http.Connections.Common/src/NegotiationResponse.cs +++ b/src/SignalR/common/Http.Connections.Common/src/NegotiationResponse.cs @@ -5,14 +5,44 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.Http.Connections { + /// + /// A response to a '/negotiate' request. + /// public class NegotiationResponse { + /// + /// An optional Url to redirect the client to another endpoint. + /// public string Url { get; set; } + + /// + /// An optional access token to go along with the Url. + /// public string AccessToken { get; set; } + + /// + /// The public ID for the connection. + /// public string ConnectionId { get; set; } + + /// + /// The private ID for the connection. + /// public string ConnectionToken { get; set; } + + /// + /// The minimum value between the version the client sends and the maximum version the server supports. + /// public int Version { get; set; } + + /// + /// A list of transports the server supports. + /// public IList AvailableTransports { get; set; } + + /// + /// An optional error during the negotiate. If this is not null the other properties on the response can be ignored. + /// public string Error { get; set; } } } diff --git a/src/SignalR/common/Http.Connections/src/ConnectionEndpointRouteBuilderExtensions.cs b/src/SignalR/common/Http.Connections/src/ConnectionEndpointRouteBuilderExtensions.cs index d9a34035a9..f473cb57bc 100644 --- a/src/SignalR/common/Http.Connections/src/ConnectionEndpointRouteBuilderExtensions.cs +++ b/src/SignalR/common/Http.Connections/src/ConnectionEndpointRouteBuilderExtensions.cs @@ -11,6 +11,9 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Builder { + /// + /// Extension methods on that add routes for s. + /// public static class ConnectionEndpointRouteBuilderExtensions { /// diff --git a/src/SignalR/common/Http.Connections/src/ConnectionOptions.cs b/src/SignalR/common/Http.Connections/src/ConnectionOptions.cs index 657e51938c..90666b4237 100644 --- a/src/SignalR/common/Http.Connections/src/ConnectionOptions.cs +++ b/src/SignalR/common/Http.Connections/src/ConnectionOptions.cs @@ -5,6 +5,9 @@ using System; namespace Microsoft.AspNetCore.Http.Connections { + /// + /// Options used to change behavior of how connections are handled. + /// public class ConnectionOptions { /// diff --git a/src/SignalR/common/Http.Connections/src/ConnectionOptionsSetup.cs b/src/SignalR/common/Http.Connections/src/ConnectionOptionsSetup.cs index 13437aea93..abc1e5ded1 100644 --- a/src/SignalR/common/Http.Connections/src/ConnectionOptionsSetup.cs +++ b/src/SignalR/common/Http.Connections/src/ConnectionOptionsSetup.cs @@ -6,10 +6,20 @@ using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Http.Connections { + /// + /// Sets up . + /// public class ConnectionOptionsSetup : IConfigureOptions { + /// + /// Default timeout value for disconnecting idle connections. + /// public static TimeSpan DefaultDisconectTimeout = TimeSpan.FromSeconds(15); + /// + /// Sets default values for options if they have not been set yet. + /// + /// The . public void Configure(ConnectionOptions options) { if (options.DisconnectTimeout == null) diff --git a/src/SignalR/common/Http.Connections/src/Features/IHttpContextFeature.cs b/src/SignalR/common/Http.Connections/src/Features/IHttpContextFeature.cs index 70c4d9e854..6cd915a3a8 100644 --- a/src/SignalR/common/Http.Connections/src/Features/IHttpContextFeature.cs +++ b/src/SignalR/common/Http.Connections/src/Features/IHttpContextFeature.cs @@ -1,15 +1,27 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; using System.Collections.Generic; using System.Text; +using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Http.Connections.Features { + /// + /// Feature set on the that provides access to the underlying + /// associated with the connection if there is one. + /// public interface IHttpContextFeature { + /// + /// The associated with the connection if available. + /// + /// + /// Connections can run on top of HTTP transports like WebSockets or Long Polling, or other non-HTTP transports. As a result, + /// this API can sometimes return depending on the configuration of your application. + /// HttpContext HttpContext { get; set; } } } diff --git a/src/SignalR/common/Http.Connections/src/Features/IHttpTransportFeature.cs b/src/SignalR/common/Http.Connections/src/Features/IHttpTransportFeature.cs index 47354f1013..24116ed2e9 100644 --- a/src/SignalR/common/Http.Connections/src/Features/IHttpTransportFeature.cs +++ b/src/SignalR/common/Http.Connections/src/Features/IHttpTransportFeature.cs @@ -4,12 +4,20 @@ using System; using System.Collections.Generic; using System.Text; +using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Http.Connections.Features { + /// + /// Feature set on the that exposes the + /// the connection is using. + /// public interface IHttpTransportFeature { + /// + /// The the connection is using. + /// HttpTransportType TransportType { get; } } } diff --git a/src/SignalR/common/Http.Connections/src/HttpConnectionContextExtensions.cs b/src/SignalR/common/Http.Connections/src/HttpConnectionContextExtensions.cs index 2b31aee59f..35042c1ffb 100644 --- a/src/SignalR/common/Http.Connections/src/HttpConnectionContextExtensions.cs +++ b/src/SignalR/common/Http.Connections/src/HttpConnectionContextExtensions.cs @@ -7,6 +7,9 @@ using Microsoft.AspNetCore.Http.Connections.Features; namespace Microsoft.AspNetCore.Http.Connections { + /// + /// Extension method to get the underlying of the connection if there is one. + /// public static class HttpConnectionContextExtensions { /// diff --git a/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj b/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj index a6224d57a4..90822b54f4 100644 --- a/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj +++ b/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj @@ -6,6 +6,7 @@ true false enable + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/common/Http.Connections/src/WebSocketOptions.cs b/src/SignalR/common/Http.Connections/src/WebSocketOptions.cs index 8cac4f12f0..c45c512c4d 100644 --- a/src/SignalR/common/Http.Connections/src/WebSocketOptions.cs +++ b/src/SignalR/common/Http.Connections/src/WebSocketOptions.cs @@ -6,8 +6,15 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.Http.Connections { + /// + /// Options used by the WebSockets transport to modify the transports behavior. + /// public class WebSocketOptions { + /// + /// Gets or sets the amount of time the WebSocket transport will wait for a graceful close before starting an ungraceful close. + /// + /// Defaults to 5 seconds public TimeSpan CloseTimeout { get; set; } = TimeSpan.FromSeconds(5); /// diff --git a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj index cae05aae11..4fe4b8d1c9 100644 --- a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj +++ b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj @@ -8,6 +8,7 @@ Microsoft.AspNetCore.SignalR true enable + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/common/Protocols.MessagePack/src/MessagePackHubProtocolOptions.cs b/src/SignalR/common/Protocols.MessagePack/src/MessagePackHubProtocolOptions.cs index eec0355405..9248339377 100644 --- a/src/SignalR/common/Protocols.MessagePack/src/MessagePackHubProtocolOptions.cs +++ b/src/SignalR/common/Protocols.MessagePack/src/MessagePackHubProtocolOptions.cs @@ -6,6 +6,9 @@ using Microsoft.AspNetCore.SignalR.Protocol; namespace Microsoft.AspNetCore.SignalR { + /// + /// The options. + /// public class MessagePackHubProtocolOptions { private MessagePackSerializerOptions? _messagePackSerializerOptions; diff --git a/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj b/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj index 8ed07be5dc..d5b01827b2 100644 --- a/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj +++ b/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj @@ -6,6 +6,7 @@ Microsoft.AspNetCore.SignalR true enable + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj b/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj index 00e59a9cee..2ada9198c2 100644 --- a/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj +++ b/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj @@ -6,6 +6,7 @@ Microsoft.AspNetCore.SignalR true enable + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/common/SignalR.Common/src/IInvocationBinder.cs b/src/SignalR/common/SignalR.Common/src/IInvocationBinder.cs index 2f1ba139c3..fd5fe245a3 100644 --- a/src/SignalR/common/SignalR.Common/src/IInvocationBinder.cs +++ b/src/SignalR/common/SignalR.Common/src/IInvocationBinder.cs @@ -3,13 +3,34 @@ using System; using System.Collections.Generic; +using Microsoft.AspNetCore.SignalR.Protocol; namespace Microsoft.AspNetCore.SignalR { + /// + /// Class used by s to get the (s) expected by the hub message being deserialized. + /// public interface IInvocationBinder { + /// + /// Gets the the invocation represented by the is expected to contain. + /// + /// The ID of the invocation being received. + /// The the invocation is expected to contain. Type GetReturnType(string invocationId); + + /// + /// Gets the list of s the method represented by takes as arguments. + /// + /// The name of the method being called. + /// A list of s the method takes as arguments. IReadOnlyList GetParameterTypes(string methodName); + + /// + /// Gets the the stream item is expected to contain. + /// + /// The ID of the stream the stream item is a part of. + /// The of the item the stream contains. Type GetStreamItemType(string streamId); } } diff --git a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj index 1206aeed68..9840623be7 100644 --- a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj +++ b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj @@ -8,6 +8,7 @@ Microsoft.AspNetCore.SignalR true enable + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/common/SignalR.Common/src/Protocol/CancelInvocationMessage.cs b/src/SignalR/common/SignalR.Common/src/Protocol/CancelInvocationMessage.cs index 25cd504096..3d5723c443 100644 --- a/src/SignalR/common/SignalR.Common/src/Protocol/CancelInvocationMessage.cs +++ b/src/SignalR/common/SignalR.Common/src/Protocol/CancelInvocationMessage.cs @@ -5,8 +5,15 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.SignalR.Protocol { + /// + /// The represents a cancellation of a streaming method. + /// public class CancelInvocationMessage : HubInvocationMessage { + /// + /// Initializes a new instance of the class. + /// + /// The ID of the hub method invocation being canceled. public CancelInvocationMessage(string invocationId) : base(invocationId) { } diff --git a/src/SignalR/common/SignalR.Common/src/Protocol/CompletionMessage.cs b/src/SignalR/common/SignalR.Common/src/Protocol/CompletionMessage.cs index 797e0f6dfe..1471f894dc 100644 --- a/src/SignalR/common/SignalR.Common/src/Protocol/CompletionMessage.cs +++ b/src/SignalR/common/SignalR.Common/src/Protocol/CompletionMessage.cs @@ -5,12 +5,34 @@ using System; namespace Microsoft.AspNetCore.SignalR.Protocol { + /// + /// Represents an invocation that has completed. If there is an error then the invocation didn't complete successfully. + /// public class CompletionMessage : HubInvocationMessage { + /// + /// Optional error message if the invocation wasn't completed successfully. This must be null if there is a result. + /// public string? Error { get; } + + /// + /// Optional result from the invocation. This must be null if there is an error. + /// This can also be null if there wasn't a result from the method invocation. + /// public object? Result { get; } + + /// + /// Specifies whether the completion contains a result. + /// public bool HasResult { get; } + /// + /// Constructs a . + /// + /// The ID of the invocation that has completed. + /// An optional error if the invocation failed. + /// An optional result if the invocation returns a result. + /// Specifies whether the completion contains a result. public CompletionMessage(string invocationId, string? error, object? result, bool hasResult) : base(invocationId) { @@ -24,6 +46,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol HasResult = hasResult; } + /// public override string ToString() { var errorStr = Error == null ? "<>" : $"\"{Error}\""; @@ -33,12 +56,30 @@ namespace Microsoft.AspNetCore.SignalR.Protocol // Static factory methods. Don't want to use constructor overloading because it will break down // if you need to send a payload statically-typed as a string. And because a static factory is clearer here + /// + /// Constructs a with an error. + /// + /// The ID of the invocation that is being completed. + /// The error that occurred during the invocation. + /// The constructed . public static CompletionMessage WithError(string invocationId, string error) => new CompletionMessage(invocationId, error, result: null, hasResult: false); + /// + /// Constructs a with a result. + /// + /// The ID of the invocation that is being completed. + /// The result from the invocation. + /// The constructed . public static CompletionMessage WithResult(string invocationId, object payload) => new CompletionMessage(invocationId, error: null, result: payload, hasResult: true); + /// + /// Constructs a without an error or result. + /// This means the invocation was successful but there is no return value. + /// + /// The ID of the invocation that is being completed. + /// The constructed . public static CompletionMessage Empty(string invocationId) => new CompletionMessage(invocationId, error: null, result: null, hasResult: false); } diff --git a/src/SignalR/common/SignalR.Common/src/Protocol/HandshakeProtocol.cs b/src/SignalR/common/SignalR.Common/src/Protocol/HandshakeProtocol.cs index 6a303a445b..10405f85dc 100644 --- a/src/SignalR/common/SignalR.Common/src/Protocol/HandshakeProtocol.cs +++ b/src/SignalR/common/SignalR.Common/src/Protocol/HandshakeProtocol.cs @@ -43,6 +43,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol } } + /// + /// Gets the bytes of a successful handshake message. + /// + /// The protocol being used for the connection. + /// The bytes of a successful handshake message. public static ReadOnlySpan GetSuccessfulHandshake(IHubProtocol protocol) => _successHandshakeData.Span; /// diff --git a/src/SignalR/common/SignalR.Common/src/Protocol/PingMessage.cs b/src/SignalR/common/SignalR.Common/src/Protocol/PingMessage.cs index 63a21bb14c..18397eee6c 100644 --- a/src/SignalR/common/SignalR.Common/src/Protocol/PingMessage.cs +++ b/src/SignalR/common/SignalR.Common/src/Protocol/PingMessage.cs @@ -3,8 +3,14 @@ namespace Microsoft.AspNetCore.SignalR.Protocol { + /// + /// A keep-alive message to let the other side of the connection know that the connection is still alive. + /// public class PingMessage : HubMessage { + /// + /// A static instance of the PingMessage to remove unneeded allocations. + /// public static readonly PingMessage Instance = new PingMessage(); private PingMessage() diff --git a/src/SignalR/common/SignalR.Common/src/Protocol/StreamItemMessage.cs b/src/SignalR/common/SignalR.Common/src/Protocol/StreamItemMessage.cs index c518622b0a..7afe364fc7 100644 --- a/src/SignalR/common/SignalR.Common/src/Protocol/StreamItemMessage.cs +++ b/src/SignalR/common/SignalR.Common/src/Protocol/StreamItemMessage.cs @@ -3,15 +3,27 @@ namespace Microsoft.AspNetCore.SignalR.Protocol { + /// + /// Represents a single item of an active stream. + /// public class StreamItemMessage : HubInvocationMessage { + /// + /// The single item from a stream. + /// public object? Item { get; } + /// + /// Constructs a . + /// + /// The ID of the stream. + /// An item from the stream. public StreamItemMessage(string invocationId, object? item) : base(invocationId) { Item = item; } + /// public override string ToString() { return $"StreamItem {{ {nameof(InvocationId)}: \"{InvocationId}\", {nameof(Item)}: {Item ?? "<>"} }}"; diff --git a/src/SignalR/server/Core/src/HubConnectionContext.cs b/src/SignalR/server/Core/src/HubConnectionContext.cs index 08913ae139..83604230d8 100644 --- a/src/SignalR/server/Core/src/HubConnectionContext.cs +++ b/src/SignalR/server/Core/src/HubConnectionContext.cs @@ -147,6 +147,12 @@ namespace Microsoft.AspNetCore.SignalR // Currently used only for streaming methods internal ConcurrentDictionary ActiveRequestCancellationSources { get; } = new ConcurrentDictionary(StringComparer.Ordinal); + /// + /// Write a to the connection. + /// + /// The being written. + /// Cancels the in progress write. + /// A that represents the completion of the write. If the write throws this task will still complete successfully. [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")] public virtual ValueTask WriteAsync(HubMessage message, CancellationToken cancellationToken = default) { diff --git a/src/SignalR/server/Core/src/HubConnectionStore.cs b/src/SignalR/server/Core/src/HubConnectionStore.cs index 9457d0e361..2573d86862 100644 --- a/src/SignalR/server/Core/src/HubConnectionStore.cs +++ b/src/SignalR/server/Core/src/HubConnectionStore.cs @@ -8,11 +8,22 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.SignalR { + /// + /// Stores s by ID. + /// + /// + /// This API is meant for internal usage. + /// public class HubConnectionStore { private readonly ConcurrentDictionary _connections = new ConcurrentDictionary(StringComparer.Ordinal); + /// + /// Get the by connection ID. + /// + /// The ID of the connection. + /// The connection for the , null if there is no connection. public HubConnectionContext? this[string connectionId] { get @@ -22,40 +33,75 @@ namespace Microsoft.AspNetCore.SignalR } } + /// + /// The number of connections in the store. + /// public int Count => _connections.Count; + /// + /// Add a to the store. + /// + /// The connection to add. public void Add(HubConnectionContext connection) { _connections.TryAdd(connection.ConnectionId, connection); } + /// + /// Removes a from the store. + /// + /// The connection to remove. public void Remove(HubConnectionContext connection) { _connections.TryRemove(connection.ConnectionId, out _); } + /// + /// Gets an enumerator over the connection store. + /// + /// The over the connections. public Enumerator GetEnumerator() { return new Enumerator(this); } + /// + /// An over the + /// public readonly struct Enumerator : IEnumerator { private readonly IEnumerator> _enumerator; + /// + /// Constructs the over the . + /// + /// The store of connections to enumerate over. public Enumerator(HubConnectionStore hubConnectionList) { _enumerator = hubConnectionList._connections.GetEnumerator(); } + /// + /// The current connection the enumerator is on. + /// public HubConnectionContext Current => _enumerator.Current.Value; object IEnumerator.Current => Current; + /// + /// Disposes the enumerator. + /// public void Dispose() => _enumerator.Dispose(); + /// + /// Moves the enumerator to the next value. + /// + /// True if there is another connection. False if there are no more connections. public bool MoveNext() => _enumerator.MoveNext(); + /// + /// Resets the enumerator to the beginning. + /// public void Reset() => _enumerator.Reset(); } } diff --git a/src/SignalR/server/Core/src/HubMetadata.cs b/src/SignalR/server/Core/src/HubMetadata.cs index 65c6fa9e21..6d44b876db 100644 --- a/src/SignalR/server/Core/src/HubMetadata.cs +++ b/src/SignalR/server/Core/src/HubMetadata.cs @@ -10,6 +10,10 @@ namespace Microsoft.AspNetCore.SignalR /// public class HubMetadata { + /// + /// Constructs the of the given type. + /// + /// The of the . public HubMetadata(Type hubType) { HubType = hubType; diff --git a/src/SignalR/server/Core/src/HubOptionsSetup.cs b/src/SignalR/server/Core/src/HubOptionsSetup.cs index c41fd8fb49..9a1ea32991 100644 --- a/src/SignalR/server/Core/src/HubOptionsSetup.cs +++ b/src/SignalR/server/Core/src/HubOptionsSetup.cs @@ -9,6 +9,9 @@ using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.SignalR { + /// + /// Class to configure the . + /// public class HubOptionsSetup : IConfigureOptions { internal static TimeSpan DefaultHandshakeTimeout => TimeSpan.FromSeconds(15); @@ -23,6 +26,10 @@ namespace Microsoft.AspNetCore.SignalR private readonly List _defaultProtocols = new List(); + /// + /// Constructs the with a list of protocols added to Dependency Injection. + /// + /// The list of s that are from Dependency Injection. public HubOptionsSetup(IEnumerable protocols) { foreach (var hubProtocol in protocols) @@ -35,6 +42,10 @@ namespace Microsoft.AspNetCore.SignalR } } + /// + /// Configures the default values of the . + /// + /// The to configure. public void Configure(HubOptions options) { if (options.KeepAliveInterval == null) diff --git a/src/SignalR/server/Core/src/HubOptionsSetup`T.cs b/src/SignalR/server/Core/src/HubOptionsSetup`T.cs index 1dfae3de0c..9936f0e632 100644 --- a/src/SignalR/server/Core/src/HubOptionsSetup`T.cs +++ b/src/SignalR/server/Core/src/HubOptionsSetup`T.cs @@ -7,14 +7,27 @@ using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.SignalR { + /// + /// Class to configure the for a specific . + /// + /// The type to configure. public class HubOptionsSetup : IConfigureOptions> where THub : Hub { private readonly HubOptions _hubOptions; + + /// + /// Constructs the options configuration class. + /// + /// The global from Dependency Injection. public HubOptionsSetup(IOptions options) { _hubOptions = options.Value; } + /// + /// Configures the default values of the . + /// + /// The options to configure. public void Configure(HubOptions options) { // Do a deep copy, otherwise users modifying the HubOptions list would be changing the global options list diff --git a/src/SignalR/server/Core/src/Microsoft.AspNetCore.SignalR.Core.csproj b/src/SignalR/server/Core/src/Microsoft.AspNetCore.SignalR.Core.csproj index c5ae1cb371..bbf199bae3 100644 --- a/src/SignalR/server/Core/src/Microsoft.AspNetCore.SignalR.Core.csproj +++ b/src/SignalR/server/Core/src/Microsoft.AspNetCore.SignalR.Core.csproj @@ -7,6 +7,7 @@ Microsoft.AspNetCore.SignalR false enable + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/server/SignalR/src/HubEndpointRouteBuilderExtensions.cs b/src/SignalR/server/SignalR/src/HubEndpointRouteBuilderExtensions.cs index 3ac90b36f0..ac7802e56c 100644 --- a/src/SignalR/server/SignalR/src/HubEndpointRouteBuilderExtensions.cs +++ b/src/SignalR/server/SignalR/src/HubEndpointRouteBuilderExtensions.cs @@ -10,6 +10,9 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Builder { + /// + /// Extension methods on to add routes to s. + /// public static class HubEndpointRouteBuilderExtensions { private const DynamicallyAccessedMemberTypes HubAccessibility = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods; diff --git a/src/SignalR/server/SignalR/src/Microsoft.AspNetCore.SignalR.csproj b/src/SignalR/server/SignalR/src/Microsoft.AspNetCore.SignalR.csproj index 1f69a61ddc..d7680bd527 100644 --- a/src/SignalR/server/SignalR/src/Microsoft.AspNetCore.SignalR.csproj +++ b/src/SignalR/server/SignalR/src/Microsoft.AspNetCore.SignalR.csproj @@ -4,6 +4,7 @@ $(DefaultNetCoreTargetFramework) true false + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/server/StackExchangeRedis/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj b/src/SignalR/server/StackExchangeRedis/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj index 562720dfb1..739eb1ed9e 100644 --- a/src/SignalR/server/StackExchangeRedis/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj +++ b/src/SignalR/server/StackExchangeRedis/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj @@ -1,8 +1,9 @@ - + Provides scale-out support for ASP.NET Core SignalR using a Redis server and the StackExchange.Redis client. $(DefaultNetCoreTargetFramework) + $(NoWarn.Replace('1591', '')) diff --git a/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs b/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs index b2e5b1f8fb..5e9e76ec76 100644 --- a/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs +++ b/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs @@ -17,6 +17,10 @@ using StackExchange.Redis; namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis { + /// + /// The Redis scaleout provider for multi-server support. + /// + /// The type of to manage connections for. public class RedisHubLifetimeManager : HubLifetimeManager, IDisposable where THub : Hub { private readonly HubConnectionStore _connections = new HubConnectionStore(); @@ -34,6 +38,12 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis private readonly AckHandler _ackHandler; private int _internalId; + /// + /// Constructs the with types from Dependency Injection. + /// + /// The logger to write information about what the class is doing. + /// The that influence behavior of the Redis connection. + /// The to get an instance when writing to connections. public RedisHubLifetimeManager(ILogger> logger, IOptions options, IHubProtocolResolver hubProtocolResolver) @@ -41,6 +51,14 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis { } + /// + /// Constructs the with types from Dependency Injection. + /// + /// The logger to write information about what the class is doing. + /// The that influence behavior of the Redis connection. + /// The to get an instance when writing to connections. + /// The global . + /// The specific options. public RedisHubLifetimeManager(ILogger> logger, IOptions options, IHubProtocolResolver hubProtocolResolver, @@ -65,6 +83,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis _ = EnsureRedisServerConnection(); } + /// public override async Task OnConnectedAsync(HubConnectionContext connection) { await EnsureRedisServerConnection(); @@ -86,6 +105,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis await Task.WhenAll(connectionTask, userTask); } + /// public override Task OnDisconnectedAsync(HubConnectionContext connection) { _connections.Remove(connection); @@ -119,18 +139,21 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return Task.WhenAll(tasks); } + /// public override Task SendAllAsync(string methodName, object[] args, CancellationToken cancellationToken = default) { var message = _protocol.WriteInvocation(methodName, args); return PublishAsync(_channels.All, message); } + /// public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList excludedConnectionIds, CancellationToken cancellationToken = default) { var message = _protocol.WriteInvocation(methodName, args, excludedConnectionIds); return PublishAsync(_channels.All, message); } + /// public override Task SendConnectionAsync(string connectionId, string methodName, object[] args, CancellationToken cancellationToken = default) { if (connectionId == null) @@ -150,6 +173,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return PublishAsync(_channels.Connection(connectionId), message); } + /// public override Task SendGroupAsync(string groupName, string methodName, object[] args, CancellationToken cancellationToken = default) { if (groupName == null) @@ -161,6 +185,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return PublishAsync(_channels.Group(groupName), message); } + /// public override Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList excludedConnectionIds, CancellationToken cancellationToken = default) { if (groupName == null) @@ -172,12 +197,14 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return PublishAsync(_channels.Group(groupName), message); } + /// public override Task SendUserAsync(string userId, string methodName, object[] args, CancellationToken cancellationToken = default) { var message = _protocol.WriteInvocation(methodName, args); return PublishAsync(_channels.User(userId), message); } + /// public override Task AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default) { if (connectionId == null) @@ -200,6 +227,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Add); } + /// public override Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default) { if (connectionId == null) @@ -222,6 +250,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Remove); } + /// public override Task SendConnectionsAsync(IReadOnlyList connectionIds, string methodName, object[] args, CancellationToken cancellationToken = default) { if (connectionIds == null) @@ -240,6 +269,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return Task.WhenAll(publishTasks); } + /// public override Task SendGroupsAsync(IReadOnlyList groupNames, string methodName, object[] args, CancellationToken cancellationToken = default) { if (groupNames == null) @@ -260,6 +290,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis return Task.WhenAll(publishTasks); } + /// public override Task SendUsersAsync(IReadOnlyList userIds, string methodName, object[] args, CancellationToken cancellationToken = default) { if (userIds.Count > 0) @@ -352,6 +383,9 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis }); } + /// + /// Cleans up the Redis connection. + /// public void Dispose() { _bus?.UnsubscribeAll();