Brennan пре 5 година
родитељ
комит
46359cd0a2
100 измењених фајлова са 1405 додато и 918 уклоњено
  1. 2 1
      eng/targets/CSharp.Common.targets
  2. 1 1
      src/Components/Ignitor/src/BlazorClient.cs
  3. 76 76
      src/SignalR/clients/csharp/Client.Core/src/HubConnection.Log.cs
  4. 82 82
      src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs
  5. 3 3
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionBuilder.cs
  6. 12 12
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.InvokeAsync.cs
  7. 12 12
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.InvokeAsyncGeneric.cs
  8. 10 10
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.SendAsync.cs
  9. 12 12
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.StreamAsChannelAsync.cs
  10. 10 12
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.StreamAsync.cs
  11. 20 20
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.cs
  12. 7 7
      src/SignalR/clients/csharp/Client.Core/src/Internal/ConnectionLogScope.cs
  13. 16 16
      src/SignalR/clients/csharp/Client.Core/src/Internal/InvocationRequest.cs
  14. 1 0
      src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj
  15. 208 0
      src/SignalR/clients/csharp/Client.Core/src/PublicAPI.Unshipped.txt
  16. 1 1
      src/SignalR/clients/csharp/Client.Core/src/RetryContext.cs
  17. 2 2
      src/SignalR/clients/csharp/Client/src/HubConnectionBuilderHttpExtensions.cs
  18. 1 0
      src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj
  19. 16 0
      src/SignalR/clients/csharp/Client/src/PublicAPI.Unshipped.txt
  20. 16 17
      src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.Log.cs
  21. 27 23
      src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
  22. 0 1
      src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs
  23. 11 12
      src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs
  24. 7 8
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ConnectionLogScope.cs
  25. 1 1
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Constants.cs
  26. 5 5
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/DefaultTransportFactory.cs
  27. 4 4
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LoggingHttpMessageHandler.cs
  28. 13 13
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.Log.cs
  29. 14 11
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.cs
  30. 7 7
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/SendUtils.cs
  31. 2 1
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsMessageParser.cs
  32. 10 10
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsTransport.Log.cs
  33. 18 13
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsTransport.cs
  34. 19 20
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.Log.cs
  35. 17 11
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
  36. 1 0
      src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj
  37. 72 0
      src/SignalR/clients/csharp/Http.Connections.Client/src/PublicAPI.Unshipped.txt
  38. 1 1
      src/SignalR/clients/csharp/Http.Connections.Client/src/TransportFailedException.cs
  39. 2 2
      src/SignalR/common/Http.Connections.Common/src/AvailableTransport.cs
  40. 1 0
      src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj
  41. 7 7
      src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs
  42. 6 6
      src/SignalR/common/Http.Connections.Common/src/NegotiationResponse.cs
  43. 36 0
      src/SignalR/common/Http.Connections.Common/src/PublicAPI.Unshipped.txt
  44. 2 6
      src/SignalR/common/Http.Connections/src/Features/IHttpContextFeature.cs
  45. 8 10
      src/SignalR/common/Http.Connections/src/Internal/ConnectionLogScope.cs
  46. 36 42
      src/SignalR/common/Http.Connections/src/Internal/HttpConnectionContext.cs
  47. 16 18
      src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs
  48. 1 3
      src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs
  49. 6 8
      src/SignalR/common/Http.Connections/src/Internal/HttpConnectionsEventSource.cs
  50. 2 0
      src/SignalR/common/Http.Connections/src/PublicAPI.Unshipped.txt
  51. 19 65
      src/SignalR/common/Http.Connections/test/WebSocketsTests.cs
  52. 55 32
      src/SignalR/common/Protocols.Json/src/Protocol/JsonHubProtocol.cs
  53. 10 0
      src/SignalR/common/Protocols.Json/src/PublicAPI.Unshipped.txt
  54. 4 5
      src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocol.cs
  55. 3 2
      src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocolWorker.cs
  56. 10 0
      src/SignalR/common/Protocols.MessagePack/src/PublicAPI.Unshipped.txt
  57. 61 36
      src/SignalR/common/Protocols.NewtonsoftJson/src/Protocol/NewtonsoftJsonHubProtocol.cs
  58. 12 0
      src/SignalR/common/Protocols.NewtonsoftJson/src/PublicAPI.Unshipped.txt
  59. 9 11
      src/SignalR/common/Shared/AsyncEnumerableAdapters.cs
  60. 14 6
      src/SignalR/common/Shared/MemoryBufferWriter.cs
  61. 0 2
      src/SignalR/common/Shared/PipeWriterStream.cs
  62. 6 5
      src/SignalR/common/Shared/ReflectionHelper.cs
  63. 1 3
      src/SignalR/common/Shared/ReusableUtf8JsonWriter.cs
  64. 2 4
      src/SignalR/common/Shared/SystemTextJsonExtensions.cs
  65. 0 2
      src/SignalR/common/Shared/TimerAwaitable.cs
  66. 1 3
      src/SignalR/common/Shared/Utf8BufferTextReader.cs
  67. 15 11
      src/SignalR/common/Shared/Utf8BufferTextWriter.cs
  68. 2 2
      src/SignalR/common/SignalR.Common/src/Protocol/CompletionMessage.cs
  69. 8 8
      src/SignalR/common/SignalR.Common/src/Protocol/HubMethodInvocationMessage.cs
  70. 1 1
      src/SignalR/common/SignalR.Common/src/Protocol/IHubProtocol.cs
  71. 21 1
      src/SignalR/common/SignalR.Common/src/PublicAPI.Unshipped.txt
  72. 2 2
      src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTestsBase.cs
  73. 13 13
      src/SignalR/server/Core/src/DefaultHubLifetimeManager.cs
  74. 1 1
      src/SignalR/server/Core/src/DefaultUserIdProvider.cs
  75. 9 11
      src/SignalR/server/Core/src/HubConnectionContext.Log.cs
  76. 12 1
      src/SignalR/server/Core/src/HubConnectionContext.cs
  77. 0 1
      src/SignalR/server/Core/src/HubInvocationContext.cs
  78. 0 2
      src/SignalR/server/Core/src/HubLifetimeContext.cs
  79. 9 9
      src/SignalR/server/Core/src/HubLifetimeManager.cs
  80. 0 2
      src/SignalR/server/Core/src/HubOptionsExtensions.cs
  81. 1 1
      src/SignalR/server/Core/src/IClientProxy.cs
  82. 27 29
      src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.Log.cs
  83. 56 51
      src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs
  84. 1 1
      src/SignalR/server/Core/src/Internal/DynamicClientProxy.cs
  85. 7 9
      src/SignalR/server/Core/src/Internal/HubMethodDescriptor.cs
  86. 9 9
      src/SignalR/server/Core/src/Internal/Proxies.cs
  87. 7 9
      src/SignalR/server/Core/src/Internal/TypedClientBuilder.cs
  88. 41 0
      src/SignalR/server/Core/src/PublicAPI.Unshipped.txt
  89. 13 15
      src/SignalR/server/Core/src/StreamTracker.cs
  90. 2 2
      src/SignalR/server/SignalR/src/GetHttpContextExtensions.cs
  91. 1 1
      src/SignalR/server/SignalR/src/HubEndpointRouteBuilderExtensions.cs
  92. 1 0
      src/SignalR/server/SignalR/src/Microsoft.AspNetCore.SignalR.csproj
  93. 16 0
      src/SignalR/server/SignalR/src/PublicAPI.Unshipped.txt
  94. 1 1
      src/SignalR/server/StackExchangeRedis/src/Internal/AckHandler.cs
  95. 1 1
      src/SignalR/server/StackExchangeRedis/src/Internal/DefaultHubMessageSerializer.cs
  96. 2 9
      src/SignalR/server/StackExchangeRedis/src/Internal/RedisInvocation.cs
  97. 9 9
      src/SignalR/server/StackExchangeRedis/src/Internal/RedisLog.cs
  98. 3 3
      src/SignalR/server/StackExchangeRedis/src/Internal/RedisProtocol.cs
  99. 1 0
      src/SignalR/server/StackExchangeRedis/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj
  100. 46 0
      src/SignalR/server/StackExchangeRedis/src/PublicAPI.Unshipped.txt

+ 2 - 1
eng/targets/CSharp.Common.targets

@@ -80,7 +80,8 @@
 
 
         SuppressNullableAttributesImport to disable. Used when attributes are already present from another project because of InternalsVisibleTo.
         SuppressNullableAttributesImport to disable. Used when attributes are already present from another project because of InternalsVisibleTo.
      -->
      -->
-    <When Condition="'$(Nullable)' != '' AND '$(SuppressNullableAttributesImport)' != 'true' AND ('$(TargetFrameworkIdentifier)' == '.NETStandard' OR '$(TargetFrameworkIdentifier)' == '.NETFramework')">
+    <When Condition="'$(Nullable)' != '' AND '$(SuppressNullableAttributesImport)' != 'true' AND
+        (('$(TargetFrameworkIdentifier)' == '.NETStandard' AND $([MSBuild]::VersionLessThanOrEquals('$(TargetFrameworkVersion)', '2.0'))) OR '$(TargetFrameworkIdentifier)' == '.NETFramework')">
       <PropertyGroup>
       <PropertyGroup>
         <DefineConstants>$(DefineConstants),INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
         <DefineConstants>$(DefineConstants),INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
         <NoWarn>$(NoWarn);nullable</NoWarn>
         <NoWarn>$(NoWarn);nullable</NoWarn>

+ 1 - 1
src/Components/Ignitor/src/BlazorClient.cs

@@ -453,7 +453,7 @@ namespace Ignitor
             NextErrorReceived?.Completion?.TrySetResult(null);
             NextErrorReceived?.Completion?.TrySetResult(null);
         }
         }
 
 
-        private Task OnClosedAsync(Exception ex)
+        private Task OnClosedAsync(Exception? ex)
         {
         {
             NextDisconnect?.Completion?.TrySetResult(null);
             NextDisconnect?.Completion?.TrySetResult(null);
 
 

+ 76 - 76
src/SignalR/clients/csharp/Client.Core/src/HubConnection.Log.cs

@@ -12,91 +12,91 @@ namespace Microsoft.AspNetCore.SignalR.Client
     {
     {
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, string, int, Exception> _preparingNonBlockingInvocation =
+            private static readonly Action<ILogger, string, int, Exception?> _preparingNonBlockingInvocation =
             LoggerMessage.Define<string, int>(LogLevel.Trace, new EventId(1, "PreparingNonBlockingInvocation"), "Preparing non-blocking invocation of '{Target}', with {ArgumentCount} argument(s).");
             LoggerMessage.Define<string, int>(LogLevel.Trace, new EventId(1, "PreparingNonBlockingInvocation"), "Preparing non-blocking invocation of '{Target}', with {ArgumentCount} argument(s).");
 
 
-            private static readonly Action<ILogger, string, string, string, int, Exception> _preparingBlockingInvocation =
+            private static readonly Action<ILogger, string, string, string, int, Exception?> _preparingBlockingInvocation =
                 LoggerMessage.Define<string, string, string, int>(LogLevel.Trace, new EventId(2, "PreparingBlockingInvocation"), "Preparing blocking invocation '{InvocationId}' of '{Target}', with return type '{ReturnType}' and {ArgumentCount} argument(s).");
                 LoggerMessage.Define<string, string, string, int>(LogLevel.Trace, new EventId(2, "PreparingBlockingInvocation"), "Preparing blocking invocation '{InvocationId}' of '{Target}', with return type '{ReturnType}' and {ArgumentCount} argument(s).");
 
 
-            private static readonly Action<ILogger, string, Exception> _registeringInvocation =
+            private static readonly Action<ILogger, string, Exception?> _registeringInvocation =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(3, "RegisteringInvocation"), "Registering Invocation ID '{InvocationId}' for tracking.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(3, "RegisteringInvocation"), "Registering Invocation ID '{InvocationId}' for tracking.");
 
 
-            private static readonly Action<ILogger, string, string, string, string, Exception> _issuingInvocation =
+            private static readonly Action<ILogger, string, string, string, string, Exception?> _issuingInvocation =
                 LoggerMessage.Define<string, string, string, string>(LogLevel.Trace, new EventId(4, "IssuingInvocation"), "Issuing Invocation '{InvocationId}': {ReturnType} {MethodName}({Args}).");
                 LoggerMessage.Define<string, string, string, string>(LogLevel.Trace, new EventId(4, "IssuingInvocation"), "Issuing Invocation '{InvocationId}': {ReturnType} {MethodName}({Args}).");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _sendingMessage =
-                LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(5, "SendingMessage"), "Sending {MessageType} message '{InvocationId}'.");
+            private static readonly Action<ILogger, string, string?, Exception?> _sendingMessage =
+                LoggerMessage.Define<string, string?>(LogLevel.Debug, new EventId(5, "SendingMessage"), "Sending {MessageType} message '{InvocationId}'.");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _messageSent =
-                LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(6, "MessageSent"), "Sending {MessageType} message '{InvocationId}' completed.");
+            private static readonly Action<ILogger, string, string?, Exception?> _messageSent =
+                LoggerMessage.Define<string, string?>(LogLevel.Debug, new EventId(6, "MessageSent"), "Sending {MessageType} message '{InvocationId}' completed.");
 
 
             private static readonly Action<ILogger, string, Exception> _failedToSendInvocation =
             private static readonly Action<ILogger, string, Exception> _failedToSendInvocation =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(7, "FailedToSendInvocation"), "Sending Invocation '{InvocationId}' failed.");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(7, "FailedToSendInvocation"), "Sending Invocation '{InvocationId}' failed.");
 
 
-            private static readonly Action<ILogger, string, string, string, Exception> _receivedInvocation =
-                LoggerMessage.Define<string, string, string>(LogLevel.Trace, new EventId(8, "ReceivedInvocation"), "Received Invocation '{InvocationId}': {MethodName}({Args}).");
+            private static readonly Action<ILogger, string?, string, string, Exception?> _receivedInvocation =
+                LoggerMessage.Define<string?, string, string>(LogLevel.Trace, new EventId(8, "ReceivedInvocation"), "Received Invocation '{InvocationId}': {MethodName}({Args}).");
 
 
-            private static readonly Action<ILogger, string, Exception> _droppedCompletionMessage =
+            private static readonly Action<ILogger, string, Exception?> _droppedCompletionMessage =
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(9, "DroppedCompletionMessage"), "Dropped unsolicited Completion message for invocation '{InvocationId}'.");
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(9, "DroppedCompletionMessage"), "Dropped unsolicited Completion message for invocation '{InvocationId}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _droppedStreamMessage =
+            private static readonly Action<ILogger, string, Exception?> _droppedStreamMessage =
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(10, "DroppedStreamMessage"), "Dropped unsolicited StreamItem message for invocation '{InvocationId}'.");
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(10, "DroppedStreamMessage"), "Dropped unsolicited StreamItem message for invocation '{InvocationId}'.");
 
 
-            private static readonly Action<ILogger, Exception> _shutdownConnection =
+            private static readonly Action<ILogger, Exception?> _shutdownConnection =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(11, "ShutdownConnection"), "Shutting down connection.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(11, "ShutdownConnection"), "Shutting down connection.");
 
 
             private static readonly Action<ILogger, Exception> _shutdownWithError =
             private static readonly Action<ILogger, Exception> _shutdownWithError =
                 LoggerMessage.Define(LogLevel.Error, new EventId(12, "ShutdownWithError"), "Connection is shutting down due to an error.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(12, "ShutdownWithError"), "Connection is shutting down due to an error.");
 
 
-            private static readonly Action<ILogger, string, Exception> _removingInvocation =
+            private static readonly Action<ILogger, string, Exception?> _removingInvocation =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(13, "RemovingInvocation"), "Removing pending invocation {InvocationId}.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(13, "RemovingInvocation"), "Removing pending invocation {InvocationId}.");
 
 
-            private static readonly Action<ILogger, string, Exception> _missingHandler =
+            private static readonly Action<ILogger, string, Exception?> _missingHandler =
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(14, "MissingHandler"), "Failed to find handler for '{Target}' method.");
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(14, "MissingHandler"), "Failed to find handler for '{Target}' method.");
 
 
-            private static readonly Action<ILogger, string, Exception> _receivedStreamItem =
+            private static readonly Action<ILogger, string, Exception?> _receivedStreamItem =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(15, "ReceivedStreamItem"), "Received StreamItem for Invocation {InvocationId}.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(15, "ReceivedStreamItem"), "Received StreamItem for Invocation {InvocationId}.");
 
 
-            private static readonly Action<ILogger, string, Exception> _cancelingStreamItem =
+            private static readonly Action<ILogger, string, Exception?> _cancelingStreamItem =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(16, "CancelingStreamItem"), "Canceling dispatch of StreamItem message for Invocation {InvocationId}. The invocation was canceled.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(16, "CancelingStreamItem"), "Canceling dispatch of StreamItem message for Invocation {InvocationId}. The invocation was canceled.");
 
 
-            private static readonly Action<ILogger, string, Exception> _receivedStreamItemAfterClose =
+            private static readonly Action<ILogger, string, Exception?> _receivedStreamItemAfterClose =
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(17, "ReceivedStreamItemAfterClose"), "Invocation {InvocationId} received stream item after channel was closed.");
                 LoggerMessage.Define<string>(LogLevel.Warning, new EventId(17, "ReceivedStreamItemAfterClose"), "Invocation {InvocationId} received stream item after channel was closed.");
 
 
-            private static readonly Action<ILogger, string, Exception> _receivedInvocationCompletion =
+            private static readonly Action<ILogger, string, Exception?> _receivedInvocationCompletion =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(18, "ReceivedInvocationCompletion"), "Received Completion for Invocation {InvocationId}.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(18, "ReceivedInvocationCompletion"), "Received Completion for Invocation {InvocationId}.");
 
 
-            private static readonly Action<ILogger, string, Exception> _cancelingInvocationCompletion =
+            private static readonly Action<ILogger, string, Exception?> _cancelingInvocationCompletion =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(19, "CancelingInvocationCompletion"), "Canceling dispatch of Completion message for Invocation {InvocationId}. The invocation was canceled.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(19, "CancelingInvocationCompletion"), "Canceling dispatch of Completion message for Invocation {InvocationId}. The invocation was canceled.");
 
 
-            private static readonly Action<ILogger, string, string, int, Exception> _releasingConnectionLock =
-                LoggerMessage.Define<string, string, int>(LogLevel.Trace, new EventId(20, "ReleasingConnectionLock"), "Releasing Connection Lock in {MethodName} ({FilePath}:{LineNumber}).");
+            private static readonly Action<ILogger, string?, string?, int, Exception?> _releasingConnectionLock =
+                LoggerMessage.Define<string?, string?, int>(LogLevel.Trace, new EventId(20, "ReleasingConnectionLock"), "Releasing Connection Lock in {MethodName} ({FilePath}:{LineNumber}).");
 
 
-            private static readonly Action<ILogger, Exception> _stopped =
+            private static readonly Action<ILogger, Exception?> _stopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(21, "Stopped"), "HubConnection stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(21, "Stopped"), "HubConnection stopped.");
 
 
-            private static readonly Action<ILogger, string, Exception> _invocationAlreadyInUse =
+            private static readonly Action<ILogger, string, Exception?> _invocationAlreadyInUse =
                 LoggerMessage.Define<string>(LogLevel.Critical, new EventId(22, "InvocationAlreadyInUse"), "Invocation ID '{InvocationId}' is already in use.");
                 LoggerMessage.Define<string>(LogLevel.Critical, new EventId(22, "InvocationAlreadyInUse"), "Invocation ID '{InvocationId}' is already in use.");
 
 
-            private static readonly Action<ILogger, string, Exception> _receivedUnexpectedResponse =
+            private static readonly Action<ILogger, string, Exception?> _receivedUnexpectedResponse =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(23, "ReceivedUnexpectedResponse"), "Unsolicited response received for invocation '{InvocationId}'.");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(23, "ReceivedUnexpectedResponse"), "Unsolicited response received for invocation '{InvocationId}'.");
 
 
-            private static readonly Action<ILogger, string, int, Exception> _hubProtocol =
+            private static readonly Action<ILogger, string, int, Exception?> _hubProtocol =
                 LoggerMessage.Define<string, int>(LogLevel.Information, new EventId(24, "HubProtocol"), "Using HubProtocol '{Protocol} v{Version}'.");
                 LoggerMessage.Define<string, int>(LogLevel.Information, new EventId(24, "HubProtocol"), "Using HubProtocol '{Protocol} v{Version}'.");
 
 
-            private static readonly Action<ILogger, string, string, string, int, Exception> _preparingStreamingInvocation =
+            private static readonly Action<ILogger, string, string, string, int, Exception?> _preparingStreamingInvocation =
                 LoggerMessage.Define<string, string, string, int>(LogLevel.Trace, new EventId(25, "PreparingStreamingInvocation"), "Preparing streaming invocation '{InvocationId}' of '{Target}', with return type '{ReturnType}' and {ArgumentCount} argument(s).");
                 LoggerMessage.Define<string, string, string, int>(LogLevel.Trace, new EventId(25, "PreparingStreamingInvocation"), "Preparing streaming invocation '{InvocationId}' of '{Target}', with return type '{ReturnType}' and {ArgumentCount} argument(s).");
 
 
-            private static readonly Action<ILogger, Exception> _resettingKeepAliveTimer =
+            private static readonly Action<ILogger, Exception?> _resettingKeepAliveTimer =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(26, "ResettingKeepAliveTimer"), "Resetting keep-alive timer, received a message from the server.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(26, "ResettingKeepAliveTimer"), "Resetting keep-alive timer, received a message from the server.");
 
 
             private static readonly Action<ILogger, Exception> _errorDuringClosedEvent =
             private static readonly Action<ILogger, Exception> _errorDuringClosedEvent =
                 LoggerMessage.Define(LogLevel.Error, new EventId(27, "ErrorDuringClosedEvent"), "An exception was thrown in the handler for the Closed event.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(27, "ErrorDuringClosedEvent"), "An exception was thrown in the handler for the Closed event.");
 
 
-            private static readonly Action<ILogger, Exception> _sendingHubHandshake =
+            private static readonly Action<ILogger, Exception?> _sendingHubHandshake =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(28, "SendingHubHandshake"), "Sending Hub Handshake.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(28, "SendingHubHandshake"), "Sending Hub Handshake.");
 
 
-            private static readonly Action<ILogger, Exception> _receivedPing =
+            private static readonly Action<ILogger, Exception?> _receivedPing =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(31, "ReceivedPing"), "Received a ping message.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(31, "ReceivedPing"), "Received a ping message.");
 
 
             private static readonly Action<ILogger, string, Exception> _errorInvokingClientSideMethod =
             private static readonly Action<ILogger, string, Exception> _errorInvokingClientSideMethod =
@@ -105,115 +105,115 @@ namespace Microsoft.AspNetCore.SignalR.Client
             private static readonly Action<ILogger, Exception> _errorProcessingHandshakeResponse =
             private static readonly Action<ILogger, Exception> _errorProcessingHandshakeResponse =
                 LoggerMessage.Define(LogLevel.Error, new EventId(35, "ErrorReceivingHandshakeResponse"), "The underlying connection closed while processing the handshake response. See exception for details.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(35, "ErrorReceivingHandshakeResponse"), "The underlying connection closed while processing the handshake response. See exception for details.");
 
 
-            private static readonly Action<ILogger, string, Exception> _handshakeServerError =
+            private static readonly Action<ILogger, string, Exception?> _handshakeServerError =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(36, "HandshakeServerError"), "Server returned handshake error: {Error}");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(36, "HandshakeServerError"), "Server returned handshake error: {Error}");
 
 
-            private static readonly Action<ILogger, Exception> _receivedClose =
+            private static readonly Action<ILogger, Exception?> _receivedClose =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(37, "ReceivedClose"), "Received close message.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(37, "ReceivedClose"), "Received close message.");
 
 
-            private static readonly Action<ILogger, string, Exception> _receivedCloseWithError =
+            private static readonly Action<ILogger, string, Exception?> _receivedCloseWithError =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(38, "ReceivedCloseWithError"), "Received close message with an error: {Error}");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(38, "ReceivedCloseWithError"), "Received close message with an error: {Error}");
 
 
-            private static readonly Action<ILogger, Exception> _handshakeComplete =
+            private static readonly Action<ILogger, Exception?> _handshakeComplete =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(39, "HandshakeComplete"), "Handshake with server complete.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(39, "HandshakeComplete"), "Handshake with server complete.");
 
 
-            private static readonly Action<ILogger, string, Exception> _registeringHandler =
+            private static readonly Action<ILogger, string, Exception?> _registeringHandler =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(40, "RegisteringHandler"), "Registering handler for client method '{MethodName}'.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(40, "RegisteringHandler"), "Registering handler for client method '{MethodName}'.");
 
 
-            private static readonly Action<ILogger, Exception> _starting =
+            private static readonly Action<ILogger, Exception?> _starting =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(41, "Starting"), "Starting HubConnection.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(41, "Starting"), "Starting HubConnection.");
 
 
-            private static readonly Action<ILogger, string, string, int, Exception> _waitingOnConnectionLock =
-                LoggerMessage.Define<string, string, int>(LogLevel.Trace, new EventId(42, "WaitingOnConnectionLock"), "Waiting on Connection Lock in {MethodName} ({FilePath}:{LineNumber}).");
+            private static readonly Action<ILogger, string?, string?, int, Exception?> _waitingOnConnectionLock =
+                LoggerMessage.Define<string?, string?, int>(LogLevel.Trace, new EventId(42, "WaitingOnConnectionLock"), "Waiting on Connection Lock in {MethodName} ({FilePath}:{LineNumber}).");
 
 
             private static readonly Action<ILogger, Exception> _errorStartingConnection =
             private static readonly Action<ILogger, Exception> _errorStartingConnection =
                 LoggerMessage.Define(LogLevel.Error, new EventId(43, "ErrorStartingConnection"), "Error starting connection.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(43, "ErrorStartingConnection"), "Error starting connection.");
 
 
-            private static readonly Action<ILogger, Exception> _started =
+            private static readonly Action<ILogger, Exception?> _started =
                 LoggerMessage.Define(LogLevel.Information, new EventId(44, "Started"), "HubConnection started.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(44, "Started"), "HubConnection started.");
 
 
-            private static readonly Action<ILogger, string, Exception> _sendingCancellation =
+            private static readonly Action<ILogger, string, Exception?> _sendingCancellation =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(45, "SendingCancellation"), "Sending Cancellation for Invocation '{InvocationId}'.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(45, "SendingCancellation"), "Sending Cancellation for Invocation '{InvocationId}'.");
 
 
-            private static readonly Action<ILogger, Exception> _cancelingOutstandingInvocations =
+            private static readonly Action<ILogger, Exception?> _cancelingOutstandingInvocations =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(46, "CancelingOutstandingInvocations"), "Canceling all outstanding invocations.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(46, "CancelingOutstandingInvocations"), "Canceling all outstanding invocations.");
 
 
-            private static readonly Action<ILogger, Exception> _receiveLoopStarting =
+            private static readonly Action<ILogger, Exception?> _receiveLoopStarting =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(47, "ReceiveLoopStarting"), "Receive loop starting.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(47, "ReceiveLoopStarting"), "Receive loop starting.");
 
 
-            private static readonly Action<ILogger, double, Exception> _startingServerTimeoutTimer =
+            private static readonly Action<ILogger, double, Exception?> _startingServerTimeoutTimer =
                 LoggerMessage.Define<double>(LogLevel.Debug, new EventId(48, "StartingServerTimeoutTimer"), "Starting server timeout timer. Duration: {ServerTimeout:0.00}ms");
                 LoggerMessage.Define<double>(LogLevel.Debug, new EventId(48, "StartingServerTimeoutTimer"), "Starting server timeout timer. Duration: {ServerTimeout:0.00}ms");
 
 
-            private static readonly Action<ILogger, Exception> _notUsingServerTimeout =
+            private static readonly Action<ILogger, Exception?> _notUsingServerTimeout =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(49, "NotUsingServerTimeout"), "Not using server timeout because the transport inherently tracks server availability.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(49, "NotUsingServerTimeout"), "Not using server timeout because the transport inherently tracks server availability.");
 
 
             private static readonly Action<ILogger, Exception> _serverDisconnectedWithError =
             private static readonly Action<ILogger, Exception> _serverDisconnectedWithError =
                 LoggerMessage.Define(LogLevel.Error, new EventId(50, "ServerDisconnectedWithError"), "The server connection was terminated with an error.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(50, "ServerDisconnectedWithError"), "The server connection was terminated with an error.");
 
 
-            private static readonly Action<ILogger, Exception> _invokingClosedEventHandler =
+            private static readonly Action<ILogger, Exception?> _invokingClosedEventHandler =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(51, "InvokingClosedEventHandler"), "Invoking the Closed event handler.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(51, "InvokingClosedEventHandler"), "Invoking the Closed event handler.");
 
 
-            private static readonly Action<ILogger, Exception> _stopping =
+            private static readonly Action<ILogger, Exception?> _stopping =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(52, "Stopping"), "Stopping HubConnection.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(52, "Stopping"), "Stopping HubConnection.");
 
 
-            private static readonly Action<ILogger, Exception> _terminatingReceiveLoop =
+            private static readonly Action<ILogger, Exception?> _terminatingReceiveLoop =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(53, "TerminatingReceiveLoop"), "Terminating receive loop.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(53, "TerminatingReceiveLoop"), "Terminating receive loop.");
 
 
-            private static readonly Action<ILogger, Exception> _waitingForReceiveLoopToTerminate =
+            private static readonly Action<ILogger, Exception?> _waitingForReceiveLoopToTerminate =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(54, "WaitingForReceiveLoopToTerminate"), "Waiting for the receive loop to terminate.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(54, "WaitingForReceiveLoopToTerminate"), "Waiting for the receive loop to terminate.");
 
 
-            private static readonly Action<ILogger, string, Exception> _unableToSendCancellation =
+            private static readonly Action<ILogger, string, Exception?> _unableToSendCancellation =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(55, "UnableToSendCancellation"), "Unable to send cancellation for invocation '{InvocationId}'. The connection is inactive.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(55, "UnableToSendCancellation"), "Unable to send cancellation for invocation '{InvocationId}'. The connection is inactive.");
 
 
-            private static readonly Action<ILogger, long, Exception> _processingMessage =
+            private static readonly Action<ILogger, long, Exception?> _processingMessage =
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(56, "ProcessingMessage"), "Processing {MessageLength} byte message from server.");
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(56, "ProcessingMessage"), "Processing {MessageLength} byte message from server.");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _argumentBindingFailure =
-                LoggerMessage.Define<string, string>(LogLevel.Error, new EventId(57, "ArgumentBindingFailure"), "Failed to bind arguments received in invocation '{InvocationId}' of '{MethodName}'.");
+            private static readonly Action<ILogger, string?, string, Exception> _argumentBindingFailure =
+                LoggerMessage.Define<string?, string>(LogLevel.Error, new EventId(57, "ArgumentBindingFailure"), "Failed to bind arguments received in invocation '{InvocationId}' of '{MethodName}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _removingHandlers =
+            private static readonly Action<ILogger, string, Exception?> _removingHandlers =
                LoggerMessage.Define<string>(LogLevel.Debug, new EventId(58, "RemovingHandlers"), "Removing handlers for client method '{MethodName}'.");
                LoggerMessage.Define<string>(LogLevel.Debug, new EventId(58, "RemovingHandlers"), "Removing handlers for client method '{MethodName}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _sendingMessageGeneric =
+            private static readonly Action<ILogger, string, Exception?> _sendingMessageGeneric =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(59, "SendingMessageGeneric"), "Sending {MessageType} message.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(59, "SendingMessageGeneric"), "Sending {MessageType} message.");
 
 
-            private static readonly Action<ILogger, string, Exception> _messageSentGeneric =
+            private static readonly Action<ILogger, string, Exception?> _messageSentGeneric =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(60, "MessageSentGeneric"), "Sending {MessageType} message completed.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(60, "MessageSentGeneric"), "Sending {MessageType} message completed.");
 
 
-            private static readonly Action<ILogger, Exception> _acquiredConnectionLockForPing =
+            private static readonly Action<ILogger, Exception?> _acquiredConnectionLockForPing =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(61, "AcquiredConnectionLockForPing"), "Acquired the Connection Lock in order to ping the server.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(61, "AcquiredConnectionLockForPing"), "Acquired the Connection Lock in order to ping the server.");
 
 
-            private static readonly Action<ILogger, Exception> _unableToAcquireConnectionLockForPing =
+            private static readonly Action<ILogger, Exception?> _unableToAcquireConnectionLockForPing =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(62, "UnableToAcquireConnectionLockForPing"), "Skipping ping because a send is already in progress.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(62, "UnableToAcquireConnectionLockForPing"), "Skipping ping because a send is already in progress.");
 
 
-            private static readonly Action<ILogger, string, Exception> _startingStream =
+            private static readonly Action<ILogger, string, Exception?> _startingStream =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(63, "StartingStream"), "Initiating stream '{StreamId}'.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(63, "StartingStream"), "Initiating stream '{StreamId}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _sendingStreamItem =
+            private static readonly Action<ILogger, string, Exception?> _sendingStreamItem =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(64, "StreamItemSent"), "Sending item for stream '{StreamId}'.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(64, "StreamItemSent"), "Sending item for stream '{StreamId}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _cancelingStream =
+            private static readonly Action<ILogger, string, Exception?> _cancelingStream =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(65, "CancelingStream"), "Stream '{StreamId}' has been canceled by client.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(65, "CancelingStream"), "Stream '{StreamId}' has been canceled by client.");
 
 
-            private static readonly Action<ILogger, string, Exception> _completingStream =
+            private static readonly Action<ILogger, string, Exception?> _completingStream =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(66, "CompletingStream"), "Sending completion message for stream '{StreamId}'.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(66, "CompletingStream"), "Sending completion message for stream '{StreamId}'.");
 
 
-            private static readonly Action<ILogger, HubConnectionState, HubConnectionState, HubConnectionState, Exception> _stateTransitionFailed =
+            private static readonly Action<ILogger, HubConnectionState, HubConnectionState, HubConnectionState, Exception?> _stateTransitionFailed =
                 LoggerMessage.Define<HubConnectionState, HubConnectionState, HubConnectionState>(LogLevel.Error, new EventId(67, "StateTransitionFailed"), "The HubConnection failed to transition from the {ExpectedState} state to the {NewState} state because it was actually in the {ActualState} state.");
                 LoggerMessage.Define<HubConnectionState, HubConnectionState, HubConnectionState>(LogLevel.Error, new EventId(67, "StateTransitionFailed"), "The HubConnection failed to transition from the {ExpectedState} state to the {NewState} state because it was actually in the {ActualState} state.");
 
 
-            private static readonly Action<ILogger, Exception> _reconnecting =
+            private static readonly Action<ILogger, Exception?> _reconnecting =
                 LoggerMessage.Define(LogLevel.Information, new EventId(68, "Reconnecting"), "HubConnection reconnecting.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(68, "Reconnecting"), "HubConnection reconnecting.");
 
 
             private static readonly Action<ILogger, Exception> _reconnectingWithError =
             private static readonly Action<ILogger, Exception> _reconnectingWithError =
                 LoggerMessage.Define(LogLevel.Error, new EventId(69, "ReconnectingWithError"), "HubConnection reconnecting due to an error.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(69, "ReconnectingWithError"), "HubConnection reconnecting due to an error.");
 
 
-            private static readonly Action<ILogger, long, TimeSpan, Exception> _reconnected =
+            private static readonly Action<ILogger, long, TimeSpan, Exception?> _reconnected =
                 LoggerMessage.Define<long, TimeSpan>(LogLevel.Information, new EventId(70, "Reconnected"), "HubConnection reconnected successfully after {ReconnectAttempts} attempts and {ElapsedTime} elapsed.");
                 LoggerMessage.Define<long, TimeSpan>(LogLevel.Information, new EventId(70, "Reconnected"), "HubConnection reconnected successfully after {ReconnectAttempts} attempts and {ElapsedTime} elapsed.");
 
 
-            private static readonly Action<ILogger, long, TimeSpan, Exception> _reconnectAttemptsExhausted =
+            private static readonly Action<ILogger, long, TimeSpan, Exception?> _reconnectAttemptsExhausted =
                 LoggerMessage.Define<long, TimeSpan>(LogLevel.Information, new EventId(71, "ReconnectAttemptsExhausted"), "Reconnect retries have been exhausted after {ReconnectAttempts} failed attempts and {ElapsedTime} elapsed. Disconnecting.");
                 LoggerMessage.Define<long, TimeSpan>(LogLevel.Information, new EventId(71, "ReconnectAttemptsExhausted"), "Reconnect retries have been exhausted after {ReconnectAttempts} failed attempts and {ElapsedTime} elapsed. Disconnecting.");
 
 
-            private static readonly Action<ILogger, long, TimeSpan, Exception> _awaitingReconnectRetryDelay =
+            private static readonly Action<ILogger, long, TimeSpan, Exception?> _awaitingReconnectRetryDelay =
                 LoggerMessage.Define<long, TimeSpan>(LogLevel.Trace, new EventId(72, "AwaitingReconnectRetryDelay"), "Reconnect attempt number {ReconnectAttempts} will start in {RetryDelay}.");
                 LoggerMessage.Define<long, TimeSpan>(LogLevel.Trace, new EventId(72, "AwaitingReconnectRetryDelay"), "Reconnect attempt number {ReconnectAttempts} will start in {RetryDelay}.");
 
 
             private static readonly Action<ILogger, Exception> _reconnectAttemptFailed =
             private static readonly Action<ILogger, Exception> _reconnectAttemptFailed =
@@ -228,16 +228,16 @@ namespace Microsoft.AspNetCore.SignalR.Client
             private static readonly Action<ILogger, Exception> _errorDuringNextRetryDelay  =
             private static readonly Action<ILogger, Exception> _errorDuringNextRetryDelay  =
                 LoggerMessage.Define(LogLevel.Error, new EventId(76, "ErrorDuringNextRetryDelay"), $"An exception was thrown from {nameof(IRetryPolicy)}.{nameof(IRetryPolicy.NextRetryDelay)}().");
                 LoggerMessage.Define(LogLevel.Error, new EventId(76, "ErrorDuringNextRetryDelay"), $"An exception was thrown from {nameof(IRetryPolicy)}.{nameof(IRetryPolicy.NextRetryDelay)}().");
 
 
-            private static readonly Action<ILogger, Exception> _firstReconnectRetryDelayNull =
+            private static readonly Action<ILogger, Exception?> _firstReconnectRetryDelayNull =
                 LoggerMessage.Define(LogLevel.Warning, new EventId(77, "FirstReconnectRetryDelayNull"), "Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt.");
                 LoggerMessage.Define(LogLevel.Warning, new EventId(77, "FirstReconnectRetryDelayNull"), "Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt.");
 
 
-            private static readonly Action<ILogger, Exception> _reconnectingStoppedDuringRetryDelay =
+            private static readonly Action<ILogger, Exception?> _reconnectingStoppedDuringRetryDelay =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(78, "ReconnectingStoppedDueToStateChangeDuringRetryDelay"), "Connection stopped during reconnect delay. Done reconnecting.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(78, "ReconnectingStoppedDueToStateChangeDuringRetryDelay"), "Connection stopped during reconnect delay. Done reconnecting.");
 
 
-            private static readonly Action<ILogger, Exception> _reconnectingStoppedDuringReconnectAttempt =
+            private static readonly Action<ILogger, Exception?> _reconnectingStoppedDuringReconnectAttempt =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(79, "ReconnectingStoppedDueToStateChangeDuringReconnectAttempt"), "Connection stopped during reconnect attempt. Done reconnecting.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(79, "ReconnectingStoppedDueToStateChangeDuringReconnectAttempt"), "Connection stopped during reconnect attempt. Done reconnecting.");
 
 
-            private static readonly Action<ILogger, HubConnectionState, HubConnectionState, Exception> _attemptingStateTransition =
+            private static readonly Action<ILogger, HubConnectionState, HubConnectionState, Exception?> _attemptingStateTransition =
                 LoggerMessage.Define<HubConnectionState, HubConnectionState>(LogLevel.Trace, new EventId(80, "AttemptingStateTransition"), "The HubConnection is attempting to transition from the {ExpectedState} state to the {NewState} state.");
                 LoggerMessage.Define<HubConnectionState, HubConnectionState>(LogLevel.Trace, new EventId(80, "AttemptingStateTransition"), "The HubConnection is attempting to transition from the {ExpectedState} state to the {NewState} state.");
 
 
             private static readonly Action<ILogger, Exception> _errorInvalidHandshakeResponse =
             private static readonly Action<ILogger, Exception> _errorInvalidHandshakeResponse =
@@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 _registeringInvocation(logger, invocationId, null);
                 _registeringInvocation(logger, invocationId, null);
             }
             }
 
 
-            public static void IssuingInvocation(ILogger logger, string invocationId, string returnType, string methodName, object[] args)
+            public static void IssuingInvocation(ILogger logger, string invocationId, string returnType, string methodName, object?[] args)
             {
             {
                 if (logger.IsEnabled(LogLevel.Trace))
                 if (logger.IsEnabled(LogLevel.Trace))
                 {
                 {
@@ -313,7 +313,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 _failedToSendInvocation(logger, invocationId, exception);
                 _failedToSendInvocation(logger, invocationId, exception);
             }
             }
 
 
-            public static void ReceivedInvocation(ILogger logger, string invocationId, string methodName, object[] args)
+            public static void ReceivedInvocation(ILogger logger, string? invocationId, string methodName, object?[] args)
             {
             {
                 if (logger.IsEnabled(LogLevel.Trace))
                 if (logger.IsEnabled(LogLevel.Trace))
                 {
                 {
@@ -530,12 +530,12 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 _processingMessage(logger, length, null);
                 _processingMessage(logger, length, null);
             }
             }
 
 
-            public static void WaitingOnConnectionLock(ILogger logger, string memberName, string filePath, int lineNumber)
+            public static void WaitingOnConnectionLock(ILogger logger, string? memberName, string? filePath, int lineNumber)
             {
             {
                 _waitingOnConnectionLock(logger, memberName, filePath, lineNumber, null);
                 _waitingOnConnectionLock(logger, memberName, filePath, lineNumber, null);
             }
             }
 
 
-            public static void ReleasingConnectionLock(ILogger logger, string memberName, string filePath, int lineNumber)
+            public static void ReleasingConnectionLock(ILogger logger, string? memberName, string? filePath, int lineNumber)
             {
             {
                 _releasingConnectionLock(logger, memberName, filePath, lineNumber, null);
                 _releasingConnectionLock(logger, memberName, filePath, lineNumber, null);
             }
             }
@@ -545,7 +545,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 _unableToSendCancellation(logger, invocationId, null);
                 _unableToSendCancellation(logger, invocationId, null);
             }
             }
 
 
-            public static void ArgumentBindingFailure(ILogger logger, string invocationId, string target, Exception exception)
+            public static void ArgumentBindingFailure(ILogger logger, string? invocationId, string target, Exception exception)
             {
             {
                 _argumentBindingFailure(logger, invocationId, target, exception);
                 _argumentBindingFailure(logger, invocationId, target, exception);
             }
             }
@@ -559,7 +559,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             {
             {
                 _unableToAcquireConnectionLockForPing(logger, null);
                 _unableToAcquireConnectionLockForPing(logger, null);
             }
             }
-            
+
             public static void StartingStream(ILogger logger, string streamId)
             public static void StartingStream(ILogger logger, string streamId)
             {
             {
                 _startingStream(logger, streamId, null);
                 _startingStream(logger, streamId, null);

+ 82 - 82
src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs

@@ -5,13 +5,13 @@ using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Net;
 using System.Net;
 using System.Reflection;
 using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading;
 using System.Threading.Channels;
 using System.Threading.Channels;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
@@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         private readonly IHubProtocol _protocol;
         private readonly IHubProtocol _protocol;
         private readonly IServiceProvider _serviceProvider;
         private readonly IServiceProvider _serviceProvider;
         private readonly IConnectionFactory _connectionFactory;
         private readonly IConnectionFactory _connectionFactory;
-        private readonly IRetryPolicy _reconnectPolicy;
+        private readonly IRetryPolicy? _reconnectPolicy;
         private readonly EndPoint _endPoint;
         private readonly EndPoint _endPoint;
         private readonly ConcurrentDictionary<string, InvocationHandlerList> _handlers = new ConcurrentDictionary<string, InvocationHandlerList>(StringComparer.Ordinal);
         private readonly ConcurrentDictionary<string, InvocationHandlerList> _handlers = new ConcurrentDictionary<string, InvocationHandlerList>(StringComparer.Ordinal);
 
 
@@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// };
         /// };
         /// </code>
         /// </code>
         /// </example>
         /// </example>
-        public event Func<Exception, Task> Closed;
+        public event Func<Exception?, Task>? Closed;
 
 
         /// <summary>
         /// <summary>
         /// Occurs when the <see cref="HubConnection"/> starts reconnecting after losing its underlying connection.
         /// Occurs when the <see cref="HubConnection"/> starts reconnecting after losing its underlying connection.
@@ -125,7 +125,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// };
         /// };
         /// </code>
         /// </code>
         /// </example>
         /// </example>
-        public event Func<Exception, Task> Reconnecting;
+        public event Func<Exception?, Task>? Reconnecting;
 
 
         /// <summary>
         /// <summary>
         /// Occurs when the <see cref="HubConnection"/> successfully reconnects after losing its underlying connection.
         /// Occurs when the <see cref="HubConnection"/> successfully reconnects after losing its underlying connection.
@@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// };
         /// };
         /// </code>
         /// </code>
         /// </example>
         /// </example>
-        public event Func<string, Task> Reconnected;
+        public event Func<string?, Task>? Reconnected;
 
 
         // internal for testing purposes
         // internal for testing purposes
         internal TimeSpan TickRate { get; set; } = TimeSpan.FromSeconds(1);
         internal TimeSpan TickRate { get; set; } = TimeSpan.FromSeconds(1);
@@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// This value will be null if the negotiation step is skipped via HttpConnectionOptions or if the WebSockets transport is explicitly specified because the
         /// This value will be null if the negotiation step is skipped via HttpConnectionOptions or if the WebSockets transport is explicitly specified because the
         /// client skips negotiation in that case as well.
         /// client skips negotiation in that case as well.
         /// </summary>
         /// </summary>
-        public string ConnectionId => _state.CurrentConnectionStateUnsynchronized?.Connection.ConnectionId;
+        public string? ConnectionId => _state.CurrentConnectionStateUnsynchronized?.Connection.ConnectionId;
 
 
         /// <summary>
         /// <summary>
         /// Indicates the state of the <see cref="HubConnection"/> to the server.
         /// Indicates the state of the <see cref="HubConnection"/> to the server.
@@ -327,7 +327,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <remarks>
         /// <remarks>
         /// This is a low level method for registering a handler. Using an <see cref="HubConnectionExtensions"/> <c>On</c> extension method is recommended.
         /// This is a low level method for registering a handler. Using an <see cref="HubConnectionExtensions"/> <c>On</c> extension method is recommended.
         /// </remarks>
         /// </remarks>
-        public IDisposable On(string methodName, Type[] parameterTypes, Func<object[], object, Task> handler, object state)
+        public IDisposable On(string methodName, Type[] parameterTypes, Func<object?[], object, Task> handler, object state)
         {
         {
             Log.RegisteringHandler(_logger, methodName);
             Log.RegisteringHandler(_logger, methodName);
 
 
@@ -373,7 +373,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <remarks>
         /// <remarks>
         /// This is a low level method for invoking a streaming hub method on the server. Using an <see cref="HubConnectionExtensions"/> <c>StreamAsChannelAsync</c> extension method is recommended.
         /// This is a low level method for invoking a streaming hub method on the server. Using an <see cref="HubConnectionExtensions"/> <c>StreamAsChannelAsync</c> extension method is recommended.
         /// </remarks>
         /// </remarks>
-        public async Task<ChannelReader<object>> StreamAsChannelCoreAsync(string methodName, Type returnType, object[] args, CancellationToken cancellationToken = default)
+        public async Task<ChannelReader<object?>> StreamAsChannelCoreAsync(string methodName, Type returnType, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             using (_logger.BeginScope(_logScope))
             using (_logger.BeginScope(_logScope))
             {
             {
@@ -395,7 +395,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <remarks>
         /// <remarks>
         /// This is a low level method for invoking a hub method on the server. Using an <see cref="HubConnectionExtensions"/> <c>InvokeAsync</c> extension method is recommended.
         /// This is a low level method for invoking a hub method on the server. Using an <see cref="HubConnectionExtensions"/> <c>InvokeAsync</c> extension method is recommended.
         /// </remarks>
         /// </remarks>
-        public async Task<object> InvokeCoreAsync(string methodName, Type returnType, object[] args, CancellationToken cancellationToken = default)
+        public async Task<object?> InvokeCoreAsync(string methodName, Type returnType, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             using (_logger.BeginScope(_logScope))
             using (_logger.BeginScope(_logScope))
             {
             {
@@ -414,7 +414,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <remarks>
         /// <remarks>
         /// This is a low level method for invoking a hub method on the server. Using an <see cref="HubConnectionExtensions"/> <c>SendAsync</c> extension method is recommended.
         /// This is a low level method for invoking a hub method on the server. Using an <see cref="HubConnectionExtensions"/> <c>SendAsync</c> extension method is recommended.
         /// </remarks>
         /// </remarks>
-        public async Task SendCoreAsync(string methodName, object[] args, CancellationToken cancellationToken = default)
+        public async Task SendCoreAsync(string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             using (_logger.BeginScope(_logScope))
             using (_logger.BeginScope(_logScope))
             {
             {
@@ -493,7 +493,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 await _state.WaitConnectionLockAsync(token: default);
                 await _state.WaitConnectionLockAsync(token: default);
             }
             }
 
 
-            ConnectionState connectionState;
+            ConnectionState? connectionState;
 
 
             try
             try
             {
             {
@@ -554,7 +554,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <returns>
         /// <returns>
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
-        public IAsyncEnumerable<TResult> StreamAsyncCore<TResult>(string methodName, object[] args, CancellationToken cancellationToken = default)
+        public IAsyncEnumerable<TResult> StreamAsyncCore<TResult>(string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             var cts = cancellationToken.CanBeCanceled ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken) : new CancellationTokenSource();
             var cts = cancellationToken.CanBeCanceled ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken) : new CancellationTokenSource();
             var stream = CastIAsyncEnumerable<TResult>(methodName, args, cts);
             var stream = CastIAsyncEnumerable<TResult>(methodName, args, cts);
@@ -562,19 +562,19 @@ namespace Microsoft.AspNetCore.SignalR.Client
             return cancelableStream;
             return cancelableStream;
         }
         }
 
 
-        private async IAsyncEnumerable<T> CastIAsyncEnumerable<T>(string methodName, object[] args, CancellationTokenSource cts)
+        private async IAsyncEnumerable<T> CastIAsyncEnumerable<T>(string methodName, object?[] args, CancellationTokenSource cts)
         {
         {
             var reader = await StreamAsChannelCoreAsync(methodName, typeof(T), args, cts.Token);
             var reader = await StreamAsChannelCoreAsync(methodName, typeof(T), args, cts.Token);
             while (await reader.WaitToReadAsync(cts.Token))
             while (await reader.WaitToReadAsync(cts.Token))
             {
             {
                 while (reader.TryRead(out var item))
                 while (reader.TryRead(out var item))
                 {
                 {
-                    yield return (T)item;
+                    yield return (T)item!;
                 }
                 }
             }
             }
         }
         }
 
 
-        private async Task<ChannelReader<object>> StreamAsChannelCoreAsyncCore(string methodName, Type returnType, object[] args, CancellationToken cancellationToken)
+        private async Task<ChannelReader<object?>> StreamAsChannelCoreAsyncCore(string methodName, Type returnType, object?[] args, CancellationToken cancellationToken)
         {
         {
             async Task OnStreamCanceled(InvocationRequest irq)
             async Task OnStreamCanceled(InvocationRequest irq)
             {
             {
@@ -608,7 +608,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             CheckDisposed();
             CheckDisposed();
             var connectionState = await _state.WaitForActiveConnectionAsync(nameof(StreamAsChannelCoreAsync), token: cancellationToken);
             var connectionState = await _state.WaitForActiveConnectionAsync(nameof(StreamAsChannelCoreAsync), token: cancellationToken);
 
 
-            ChannelReader<object> channel;
+            ChannelReader<object?> channel;
             try
             try
             {
             {
                 CheckDisposed();
                 CheckDisposed();
@@ -622,7 +622,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
                 if (cancellationToken.CanBeCanceled)
                 if (cancellationToken.CanBeCanceled)
                 {
                 {
-                    cancellationToken.Register(state => _ = OnStreamCanceled((InvocationRequest)state), irq);
+                    cancellationToken.Register(state => _ = OnStreamCanceled((InvocationRequest)state!), irq);
                 }
                 }
 
 
                 LaunchStreams(connectionState, readers, cancellationToken);
                 LaunchStreams(connectionState, readers, cancellationToken);
@@ -635,9 +635,9 @@ namespace Microsoft.AspNetCore.SignalR.Client
             return channel;
             return channel;
         }
         }
 
 
-        private Dictionary<string, object> PackageStreamingParams(ConnectionState connectionState, ref object[] args, out List<string> streamIds)
+        private Dictionary<string, object>? PackageStreamingParams(ConnectionState connectionState, ref object?[] args, out List<string>? streamIds)
         {
         {
-            Dictionary<string, object> readers = null;
+            Dictionary<string, object>? readers = null;
             streamIds = null;
             streamIds = null;
             var newArgsCount = args.Length;
             var newArgsCount = args.Length;
             const int MaxStackSize = 256;
             const int MaxStackSize = 256;
@@ -662,7 +662,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                     }
                     }
 
 
                     var id = connectionState.GetNextId();
                     var id = connectionState.GetNextId();
-                    readers[id] = args[i];
+                    readers[id] = arg;
                     streamIds.Add(id);
                     streamIds.Add(id);
 
 
                     Log.StartingStream(_logger, id);
                     Log.StartingStream(_logger, id);
@@ -675,8 +675,8 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
 
 
             var newArgs = newArgsCount > 0
             var newArgs = newArgsCount > 0
-                ? new object[newArgsCount]
-                : Array.Empty<object>();
+                ? new object?[newArgsCount]
+                : Array.Empty<object?>();
             int newArgsIndex = 0;
             int newArgsIndex = 0;
 
 
             for (var i = 0; i < args.Length; i++)
             for (var i = 0; i < args.Length; i++)
@@ -692,7 +692,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             return readers;
             return readers;
         }
         }
 
 
-        private void LaunchStreams(ConnectionState connectionState, Dictionary<string, object> readers, CancellationToken cancellationToken)
+        private void LaunchStreams(ConnectionState connectionState, Dictionary<string, object>? readers, CancellationToken cancellationToken)
         {
         {
             if (readers == null)
             if (readers == null)
             {
             {
@@ -710,7 +710,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 if (ReflectionHelper.IsIAsyncEnumerable(reader.GetType()))
                 if (ReflectionHelper.IsIAsyncEnumerable(reader.GetType()))
                 {
                 {
                     _ = _sendIAsyncStreamItemsMethod
                     _ = _sendIAsyncStreamItemsMethod
-                        .MakeGenericMethod(reader.GetType().GetInterface("IAsyncEnumerable`1").GetGenericArguments())
+                        .MakeGenericMethod(reader.GetType().GetInterface("IAsyncEnumerable`1")!.GetGenericArguments())
                         .Invoke(this, new object[] { connectionState, kvp.Key.ToString(), reader, cancellationToken });
                         .Invoke(this, new object[] { connectionState, kvp.Key.ToString(), reader, cancellationToken });
                     continue;
                     continue;
                 }
                 }
@@ -762,7 +762,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             var cts = CancellationTokenSource.CreateLinkedTokenSource(connectionState.UploadStreamToken, token);
             var cts = CancellationTokenSource.CreateLinkedTokenSource(connectionState.UploadStreamToken, token);
 
 
             Log.StartingStream(_logger, streamId);
             Log.StartingStream(_logger, streamId);
-            string responseError = null;
+            string? responseError = null;
             try
             try
             {
             {
                 await createAndConsumeStream(cts);
                 await createAndConsumeStream(cts);
@@ -780,14 +780,14 @@ namespace Microsoft.AspNetCore.SignalR.Client
             await SendWithLock(connectionState, CompletionMessage.WithError(streamId, responseError), cancellationToken: default);
             await SendWithLock(connectionState, CompletionMessage.WithError(streamId, responseError), cancellationToken: default);
         }
         }
 
 
-        private async Task<object> InvokeCoreAsyncCore(string methodName, Type returnType, object[] args, CancellationToken cancellationToken)
+        private async Task<object?> InvokeCoreAsyncCore(string methodName, Type returnType, object?[] args, CancellationToken cancellationToken)
         {
         {
             var readers = default(Dictionary<string, object>);
             var readers = default(Dictionary<string, object>);
 
 
             CheckDisposed();
             CheckDisposed();
             var connectionState = await _state.WaitForActiveConnectionAsync(nameof(InvokeCoreAsync), token: cancellationToken);
             var connectionState = await _state.WaitForActiveConnectionAsync(nameof(InvokeCoreAsync), token: cancellationToken);
 
 
-            Task<object> invocationTask;
+            Task<object?> invocationTask;
             try
             try
             {
             {
                 CheckDisposed();
                 CheckDisposed();
@@ -808,18 +808,18 @@ namespace Microsoft.AspNetCore.SignalR.Client
             return await invocationTask;
             return await invocationTask;
         }
         }
 
 
-        private async Task InvokeCore(ConnectionState connectionState, string methodName, InvocationRequest irq, object[] args, string[] streams, CancellationToken cancellationToken)
+        private async Task InvokeCore(ConnectionState connectionState, string methodName, InvocationRequest irq, object?[] args, string[]? streams, CancellationToken cancellationToken)
         {
         {
-            Log.PreparingBlockingInvocation(_logger, irq.InvocationId, methodName, irq.ResultType.FullName, args.Length);
+            Log.PreparingBlockingInvocation(_logger, irq.InvocationId, methodName, irq.ResultType.FullName!, args.Length);
 
 
             // Client invocations are always blocking
             // Client invocations are always blocking
             var invocationMessage = new InvocationMessage(irq.InvocationId, methodName, args, streams);
             var invocationMessage = new InvocationMessage(irq.InvocationId, methodName, args, streams);
 
 
-            Log.RegisteringInvocation(_logger, invocationMessage.InvocationId);
+            Log.RegisteringInvocation(_logger, irq.InvocationId);
             connectionState.AddInvocation(irq);
             connectionState.AddInvocation(irq);
 
 
             // Trace the full invocation
             // Trace the full invocation
-            Log.IssuingInvocation(_logger, invocationMessage.InvocationId, irq.ResultType.FullName, methodName, args);
+            Log.IssuingInvocation(_logger, irq.InvocationId, irq.ResultType.FullName!, methodName, args);
 
 
             try
             try
             {
             {
@@ -827,26 +827,26 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
-                Log.FailedToSendInvocation(_logger, invocationMessage.InvocationId, ex);
-                connectionState.TryRemoveInvocation(invocationMessage.InvocationId, out _);
+                Log.FailedToSendInvocation(_logger, irq.InvocationId, ex);
+                connectionState.TryRemoveInvocation(irq.InvocationId, out _);
                 irq.Fail(ex);
                 irq.Fail(ex);
             }
             }
         }
         }
 
 
-        private async Task InvokeStreamCore(ConnectionState connectionState, string methodName, InvocationRequest irq, object[] args, string[] streams, CancellationToken cancellationToken)
+        private async Task InvokeStreamCore(ConnectionState connectionState, string methodName, InvocationRequest irq, object?[] args, string[]? streams, CancellationToken cancellationToken)
         {
         {
             _state.AssertConnectionValid();
             _state.AssertConnectionValid();
 
 
-            Log.PreparingStreamingInvocation(_logger, irq.InvocationId, methodName, irq.ResultType.FullName, args.Length);
+            Log.PreparingStreamingInvocation(_logger, irq.InvocationId, methodName, irq.ResultType.FullName!, args.Length);
 
 
             var invocationMessage = new StreamInvocationMessage(irq.InvocationId, methodName, args, streams);
             var invocationMessage = new StreamInvocationMessage(irq.InvocationId, methodName, args, streams);
 
 
-            Log.RegisteringInvocation(_logger, invocationMessage.InvocationId);
+            Log.RegisteringInvocation(_logger, irq.InvocationId);
 
 
             connectionState.AddInvocation(irq);
             connectionState.AddInvocation(irq);
 
 
             // Trace the full invocation
             // Trace the full invocation
-            Log.IssuingInvocation(_logger, invocationMessage.InvocationId, irq.ResultType.FullName, methodName, args);
+            Log.IssuingInvocation(_logger, irq.InvocationId, irq.ResultType.FullName!, methodName, args);
 
 
             try
             try
             {
             {
@@ -854,8 +854,8 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
-                Log.FailedToSendInvocation(_logger, invocationMessage.InvocationId, ex);
-                connectionState.TryRemoveInvocation(invocationMessage.InvocationId, out _);
+                Log.FailedToSendInvocation(_logger, irq.InvocationId, ex);
+                connectionState.TryRemoveInvocation(irq.InvocationId, out _);
                 irq.Fail(ex);
                 irq.Fail(ex);
             }
             }
         }
         }
@@ -875,7 +875,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             connectionState.ResetSendPing();
             connectionState.ResetSendPing();
         }
         }
 
 
-        private async Task SendCoreAsyncCore(string methodName, object[] args, CancellationToken cancellationToken)
+        private async Task SendCoreAsyncCore(string methodName, object?[] args, CancellationToken cancellationToken)
         {
         {
             var readers = default(Dictionary<string, object>);
             var readers = default(Dictionary<string, object>);
 
 
@@ -917,12 +917,12 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
         }
         }
 
 
-        private async Task<CloseMessage> ProcessMessagesAsync(HubMessage message, ConnectionState connectionState, ChannelWriter<InvocationMessage> invocationMessageWriter)
+        private async Task<CloseMessage?> ProcessMessagesAsync(HubMessage message, ConnectionState connectionState, ChannelWriter<InvocationMessage> invocationMessageWriter)
         {
         {
             Log.ResettingKeepAliveTimer(_logger);
             Log.ResettingKeepAliveTimer(_logger);
             connectionState.ResetTimeout();
             connectionState.ResetTimeout();
 
 
-            InvocationRequest irq;
+            InvocationRequest? irq;
             switch (message)
             switch (message)
             {
             {
                 case InvocationBindingFailureMessage bindingFailure:
                 case InvocationBindingFailureMessage bindingFailure:
@@ -935,9 +935,9 @@ namespace Microsoft.AspNetCore.SignalR.Client
                     await invocationMessageWriter.WriteAsync(invocation);
                     await invocationMessageWriter.WriteAsync(invocation);
                     break;
                     break;
                 case CompletionMessage completion:
                 case CompletionMessage completion:
-                    if (!connectionState.TryRemoveInvocation(completion.InvocationId, out irq))
+                    if (!connectionState.TryRemoveInvocation(completion.InvocationId!, out irq))
                     {
                     {
-                        Log.DroppedCompletionMessage(_logger, completion.InvocationId);
+                        Log.DroppedCompletionMessage(_logger, completion.InvocationId!);
                         break;
                         break;
                     }
                     }
 
 
@@ -947,9 +947,9 @@ namespace Microsoft.AspNetCore.SignalR.Client
                     break;
                     break;
                 case StreamItemMessage streamItem:
                 case StreamItemMessage streamItem:
                     // if there's no open StreamInvocation with the given id, then complete with an error
                     // if there's no open StreamInvocation with the given id, then complete with an error
-                    if (!connectionState.TryGetInvocation(streamItem.InvocationId, out irq))
+                    if (!connectionState.TryGetInvocation(streamItem.InvocationId!, out irq))
                     {
                     {
-                        Log.DroppedStreamMessage(_logger, streamItem.InvocationId);
+                        Log.DroppedStreamMessage(_logger, streamItem.InvocationId!);
                         break;
                         break;
                     }
                     }
                     await DispatchInvocationStreamItemAsync(streamItem, irq);
                     await DispatchInvocationStreamItemAsync(streamItem, irq);
@@ -1001,7 +1001,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
         private async Task DispatchInvocationStreamItemAsync(StreamItemMessage streamItem, InvocationRequest irq)
         private async Task DispatchInvocationStreamItemAsync(StreamItemMessage streamItem, InvocationRequest irq)
         {
         {
-            Log.ReceivedStreamItem(_logger, streamItem.InvocationId);
+            Log.ReceivedStreamItem(_logger, irq.InvocationId);
 
 
             if (irq.CancellationToken.IsCancellationRequested)
             if (irq.CancellationToken.IsCancellationRequested)
             {
             {
@@ -1015,7 +1015,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
         private void DispatchInvocationCompletion(CompletionMessage completion, InvocationRequest irq)
         private void DispatchInvocationCompletion(CompletionMessage completion, InvocationRequest irq)
         {
         {
-            Log.ReceivedInvocationCompletion(_logger, completion.InvocationId);
+            Log.ReceivedInvocationCompletion(_logger, irq.InvocationId);
 
 
             if (irq.CancellationToken.IsCancellationRequested)
             if (irq.CancellationToken.IsCancellationRequested)
             {
             {
@@ -1190,7 +1190,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                         {
                         {
                             Log.ProcessingMessage(_logger, buffer.Length);
                             Log.ProcessingMessage(_logger, buffer.Length);
 
 
-                            CloseMessage closeMessage = null;
+                            CloseMessage? closeMessage = null;
 
 
                             while (_protocol.TryParseMessage(ref buffer, connectionState, out var message))
                             while (_protocol.TryParseMessage(ref buffer, connectionState, out var message))
                             {
                             {
@@ -1259,14 +1259,14 @@ namespace Microsoft.AspNetCore.SignalR.Client
         internal Task RunTimerActions()
         internal Task RunTimerActions()
         {
         {
             // Don't bother acquiring the connection lock. This is only called from tests.
             // Don't bother acquiring the connection lock. This is only called from tests.
-            return _state.CurrentConnectionStateUnsynchronized.RunTimerActions();
+            return _state.CurrentConnectionStateUnsynchronized!.RunTimerActions();
         }
         }
 
 
         // Internal for testing
         // Internal for testing
         internal void OnServerTimeout()
         internal void OnServerTimeout()
         {
         {
             // Don't bother acquiring the connection lock. This is only called from tests.
             // Don't bother acquiring the connection lock. This is only called from tests.
-            _state.CurrentConnectionStateUnsynchronized.OnServerTimeout();
+            _state.CurrentConnectionStateUnsynchronized!.OnServerTimeout();
         }
         }
 
 
         private async Task HandleConnectionClose(ConnectionState connectionState)
         private async Task HandleConnectionClose(ConnectionState connectionState)
@@ -1310,14 +1310,14 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
         }
         }
 
 
-        private void CompleteClose(Exception closeException)
+        private void CompleteClose(Exception? closeException)
         {
         {
             _state.AssertInConnectionLock();
             _state.AssertInConnectionLock();
             _state.StopCts = new CancellationTokenSource();
             _state.StopCts = new CancellationTokenSource();
             RunCloseEvent(closeException);
             RunCloseEvent(closeException);
         }
         }
 
 
-        private void RunCloseEvent(Exception closeException)
+        private void RunCloseEvent(Exception? closeException)
         {
         {
             var closed = Closed;
             var closed = Closed;
 
 
@@ -1345,7 +1345,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
         }
         }
 
 
-        private async Task ReconnectAsync(Exception closeException)
+        private async Task ReconnectAsync(Exception? closeException)
         {
         {
             var previousReconnectAttempts = 0;
             var previousReconnectAttempts = 0;
             var reconnectStartTime = DateTime.UtcNow;
             var reconnectStartTime = DateTime.UtcNow;
@@ -1464,11 +1464,11 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
         }
         }
 
 
-        private TimeSpan? GetNextRetryDelay(long previousRetryCount, TimeSpan elapsedTime, Exception retryReason)
+        private TimeSpan? GetNextRetryDelay(long previousRetryCount, TimeSpan elapsedTime, Exception? retryReason)
         {
         {
             try
             try
             {
             {
-                return _reconnectPolicy.NextRetryDelay(new RetryContext
+                return _reconnectPolicy!.NextRetryDelay(new RetryContext
                 {
                 {
                     PreviousRetryCount = previousRetryCount,
                     PreviousRetryCount = previousRetryCount,
                     ElapsedTime = elapsedTime,
                     ElapsedTime = elapsedTime,
@@ -1491,7 +1491,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 #endif
 #endif
         }
         }
 
 
-        private void RunReconnectingEvent(Exception closeException)
+        private void RunReconnectingEvent(Exception? closeException)
         {
         {
             var reconnecting = Reconnecting;
             var reconnecting = Reconnecting;
 
 
@@ -1545,7 +1545,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
         }
         }
 
 
-        private IDisposable CreateLinkedToken(CancellationToken token1, CancellationToken token2, out CancellationToken linkedToken)
+        private IDisposable? CreateLinkedToken(CancellationToken token1, CancellationToken token2, out CancellationToken linkedToken)
         {
         {
             if (!token1.CanBeCanceled)
             if (!token1.CanBeCanceled)
             {
             {
@@ -1567,7 +1567,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
         // Debug.Assert plays havoc with Unit Tests. But I want something that I can "assert" only in Debug builds.
         // Debug.Assert plays havoc with Unit Tests. But I want something that I can "assert" only in Debug builds.
         [Conditional("DEBUG")]
         [Conditional("DEBUG")]
-        private static void SafeAssert(bool condition, string message, [CallerMemberName] string memberName = null, [CallerFilePath] string fileName = null, [CallerLineNumber] int lineNumber = 0)
+        private static void SafeAssert(bool condition, string message, [CallerMemberName] string? memberName = null, [CallerFilePath] string? fileName = null, [CallerLineNumber] int lineNumber = 0)
         {
         {
             if (!condition)
             if (!condition)
             {
             {
@@ -1597,7 +1597,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             private readonly List<InvocationHandler> _invocationHandlers;
             private readonly List<InvocationHandler> _invocationHandlers;
             // A lazy cached copy of the handlers that doesn't change for thread safety.
             // A lazy cached copy of the handlers that doesn't change for thread safety.
             // Adding or removing a handler sets this to null.
             // Adding or removing a handler sets this to null.
-            private InvocationHandler[] _copiedHandlers;
+            private InvocationHandler[]? _copiedHandlers;
 
 
             internal InvocationHandlerList(InvocationHandler handler)
             internal InvocationHandlerList(InvocationHandler handler)
             {
             {
@@ -1646,17 +1646,17 @@ namespace Microsoft.AspNetCore.SignalR.Client
         private readonly struct InvocationHandler
         private readonly struct InvocationHandler
         {
         {
             public Type[] ParameterTypes { get; }
             public Type[] ParameterTypes { get; }
-            private readonly Func<object[], object, Task> _callback;
+            private readonly Func<object?[], object, Task> _callback;
             private readonly object _state;
             private readonly object _state;
 
 
-            public InvocationHandler(Type[] parameterTypes, Func<object[], object, Task> callback, object state)
+            public InvocationHandler(Type[] parameterTypes, Func<object?[], object, Task> callback, object state)
             {
             {
                 _callback = callback;
                 _callback = callback;
                 ParameterTypes = parameterTypes;
                 ParameterTypes = parameterTypes;
                 _state = state;
                 _state = state;
             }
             }
 
 
-            public Task InvokeAsync(object[] parameters)
+            public Task InvokeAsync(object?[] parameters)
             {
             {
                 return _callback(parameters, _state);
                 return _callback(parameters, _state);
             }
             }
@@ -1670,7 +1670,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             private readonly object _lock = new object();
             private readonly object _lock = new object();
             private readonly Dictionary<string, InvocationRequest> _pendingCalls = new Dictionary<string, InvocationRequest>(StringComparer.Ordinal);
             private readonly Dictionary<string, InvocationRequest> _pendingCalls = new Dictionary<string, InvocationRequest>(StringComparer.Ordinal);
-            private TaskCompletionSource<object> _stopTcs;
+            private TaskCompletionSource<object?>? _stopTcs;
 
 
             private volatile bool _stopping;
             private volatile bool _stopping;
 
 
@@ -1680,12 +1680,12 @@ namespace Microsoft.AspNetCore.SignalR.Client
             private long _nextActivationSendPing;
             private long _nextActivationSendPing;
 
 
             public ConnectionContext Connection { get; }
             public ConnectionContext Connection { get; }
-            public Task ReceiveTask { get; set; }
-            public Exception CloseException { get; set; }
+            public Task? ReceiveTask { get; set; }
+            public Exception? CloseException { get; set; }
             public CancellationToken UploadStreamToken { get; set; }
             public CancellationToken UploadStreamToken { get; set; }
 
 
             // We store this task so we can view it in a dump file, but never await it
             // We store this task so we can view it in a dump file, but never await it
-            public Task InvocationMessageReceiveTask { get; set; }
+            public Task? InvocationMessageReceiveTask { get; set; }
 
 
             // Indicates the connection is stopping AND the client should NOT attempt to reconnect even if automatic reconnects are enabled.
             // Indicates the connection is stopping AND the client should NOT attempt to reconnect even if automatic reconnects are enabled.
             // This means either HubConnection.DisposeAsync/StopAsync was called OR a CloseMessage with AllowReconnects set to false was received.
             // This means either HubConnection.DisposeAsync/StopAsync was called OR a CloseMessage with AllowReconnects set to false was received.
@@ -1724,7 +1724,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 }
                 }
             }
             }
 
 
-            public bool TryGetInvocation(string invocationId, out InvocationRequest irq)
+            public bool TryGetInvocation(string invocationId, [NotNullWhen(true)] out InvocationRequest? irq)
             {
             {
                 lock (_lock)
                 lock (_lock)
                 {
                 {
@@ -1732,7 +1732,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 }
                 }
             }
             }
 
 
-            public bool TryRemoveInvocation(string invocationId, out InvocationRequest irq)
+            public bool TryRemoveInvocation(string invocationId, [NotNullWhen(true)] out InvocationRequest? irq)
             {
             {
                 lock (_lock)
                 lock (_lock)
                 {
                 {
@@ -1748,7 +1748,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 }
                 }
             }
             }
 
 
-            public void CancelOutstandingInvocations(Exception exception)
+            public void CancelOutstandingInvocations(Exception? exception)
             {
             {
                 Log.CancelingOutstandingInvocations(_logger);
                 Log.CancelingOutstandingInvocations(_logger);
 
 
@@ -1779,7 +1779,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                     }
                     }
                     else
                     else
                     {
                     {
-                        _stopTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
+                        _stopTcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
                         return StopAsyncCore();
                         return StopAsyncCore();
                     }
                     }
                 }
                 }
@@ -1795,12 +1795,12 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
                 // Wait ServerTimeout for the server or transport to shut down.
                 // Wait ServerTimeout for the server or transport to shut down.
                 Log.WaitingForReceiveLoopToTerminate(_logger);
                 Log.WaitingForReceiveLoopToTerminate(_logger);
-                await ReceiveTask;
+                await (ReceiveTask ?? Task.CompletedTask);
 
 
                 Log.Stopped(_logger);
                 Log.Stopped(_logger);
 
 
                 _hubConnection._logScope.ConnectionId = null;
                 _hubConnection._logScope.ConnectionId = null;
-                _stopTcs.TrySetResult(null);
+                _stopTcs!.TrySetResult(null);
             }
             }
 
 
             public async Task TimerLoop(TimerAwaitable timer)
             public async Task TimerLoop(TimerAwaitable timer)
@@ -1892,7 +1892,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 if (!TryGetInvocation(invocationId, out var irq))
                 if (!TryGetInvocation(invocationId, out var irq))
                 {
                 {
                     Log.ReceivedUnexpectedResponse(_logger, invocationId);
                     Log.ReceivedUnexpectedResponse(_logger, invocationId);
-                    return null;
+                    throw new KeyNotFoundException($"No invocation with id '{invocationId}' could be found.");
                 }
                 }
                 return irq.ResultType;
                 return irq.ResultType;
             }
             }
@@ -1904,7 +1904,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 if (!TryGetInvocation(invocationId, out var irq))
                 if (!TryGetInvocation(invocationId, out var irq))
                 {
                 {
                     Log.ReceivedUnexpectedResponse(_logger, invocationId);
                     Log.ReceivedUnexpectedResponse(_logger, invocationId);
-                    return null;
+                    throw new KeyNotFoundException($"No invocation with id '{invocationId}' could be found.");
                 }
                 }
                 return irq.ResultType;
                 return irq.ResultType;
             }
             }
@@ -1941,7 +1941,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 ReconnectTask = Task.CompletedTask;
                 ReconnectTask = Task.CompletedTask;
             }
             }
 
 
-            public ConnectionState CurrentConnectionStateUnsynchronized { get; set; }
+            public ConnectionState? CurrentConnectionStateUnsynchronized { get; set; }
 
 
             public HubConnectionState OverallState { get; private set; }
             public HubConnectionState OverallState { get; private set; }
 
 
@@ -1974,16 +1974,16 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
 
 
             [Conditional("DEBUG")]
             [Conditional("DEBUG")]
-            public void AssertInConnectionLock([CallerMemberName] string memberName = null, [CallerFilePath] string fileName = null, [CallerLineNumber] int lineNumber = 0) => SafeAssert(_connectionLock.CurrentCount == 0, "We're not in the Connection Lock!", memberName, fileName, lineNumber);
+            public void AssertInConnectionLock([CallerMemberName] string? memberName = null, [CallerFilePath] string? fileName = null, [CallerLineNumber] int lineNumber = 0) => SafeAssert(_connectionLock.CurrentCount == 0, "We're not in the Connection Lock!", memberName, fileName, lineNumber);
 
 
             [Conditional("DEBUG")]
             [Conditional("DEBUG")]
-            public void AssertConnectionValid([CallerMemberName] string memberName = null, [CallerFilePath] string fileName = null, [CallerLineNumber] int lineNumber = 0)
+            public void AssertConnectionValid([CallerMemberName] string? memberName = null, [CallerFilePath] string? fileName = null, [CallerLineNumber] int lineNumber = 0)
             {
             {
                 AssertInConnectionLock(memberName, fileName, lineNumber);
                 AssertInConnectionLock(memberName, fileName, lineNumber);
                 SafeAssert(CurrentConnectionStateUnsynchronized != null, "We don't have a connection!", memberName, fileName, lineNumber);
                 SafeAssert(CurrentConnectionStateUnsynchronized != null, "We don't have a connection!", memberName, fileName, lineNumber);
             }
             }
 
 
-            public Task WaitConnectionLockAsync(CancellationToken token, [CallerMemberName] string memberName = null, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0)
+            public Task WaitConnectionLockAsync(CancellationToken token, [CallerMemberName] string? memberName = null, [CallerFilePath] string? filePath = null, [CallerLineNumber] int lineNumber = 0)
             {
             {
                 Log.WaitingOnConnectionLock(_logger, memberName, filePath, lineNumber);
                 Log.WaitingOnConnectionLock(_logger, memberName, filePath, lineNumber);
                 return _connectionLock.WaitAsync(token);
                 return _connectionLock.WaitAsync(token);
@@ -1999,7 +1999,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
             }
 
 
             // Don't call this method in a try/finally that releases the lock since we're also potentially releasing the connection lock here.
             // Don't call this method in a try/finally that releases the lock since we're also potentially releasing the connection lock here.
-            public async Task<ConnectionState> WaitForActiveConnectionAsync(string methodName, CancellationToken token, [CallerMemberName] string memberName = null, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0)
+            public async Task<ConnectionState> WaitForActiveConnectionAsync(string methodName, CancellationToken token, [CallerMemberName] string? memberName = null, [CallerFilePath] string? filePath = null, [CallerLineNumber] int lineNumber = 0)
             {
             {
                 await WaitConnectionLockAsync(token, methodName);
                 await WaitConnectionLockAsync(token, methodName);
 
 
@@ -2012,8 +2012,8 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 return CurrentConnectionStateUnsynchronized;
                 return CurrentConnectionStateUnsynchronized;
             }
             }
 
 
-            public void ReleaseConnectionLock([CallerMemberName] string memberName = null,
-                [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0)
+            public void ReleaseConnectionLock([CallerMemberName] string? memberName = null,
+                [CallerFilePath] string? filePath = null, [CallerLineNumber] int lineNumber = 0)
             {
             {
                 Log.ReleasingConnectionLock(_logger, memberName, filePath, lineNumber);
                 Log.ReleasingConnectionLock(_logger, memberName, filePath, lineNumber);
                 _connectionLock.Release();
                 _connectionLock.Release();

+ 3 - 3
src/SignalR/clients/csharp/Client.Core/src/HubConnectionBuilder.cs

@@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             var endPoint = serviceProvider.GetService<EndPoint>() ??
             var endPoint = serviceProvider.GetService<EndPoint>() ??
                 throw new InvalidOperationException($"Cannot create {nameof(HubConnection)} instance. An {nameof(EndPoint)} was not configured.");
                 throw new InvalidOperationException($"Cannot create {nameof(HubConnection)} instance. An {nameof(EndPoint)} was not configured.");
 
 
-            return serviceProvider.GetService<HubConnection>();
+            return serviceProvider.GetRequiredService<HubConnection>();
         }
         }
 
 
         // Prevents from being displayed in intellisense
         // Prevents from being displayed in intellisense
@@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         // Prevents from being displayed in intellisense
         // Prevents from being displayed in intellisense
         /// <inheritdoc />
         /// <inheritdoc />
         [EditorBrowsable(EditorBrowsableState.Never)]
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
         {
             return base.Equals(obj);
             return base.Equals(obj);
         }
         }
@@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         // Prevents from being displayed in intellisense
         // Prevents from being displayed in intellisense
         /// <inheritdoc />
         /// <inheritdoc />
         [EditorBrowsable(EditorBrowsableState.Never)]
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public override string ToString()
+        public override string? ToString()
         {
         {
             return base.ToString();
             return base.ToString();
         }
         }

+ 12 - 12
src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.InvokeAsync.cs

@@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         public static Task InvokeAsync(this HubConnection hubConnection, string methodName, CancellationToken cancellationToken = default)
         public static Task InvokeAsync(this HubConnection hubConnection, string methodName, CancellationToken cancellationToken = default)
         {
         {
-            return hubConnection.InvokeCoreAsync(methodName, Array.Empty<object>(), cancellationToken);
+            return hubConnection.InvokeCoreAsync(methodName, Array.Empty<object?>(), cancellationToken);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1 }, cancellationToken);
         }
         }
@@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2 }, cancellationToken);
         }
         }
@@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
         }
         }
@@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
         }
         }
@@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
         }
         }
@@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
         }
         }
@@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
         }
         }
@@ -161,7 +161,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
         }
         }
@@ -183,7 +183,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
         }
         }
@@ -206,7 +206,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, CancellationToken cancellationToken = default)
+        public static Task InvokeAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
             return hubConnection.InvokeCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
         }
         }
@@ -219,7 +219,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="args">The arguments used to invoke the server method.</param>
         /// <param name="args">The arguments used to invoke the server method.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
-        public static Task InvokeCoreAsync(this HubConnection hubConnection, string methodName, object[] args, CancellationToken cancellationToken = default)
+        public static Task InvokeCoreAsync(this HubConnection hubConnection, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             if (hubConnection == null)
             if (hubConnection == null)
             {
             {

+ 12 - 12
src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.InvokeAsyncGeneric.cs

@@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1 }, cancellationToken);
         }
         }
@@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2 }, cancellationToken);
         }
         }
@@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
         }
         }
@@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
         }
         }
@@ -125,7 +125,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
         }
         }
@@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
         }
         }
@@ -172,7 +172,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
         }
         }
@@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
         }
         }
@@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
         }
         }
@@ -250,7 +250,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, CancellationToken cancellationToken = default)
+        public static Task<TResult> InvokeAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
             return hubConnection.InvokeCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
         }
         }
@@ -267,14 +267,14 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="Task{TResult}"/> that represents the asynchronous invoke.
         /// A <see cref="Task{TResult}"/> that represents the asynchronous invoke.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// The <see cref="Task{TResult}.Result"/> property returns a <typeparamref name="TResult"/> for the hub method return value.
         /// </returns>
         /// </returns>
-        public static async Task<TResult> InvokeCoreAsync<TResult>(this HubConnection hubConnection, string methodName, object[] args, CancellationToken cancellationToken = default)
+        public static async Task<TResult> InvokeCoreAsync<TResult>(this HubConnection hubConnection, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             if (hubConnection == null)
             if (hubConnection == null)
             {
             {
                 throw new ArgumentNullException(nameof(hubConnection));
                 throw new ArgumentNullException(nameof(hubConnection));
             }
             }
 
 
-            return (TResult)await hubConnection.InvokeCoreAsync(methodName, typeof(TResult), args, cancellationToken);
+            return (TResult)(await hubConnection.InvokeCoreAsync(methodName, typeof(TResult), args, cancellationToken))!;
         }
         }
 
 
     }
     }

+ 10 - 10
src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.SendAsync.cs

@@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1 }, cancellationToken);
         }
         }
@@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2 }, cancellationToken);
         }
         }
@@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
         }
         }
@@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
         }
         }
@@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
         }
         }
@@ -127,7 +127,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
         }
         }
@@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7,  CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7,  CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
         }
         }
@@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
         }
         }
@@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
         }
         }
@@ -217,7 +217,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous invoke.</returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task SendAsync(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, CancellationToken cancellationToken = default)
+        public static Task SendAsync(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
             return hubConnection.SendCoreAsync(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
         }
         }

+ 12 - 12
src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.StreamAsChannelAsync.cs

@@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1 }, cancellationToken);
         }
         }
@@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2 }, cancellationToken);
         }
         }
@@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
         }
         }
@@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
         }
         }
@@ -126,7 +126,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
         }
         }
@@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
         }
         }
@@ -173,7 +173,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
         }
         }
@@ -198,7 +198,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
         }
         }
@@ -224,7 +224,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
         }
         }
@@ -251,7 +251,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, CancellationToken cancellationToken = default)
+        public static Task<ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
             return hubConnection.StreamAsChannelCoreAsync<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
         }
         }
@@ -268,7 +268,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="Task{TResult}"/> that represents the asynchronous invoke.
         /// A <see cref="Task{TResult}"/> that represents the asynchronous invoke.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// The <see cref="Task{TResult}.Result"/> property returns a <see cref="ChannelReader{T}"/> for the streamed hub method values.
         /// </returns>
         /// </returns>
-        public static async Task<ChannelReader<TResult>> StreamAsChannelCoreAsync<TResult>(this HubConnection hubConnection, string methodName, object[] args, CancellationToken cancellationToken = default)
+        public static async Task<ChannelReader<TResult>> StreamAsChannelCoreAsync<TResult>(this HubConnection hubConnection, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             if (hubConnection == null)
             if (hubConnection == null)
             {
             {
@@ -288,7 +288,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
                     {
                     {
                         while (inputChannel.TryRead(out var item))
                         while (inputChannel.TryRead(out var item))
                         {
                         {
-                            while (!outputChannel.Writer.TryWrite((TResult)item))
+                            while (!outputChannel.Writer.TryWrite((TResult)item!))
                             {
                             {
                                 if (!await outputChannel.Writer.WaitToWriteAsync())
                                 if (!await outputChannel.Writer.WaitToWriteAsync())
                                 {
                                 {

+ 10 - 12
src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.StreamAsync.cs

@@ -3,8 +3,6 @@
 
 
 using System;
 using System;
 using System.Threading;
 using System.Threading;
-using System.Threading.Tasks;
-using System.Threading.Channels;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.CodeAnalysis;
 
 
@@ -43,7 +41,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1 }, cancellationToken);
         }
         }
@@ -61,7 +59,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2 }, cancellationToken);
         }
         }
@@ -80,7 +78,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3 }, cancellationToken);
         }
         }
@@ -100,7 +98,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4 }, cancellationToken);
         }
         }
@@ -121,7 +119,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5 }, cancellationToken);
         }
         }
@@ -143,7 +141,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6 }, cancellationToken);
         }
         }
@@ -166,7 +164,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }, cancellationToken);
         }
         }
@@ -190,7 +188,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }, cancellationToken);
         }
         }
@@ -215,7 +213,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }, cancellationToken);
         }
         }
@@ -241,7 +239,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// A <see cref="IAsyncEnumerable{TResult}"/> that represents the stream.
         /// </returns>
         /// </returns>
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
         [SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "Required to maintain compatibility")]
-        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<TResult> StreamAsync<TResult>(this HubConnection hubConnection, string methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, CancellationToken cancellationToken = default)
         {
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
         }
         }

+ 20 - 20
src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.cs

@@ -11,11 +11,11 @@ namespace Microsoft.AspNetCore.SignalR.Client
     /// </summary>
     /// </summary>
     public static partial class HubConnectionExtensions
     public static partial class HubConnectionExtensions
     {
     {
-        private static IDisposable On(this HubConnection hubConnection, string methodName, Type[] parameterTypes, Action<object[]> handler)
+        private static IDisposable On(this HubConnection hubConnection, string methodName, Type[] parameterTypes, Action<object?[]> handler)
         {
         {
             return hubConnection.On(methodName, parameterTypes, (parameters, state) =>
             return hubConnection.On(methodName, parameterTypes, (parameters, state) =>
             {
             {
-                var currentHandler = (Action<object[]>)state;
+                var currentHandler = (Action<object?[]>)state;
                 currentHandler(parameters);
                 currentHandler(parameters);
                 return Task.CompletedTask;
                 return Task.CompletedTask;
             }, handler);
             }, handler);
@@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1) },
                 new[] { typeof(T1) },
-                args => handler((T1)args[0]));
+                args => handler((T1)args[0]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2) },
                 new[] { typeof(T1), typeof(T2) },
-                args => handler((T1)args[0], (T2)args[1]));
+                args => handler((T1)args[0]!, (T2)args[1]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3) },
                 new[] { typeof(T1), typeof(T2), typeof(T3) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -145,7 +145,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!, (T6)args[5]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -196,7 +196,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5], (T7)args[6]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!, (T6)args[5]!, (T7)args[6]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5], (T7)args[6], (T8)args[7]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!, (T6)args[5]!, (T7)args[6]!, (T8)args[7]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -234,11 +234,11 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <param name="parameterTypes">The parameters types expected by the hub method.</param>
         /// <param name="parameterTypes">The parameters types expected by the hub method.</param>
         /// <param name="handler">The handler that will be raised when the hub method is invoked.</param>
         /// <param name="handler">The handler that will be raised when the hub method is invoked.</param>
         /// <returns>A subscription that can be disposed to unsubscribe from the hub method.</returns>
         /// <returns>A subscription that can be disposed to unsubscribe from the hub method.</returns>
-        public static IDisposable On(this HubConnection hubConnection, string methodName, Type[] parameterTypes, Func<object[], Task> handler)
+        public static IDisposable On(this HubConnection hubConnection, string methodName, Type[] parameterTypes, Func<object?[], Task> handler)
         {
         {
             return hubConnection.On(methodName, parameterTypes, (parameters, state) =>
             return hubConnection.On(methodName, parameterTypes, (parameters, state) =>
             {
             {
-                var currentHandler = (Func<object[], Task>)state;
+                var currentHandler = (Func<object?[], Task>)state;
                 return currentHandler(parameters);
                 return currentHandler(parameters);
             }, handler);
             }, handler);
         }
         }
@@ -277,7 +277,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1) },
                 new[] { typeof(T1) },
-                args => handler((T1)args[0]));
+                args => handler((T1)args[0]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -298,7 +298,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2) },
                 new[] { typeof(T1), typeof(T2) },
-                args => handler((T1)args[0], (T2)args[1]));
+                args => handler((T1)args[0]!, (T2)args[1]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -320,7 +320,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3) },
                 new[] { typeof(T1), typeof(T2), typeof(T3) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -343,7 +343,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -367,7 +367,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -392,7 +392,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!, (T6)args[5]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -418,7 +418,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5], (T7)args[6]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!, (T6)args[5]!, (T7)args[6]!));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -445,7 +445,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
 
             return hubConnection.On(methodName,
             return hubConnection.On(methodName,
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) },
                 new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8) },
-                args => handler((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3], (T5)args[4], (T6)args[5], (T7)args[6], (T8)args[7]));
+                args => handler((T1)args[0]!, (T2)args[1]!, (T3)args[2]!, (T4)args[3]!, (T5)args[4]!, (T6)args[5]!, (T7)args[6]!, (T8)args[7]!));
         }
         }
     }
     }
 }
 }

+ 7 - 7
src/SignalR/clients/csharp/Client.Core/src/Internal/ConnectionLogScope.cs

@@ -8,15 +8,15 @@ using System.Globalization;
 
 
 namespace Microsoft.AspNetCore.SignalR.Client.Internal
 namespace Microsoft.AspNetCore.SignalR.Client.Internal
 {
 {
-    internal class ConnectionLogScope : IReadOnlyList<KeyValuePair<string, object>>
+    internal class ConnectionLogScope : IReadOnlyList<KeyValuePair<string, object?>>
     {
     {
         // Name chosen so as not to collide with Kestrel's "ConnectionId"
         // Name chosen so as not to collide with Kestrel's "ConnectionId"
         private const string ClientConnectionIdKey = "ClientConnectionId";
         private const string ClientConnectionIdKey = "ClientConnectionId";
 
 
-        private string _cachedToString;
-        private string _connectionId;
+        private string? _cachedToString;
+        private string? _connectionId;
 
 
-        public string ConnectionId
+        public string? ConnectionId
         {
         {
             get => _connectionId;
             get => _connectionId;
             set
             set
@@ -26,13 +26,13 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
             }
             }
         }
         }
 
 
-        public KeyValuePair<string, object> this[int index]
+        public KeyValuePair<string, object?> this[int index]
         {
         {
             get
             get
             {
             {
                 if (index == 0)
                 if (index == 0)
                 {
                 {
-                    return new KeyValuePair<string, object>(ClientConnectionIdKey, ConnectionId);
+                    return new KeyValuePair<string, object?>(ClientConnectionIdKey, ConnectionId);
                 }
                 }
 
 
                 throw new ArgumentOutOfRangeException(nameof(index));
                 throw new ArgumentOutOfRangeException(nameof(index));
@@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
 
 
         public int Count => string.IsNullOrEmpty(ConnectionId) ? 0 : 1;
         public int Count => string.IsNullOrEmpty(ConnectionId) ? 0 : 1;
 
 
-        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+        public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
         {
         {
             for (var i = 0; i < Count; ++i)
             for (var i = 0; i < Count; ++i)
             {
             {

+ 16 - 16
src/SignalR/clients/csharp/Client.Core/src/Internal/InvocationRequest.cs

@@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
 
 
         protected InvocationRequest(CancellationToken cancellationToken, Type resultType, string invocationId, ILogger logger, HubConnection hubConnection)
         protected InvocationRequest(CancellationToken cancellationToken, Type resultType, string invocationId, ILogger logger, HubConnection hubConnection)
         {
         {
-            _cancellationTokenRegistration = cancellationToken.Register(self => ((InvocationRequest)self).Cancel(), this);
+            _cancellationTokenRegistration = cancellationToken.Register(self => ((InvocationRequest)self!).Cancel(), this);
 
 
             InvocationId = invocationId;
             InvocationId = invocationId;
             CancellationToken = cancellationToken;
             CancellationToken = cancellationToken;
@@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
             Log.InvocationCreated(Logger, InvocationId);
             Log.InvocationCreated(Logger, InvocationId);
         }
         }
 
 
-        public static InvocationRequest Invoke(CancellationToken cancellationToken, Type resultType, string invocationId, ILoggerFactory loggerFactory, HubConnection hubConnection, out Task<object> result)
+        public static InvocationRequest Invoke(CancellationToken cancellationToken, Type resultType, string invocationId, ILoggerFactory loggerFactory, HubConnection hubConnection, out Task<object?> result)
         {
         {
             var req = new NonStreaming(cancellationToken, resultType, invocationId, loggerFactory, hubConnection);
             var req = new NonStreaming(cancellationToken, resultType, invocationId, loggerFactory, hubConnection);
             result = req.Result;
             result = req.Result;
@@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
         }
         }
 
 
         public static InvocationRequest Stream(CancellationToken cancellationToken, Type resultType, string invocationId,
         public static InvocationRequest Stream(CancellationToken cancellationToken, Type resultType, string invocationId,
-            ILoggerFactory loggerFactory, HubConnection hubConnection, out ChannelReader<object> result)
+            ILoggerFactory loggerFactory, HubConnection hubConnection, out ChannelReader<object?> result)
         {
         {
             var req = new Streaming(cancellationToken, resultType, invocationId, loggerFactory, hubConnection);
             var req = new Streaming(cancellationToken, resultType, invocationId, loggerFactory, hubConnection);
             result = req.Result;
             result = req.Result;
@@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
 
 
         public abstract void Fail(Exception exception);
         public abstract void Fail(Exception exception);
         public abstract void Complete(CompletionMessage message);
         public abstract void Complete(CompletionMessage message);
-        public abstract ValueTask<bool> StreamItem(object item);
+        public abstract ValueTask<bool> StreamItem(object? item);
 
 
         protected abstract void Cancel();
         protected abstract void Cancel();
 
 
@@ -67,14 +67,14 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
 
 
         private class Streaming : InvocationRequest
         private class Streaming : InvocationRequest
         {
         {
-            private readonly Channel<object> _channel = Channel.CreateUnbounded<object>();
+            private readonly Channel<object?> _channel = Channel.CreateUnbounded<object?>();
 
 
             public Streaming(CancellationToken cancellationToken, Type resultType, string invocationId, ILoggerFactory loggerFactory, HubConnection hubConnection)
             public Streaming(CancellationToken cancellationToken, Type resultType, string invocationId, ILoggerFactory loggerFactory, HubConnection hubConnection)
                 : base(cancellationToken, resultType, invocationId, loggerFactory.CreateLogger<Streaming>(), hubConnection)
                 : base(cancellationToken, resultType, invocationId, loggerFactory.CreateLogger<Streaming>(), hubConnection)
             {
             {
             }
             }
 
 
-            public ChannelReader<object> Result => _channel.Reader;
+            public ChannelReader<object?> Result => _channel.Reader;
 
 
             public override void Complete(CompletionMessage completionMessage)
             public override void Complete(CompletionMessage completionMessage)
             {
             {
@@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
                 _channel.Writer.TryComplete(exception);
                 _channel.Writer.TryComplete(exception);
             }
             }
 
 
-            public override async ValueTask<bool> StreamItem(object item)
+            public override async ValueTask<bool> StreamItem(object? item)
             {
             {
                 try
                 try
                 {
                 {
@@ -127,14 +127,14 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
 
 
         private class NonStreaming : InvocationRequest
         private class NonStreaming : InvocationRequest
         {
         {
-            private readonly TaskCompletionSource<object> _completionSource = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
+            private readonly TaskCompletionSource<object?> _completionSource = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
 
 
             public NonStreaming(CancellationToken cancellationToken, Type resultType, string invocationId, ILoggerFactory loggerFactory, HubConnection hubConnection)
             public NonStreaming(CancellationToken cancellationToken, Type resultType, string invocationId, ILoggerFactory loggerFactory, HubConnection hubConnection)
                 : base(cancellationToken, resultType, invocationId, loggerFactory.CreateLogger<NonStreaming>(), hubConnection)
                 : base(cancellationToken, resultType, invocationId, loggerFactory.CreateLogger<NonStreaming>(), hubConnection)
             {
             {
             }
             }
 
 
-            public Task<object> Result => _completionSource.Task;
+            public Task<object?> Result => _completionSource.Task;
 
 
             public override void Complete(CompletionMessage completionMessage)
             public override void Complete(CompletionMessage completionMessage)
             {
             {
@@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
                 _completionSource.TrySetException(exception);
                 _completionSource.TrySetException(exception);
             }
             }
 
 
-            public override ValueTask<bool> StreamItem(object item)
+            public override ValueTask<bool> StreamItem(object? item)
             {
             {
                 Log.StreamItemOnNonStreamInvocation(Logger, InvocationId);
                 Log.StreamItemOnNonStreamInvocation(Logger, InvocationId);
                 _completionSource.TrySetException(new InvalidOperationException($"Streaming hub methods must be invoked with the '{nameof(HubConnection)}.{nameof(HubConnectionExtensions.StreamAsChannelAsync)}' method."));
                 _completionSource.TrySetException(new InvalidOperationException($"Streaming hub methods must be invoked with the '{nameof(HubConnection)}.{nameof(HubConnectionExtensions.StreamAsChannelAsync)}' method."));
@@ -172,27 +172,27 @@ namespace Microsoft.AspNetCore.SignalR.Client.Internal
         private static class Log
         private static class Log
         {
         {
             // Category: Streaming and NonStreaming
             // Category: Streaming and NonStreaming
-            private static readonly Action<ILogger, string, Exception> _invocationCreated =
+            private static readonly Action<ILogger, string, Exception?> _invocationCreated =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(1, "InvocationCreated"), "Invocation {InvocationId} created.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(1, "InvocationCreated"), "Invocation {InvocationId} created.");
 
 
-            private static readonly Action<ILogger, string, Exception> _invocationDisposed =
+            private static readonly Action<ILogger, string, Exception?> _invocationDisposed =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(2, "InvocationDisposed"), "Invocation {InvocationId} disposed.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(2, "InvocationDisposed"), "Invocation {InvocationId} disposed.");
 
 
-            private static readonly Action<ILogger, string, Exception> _invocationCompleted =
+            private static readonly Action<ILogger, string, Exception?> _invocationCompleted =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(3, "InvocationCompleted"), "Invocation {InvocationId} marked as completed.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(3, "InvocationCompleted"), "Invocation {InvocationId} marked as completed.");
 
 
-            private static readonly Action<ILogger, string, Exception> _invocationFailed =
+            private static readonly Action<ILogger, string, Exception?> _invocationFailed =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(4, "InvocationFailed"), "Invocation {InvocationId} marked as failed.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(4, "InvocationFailed"), "Invocation {InvocationId} marked as failed.");
 
 
             // Category: Streaming
             // Category: Streaming
             private static readonly Action<ILogger, string, Exception> _errorWritingStreamItem =
             private static readonly Action<ILogger, string, Exception> _errorWritingStreamItem =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(5, "ErrorWritingStreamItem"), "Invocation {InvocationId} caused an error trying to write a stream item.");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(5, "ErrorWritingStreamItem"), "Invocation {InvocationId} caused an error trying to write a stream item.");
 
 
-            private static readonly Action<ILogger, string, Exception> _receivedUnexpectedComplete =
+            private static readonly Action<ILogger, string, Exception?> _receivedUnexpectedComplete =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(6, "ReceivedUnexpectedComplete"), "Invocation {InvocationId} received a completion result, but was invoked as a streaming invocation.");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(6, "ReceivedUnexpectedComplete"), "Invocation {InvocationId} received a completion result, but was invoked as a streaming invocation.");
 
 
             // Category: NonStreaming
             // Category: NonStreaming
-            private static readonly Action<ILogger, string, Exception> _streamItemOnNonStreamInvocation =
+            private static readonly Action<ILogger, string, Exception?> _streamItemOnNonStreamInvocation =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(5, "StreamItemOnNonStreamInvocation"), "Invocation {InvocationId} received stream item but was invoked as a non-streamed invocation.");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(5, "StreamItemOnNonStreamInvocation"), "Invocation {InvocationId} received stream item but was invoked as a non-streamed invocation.");
 
 
             public static void InvocationCreated(ILogger logger, string invocationId)
             public static void InvocationCreated(ILogger logger, string invocationId)

+ 1 - 0
src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj

@@ -4,6 +4,7 @@
     <Description>Client for ASP.NET Core SignalR</Description>
     <Description>Client for ASP.NET Core SignalR</Description>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1</TargetFrameworks>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1</TargetFrameworks>
     <RootNamespace>Microsoft.AspNetCore.SignalR.Client</RootNamespace>
     <RootNamespace>Microsoft.AspNetCore.SignalR.Client</RootNamespace>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 208 - 0
src/SignalR/clients/csharp/Client.Core/src/PublicAPI.Unshipped.txt

@@ -1 +1,209 @@
 #nullable enable
 #nullable enable
+*REMOVED*Microsoft.AspNetCore.SignalR.Client.HubConnection.Closed -> System.Func<System.Exception, System.Threading.Tasks.Task>
+*REMOVED*Microsoft.AspNetCore.SignalR.Client.HubConnection.Reconnecting -> System.Func<System.Exception, System.Threading.Tasks.Task>
+*REMOVED*Microsoft.AspNetCore.SignalR.Client.HubConnection.Reconnected -> System.Func<string, System.Threading.Tasks.Task>
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.ConnectionId.get -> string
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.Net.EndPoint endPoint, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.Net.EndPoint endPoint, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy reconnectPolicy) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.StopAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) -> System.IDisposable
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.Remove(string methodName) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.StreamAsChannelCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<object>>
+*REMOVED*Microsoft.AspNetCore.SignalR.Client.HubConnection.InvokeCoreAsync(string! methodName, System.Type! returnType, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<object?>!
+*REMOVED*Microsoft.AspNetCore.SignalR.Client.HubConnection.SendCoreAsync(string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnection.StreamAsyncCore<TResult>(string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Type[] parameterTypes, System.Func<object[], System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7, T8>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3, T4, T5, T6, T7, T8> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7, T8>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3, T4, T5, T6, T7> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, T3, T4, T5, T6, T7, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3, T4, T5, T6> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, T3, T4, T5, T6, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3, T4, T5> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, T3, T4, T5, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3, T4> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, T3, T4, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, T3, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1> handler) -> System.IDisposable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, System.Threading.Tasks.Task> handler) -> System.IDisposable
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.Build() -> Microsoft.AspNetCore.SignalR.Client.HubConnection
+*REMOVED*~override Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.Equals(object obj) -> bool
+*REMOVED*~override Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.ToString() -> string
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.GetType() -> System.Type
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.RetryContext.RetryReason.get -> System.Exception
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.RetryContext.RetryReason.set -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.IRetryPolicy.NextRetryDelay(Microsoft.AspNetCore.SignalR.Client.RetryContext retryContext) -> System.TimeSpan?
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.ConfigureLogging(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.Action<Microsoft.Extensions.Logging.ILoggingBuilder> configureLogging) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy retryPolicy) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.TimeSpan[] reconnectDelays) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder.Build() -> Microsoft.AspNetCore.SignalR.Client.HubConnection
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeCoreAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeCoreAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelCoreAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>
+Microsoft.AspNetCore.SignalR.Client.HubConnection.Closed -> System.Func<System.Exception?, System.Threading.Tasks.Task!>?
+Microsoft.AspNetCore.SignalR.Client.HubConnection.Reconnecting -> System.Func<System.Exception?, System.Threading.Tasks.Task!>?
+Microsoft.AspNetCore.SignalR.Client.HubConnection.Reconnected -> System.Func<string?, System.Threading.Tasks.Task!>?
+Microsoft.AspNetCore.SignalR.Client.HubConnection.ConnectionId.get -> string?
+Microsoft.AspNetCore.SignalR.Client.HubConnection.HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory! connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol! protocol, System.Net.EndPoint! endPoint, System.IServiceProvider! serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void
+Microsoft.AspNetCore.SignalR.Client.HubConnection.HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory! connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol! protocol, System.Net.EndPoint! endPoint, System.IServiceProvider! serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy! reconnectPolicy) -> void
+Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.AspNetCore.SignalR.Client.HubConnection.StopAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.AspNetCore.SignalR.Client.HubConnection.On(string! methodName, System.Type![]! parameterTypes, System.Func<object?[]!, object!, System.Threading.Tasks.Task!>! handler, object! state) -> System.IDisposable!
+Microsoft.AspNetCore.SignalR.Client.HubConnection.Remove(string! methodName) -> void
+Microsoft.AspNetCore.SignalR.Client.HubConnection.StreamAsChannelCoreAsync(string! methodName, System.Type! returnType, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<object?>!>!
+Microsoft.AspNetCore.SignalR.Client.HubConnection.InvokeCoreAsync(string! methodName, System.Type! returnType, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<object?>!
+Microsoft.AspNetCore.SignalR.Client.HubConnection.SendCoreAsync(string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.AspNetCore.SignalR.Client.HubConnection.StreamAsyncCore<TResult>(string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Type![]! parameterTypes, System.Func<object?[]!, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7, T8>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1, T2, T3, T4, T5, T6, T7, T8>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7, T8>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, T2, T3, T4, T5, T6, T7, T8, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1, T2, T3, T4, T5, T6, T7>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6, T7>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, T2, T3, T4, T5, T6, T7, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1, T2, T3, T4, T5, T6>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5, T6>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, T2, T3, T4, T5, T6, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1, T2, T3, T4, T5>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4, T5>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, T2, T3, T4, T5, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1, T2, T3, T4>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3, T4>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, T2, T3, T4, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1, T2, T3>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2, T3>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, T2, T3, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1, T2>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1, T2>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, T2, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Action<T1>! handler) -> System.IDisposable!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.On<T1>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Func<T1, System.Threading.Tasks.Task!>! handler) -> System.IDisposable!
+Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
+Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.Build() -> Microsoft.AspNetCore.SignalR.Client.HubConnection!
+override Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.Equals(object? obj) -> bool
+override Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.ToString() -> string?
+Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.GetType() -> System.Type!
+Microsoft.AspNetCore.SignalR.Client.RetryContext.RetryReason.get -> System.Exception?
+Microsoft.AspNetCore.SignalR.Client.RetryContext.RetryReason.set -> void
+Microsoft.AspNetCore.SignalR.Client.IRetryPolicy.NextRetryDelay(Microsoft.AspNetCore.SignalR.Client.RetryContext! retryContext) -> System.TimeSpan?
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.ConfigureLogging(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, System.Action<Microsoft.Extensions.Logging.ILoggingBuilder!>! configureLogging) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy! retryPolicy) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderExtensions.WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, System.TimeSpan[]! reconnectDelays) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder.Build() -> Microsoft.AspNetCore.SignalR.Client.HubConnection!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeCoreAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.InvokeCoreAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsChannelCoreAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>!>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionExtensions.StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection! hubConnection, string! methodName, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9, object? arg10, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerable<TResult>!

+ 1 - 1
src/SignalR/clients/csharp/Client.Core/src/RetryContext.cs

@@ -24,6 +24,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
         /// <summary>
         /// <summary>
         /// The error precipitating the current retry if any.
         /// The error precipitating the current retry if any.
         /// </summary>
         /// </summary>
-        public Exception RetryReason { get; set; }
+        public Exception? RetryReason { get; set; }
     }
     }
 }
 }

+ 2 - 2
src/SignalR/clients/csharp/Client/src/HubConnectionBuilderHttpExtensions.cs

@@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
             return hubConnectionBuilder;
             return hubConnectionBuilder;
         }
         }
 
 
-        private static IHubConnectionBuilder WithUrlCore(this IHubConnectionBuilder hubConnectionBuilder, Uri url, HttpTransportType? transports, Action<HttpConnectionOptions> configureHttpConnection)
+        private static IHubConnectionBuilder WithUrlCore(this IHubConnectionBuilder hubConnectionBuilder, Uri url, HttpTransportType? transports, Action<HttpConnectionOptions>? configureHttpConnection)
         {
         {
             if (hubConnectionBuilder == null)
             if (hubConnectionBuilder == null)
             {
             {
@@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         private class HttpConnectionOptionsDerivedHttpEndPoint : UriEndPoint
         private class HttpConnectionOptionsDerivedHttpEndPoint : UriEndPoint
         {
         {
             public HttpConnectionOptionsDerivedHttpEndPoint(IOptions<HttpConnectionOptions> httpConnectionOptions)
             public HttpConnectionOptionsDerivedHttpEndPoint(IOptions<HttpConnectionOptions> httpConnectionOptions)
-                : base(httpConnectionOptions.Value.Url)
+                : base(httpConnectionOptions.Value.Url!)
             {
             {
             }
             }
         }
         }

+ 1 - 0
src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj

@@ -3,6 +3,7 @@
   <PropertyGroup>
   <PropertyGroup>
     <Description>Client for ASP.NET Core SignalR</Description>
     <Description>Client for ASP.NET Core SignalR</Description>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0</TargetFrameworks>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0</TargetFrameworks>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 16 - 0
src/SignalR/clients/csharp/Client/src/PublicAPI.Unshipped.txt

@@ -1 +1,17 @@
 #nullable enable
 #nullable enable
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.Uri url) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions> configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.Uri url, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions> configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, string url) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, string url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, string url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions> configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, string url, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions> configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, System.Uri! url) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, System.Uri! url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, System.Uri! url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions!>! configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, System.Uri! url, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions!>! configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, string! url) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, string! url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, string! url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions!>! configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!
+static Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder! hubConnectionBuilder, string! url, System.Action<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions!>! configureHttpConnection) -> Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder!

+ 16 - 17
src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.Log.cs

@@ -3,7 +3,6 @@
 
 
 using System;
 using System;
 using Microsoft.AspNetCore.Connections;
 using Microsoft.AspNetCore.Connections;
-using Microsoft.AspNetCore.Http.Connections.Client.Internal;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
 namespace Microsoft.AspNetCore.Http.Connections.Client
 namespace Microsoft.AspNetCore.Http.Connections.Client
@@ -12,31 +11,31 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
     {
     {
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, Exception> _starting =
+            private static readonly Action<ILogger, Exception?> _starting =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(1, "Starting"), "Starting HttpConnection.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(1, "Starting"), "Starting HttpConnection.");
 
 
-            private static readonly Action<ILogger, Exception> _skippingStart =
+            private static readonly Action<ILogger, Exception?> _skippingStart =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "SkippingStart"), "Skipping start, connection is already started.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "SkippingStart"), "Skipping start, connection is already started.");
 
 
-            private static readonly Action<ILogger, Exception> _started =
+            private static readonly Action<ILogger, Exception?> _started =
                 LoggerMessage.Define(LogLevel.Information, new EventId(3, "Started"), "HttpConnection Started.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(3, "Started"), "HttpConnection Started.");
 
 
-            private static readonly Action<ILogger, Exception> _disposingHttpConnection =
+            private static readonly Action<ILogger, Exception?> _disposingHttpConnection =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "DisposingHttpConnection"), "Disposing HttpConnection.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "DisposingHttpConnection"), "Disposing HttpConnection.");
 
 
-            private static readonly Action<ILogger, Exception> _skippingDispose =
+            private static readonly Action<ILogger, Exception?> _skippingDispose =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "SkippingDispose"), "Skipping dispose, connection is already disposed.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "SkippingDispose"), "Skipping dispose, connection is already disposed.");
 
 
-            private static readonly Action<ILogger, Exception> _disposed =
+            private static readonly Action<ILogger, Exception?> _disposed =
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "Disposed"), "HttpConnection Disposed.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "Disposed"), "HttpConnection Disposed.");
 
 
-            private static readonly Action<ILogger, string, Uri, Exception> _startingTransport =
+            private static readonly Action<ILogger, string, Uri, Exception?> _startingTransport =
                 LoggerMessage.Define<string, Uri>(LogLevel.Debug, new EventId(7, "StartingTransport"), "Starting transport '{Transport}' with Url: {Url}.");
                 LoggerMessage.Define<string, Uri>(LogLevel.Debug, new EventId(7, "StartingTransport"), "Starting transport '{Transport}' with Url: {Url}.");
 
 
-            private static readonly Action<ILogger, Uri, Exception> _establishingConnection =
+            private static readonly Action<ILogger, Uri, Exception?> _establishingConnection =
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(8, "EstablishingConnection"), "Establishing connection with server at '{Url}'.");
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(8, "EstablishingConnection"), "Establishing connection with server at '{Url}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _connectionEstablished =
+            private static readonly Action<ILogger, string, Exception?> _connectionEstablished =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(9, "Established"), "Established connection '{ConnectionId}' with the server.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(9, "Established"), "Established connection '{ConnectionId}' with the server.");
 
 
             private static readonly Action<ILogger, Uri, Exception> _errorWithNegotiation =
             private static readonly Action<ILogger, Uri, Exception> _errorWithNegotiation =
@@ -45,31 +44,31 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
             private static readonly Action<ILogger, HttpTransportType, Exception> _errorStartingTransport =
             private static readonly Action<ILogger, HttpTransportType, Exception> _errorStartingTransport =
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Error, new EventId(11, "ErrorStartingTransport"), "Failed to start connection. Error starting transport '{Transport}'.");
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Error, new EventId(11, "ErrorStartingTransport"), "Failed to start connection. Error starting transport '{Transport}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _transportNotSupported =
+            private static readonly Action<ILogger, string, Exception?> _transportNotSupported =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(12, "TransportNotSupported"), "Skipping transport {TransportName} because it is not supported by this client.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(12, "TransportNotSupported"), "Skipping transport {TransportName} because it is not supported by this client.");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _transportDoesNotSupportTransferFormat =
+            private static readonly Action<ILogger, string, string, Exception?> _transportDoesNotSupportTransferFormat =
                 LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(13, "TransportDoesNotSupportTransferFormat"), "Skipping transport {TransportName} because it does not support the requested transfer format '{TransferFormat}'.");
                 LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(13, "TransportDoesNotSupportTransferFormat"), "Skipping transport {TransportName} because it does not support the requested transfer format '{TransferFormat}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _transportDisabledByClient =
+            private static readonly Action<ILogger, string, Exception?> _transportDisabledByClient =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(14, "TransportDisabledByClient"), "Skipping transport {TransportName} because it was disabled by the client.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(14, "TransportDisabledByClient"), "Skipping transport {TransportName} because it was disabled by the client.");
 
 
             private static readonly Action<ILogger, string, Exception> _transportFailed =
             private static readonly Action<ILogger, string, Exception> _transportFailed =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(15, "TransportFailed"), "Skipping transport {TransportName} because it failed to initialize.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(15, "TransportFailed"), "Skipping transport {TransportName} because it failed to initialize.");
 
 
-            private static readonly Action<ILogger, Exception> _webSocketsNotSupportedByOperatingSystem =
+            private static readonly Action<ILogger, Exception?> _webSocketsNotSupportedByOperatingSystem =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(16, "WebSocketsNotSupportedByOperatingSystem"), "Skipping WebSockets because they are not supported by the operating system.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(16, "WebSocketsNotSupportedByOperatingSystem"), "Skipping WebSockets because they are not supported by the operating system.");
 
 
             private static readonly Action<ILogger, Exception> _transportThrewExceptionOnStop =
             private static readonly Action<ILogger, Exception> _transportThrewExceptionOnStop =
                 LoggerMessage.Define(LogLevel.Error, new EventId(17, "TransportThrewExceptionOnStop"), "The transport threw an exception while stopping.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(17, "TransportThrewExceptionOnStop"), "The transport threw an exception while stopping.");
 
 
-            private static readonly Action<ILogger, HttpTransportType, Exception> _transportStarted =
+            private static readonly Action<ILogger, HttpTransportType, Exception?> _transportStarted =
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Debug, new EventId(18, "TransportStarted"), "Transport '{Transport}' started.");
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Debug, new EventId(18, "TransportStarted"), "Transport '{Transport}' started.");
 
 
-            private static readonly Action<ILogger, Exception> _serverSentEventsNotSupportedByBrowser =
+            private static readonly Action<ILogger, Exception?> _serverSentEventsNotSupportedByBrowser =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(19, "ServerSentEventsNotSupportedByBrowser"), "Skipping ServerSentEvents because they are not supported by the browser.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(19, "ServerSentEventsNotSupportedByBrowser"), "Skipping ServerSentEvents because they are not supported by the browser.");
 
 
-            private static readonly Action<ILogger, Exception> _cookiesNotSupported =
+            private static readonly Action<ILogger, Exception?> _cookiesNotSupported =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(20, "CookiesNotSupported"), "Cookies are not supported on this platform.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(20, "CookiesNotSupported"), "Cookies are not supported on this platform.");
 
 
             public static void Starting(ILogger logger)
             public static void Starting(ILogger logger)

+ 27 - 23
src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs

@@ -8,7 +8,6 @@ using System.IO.Pipelines;
 using System.Linq;
 using System.Linq;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.WebSockets;
 using System.Net.WebSockets;
-using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Connections;
 using Microsoft.AspNetCore.Connections;
@@ -29,7 +28,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         // a buggy server
         // a buggy server
         private static readonly int _maxRedirects = 100;
         private static readonly int _maxRedirects = 100;
         private static readonly int _protocolVersionNumber = 1;
         private static readonly int _protocolVersionNumber = 1;
-        private static readonly Task<string> _noAccessToken = Task.FromResult<string>(null);
+        private static readonly Task<string?> _noAccessToken = Task.FromResult<string?>(null);
 
 
         private static readonly TimeSpan HttpClientTimeout = TimeSpan.FromSeconds(120);
         private static readonly TimeSpan HttpClientTimeout = TimeSpan.FromSeconds(120);
 
 
@@ -40,14 +39,15 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         private bool _disposed;
         private bool _disposed;
         private bool _hasInherentKeepAlive;
         private bool _hasInherentKeepAlive;
 
 
-        private readonly HttpClient _httpClient;
+        private readonly HttpClient? _httpClient;
         private readonly HttpConnectionOptions _httpConnectionOptions;
         private readonly HttpConnectionOptions _httpConnectionOptions;
-        private ITransport _transport;
+        private ITransport? _transport;
         private readonly ITransportFactory _transportFactory;
         private readonly ITransportFactory _transportFactory;
-        private string _connectionId;
+        private string? _connectionId;
         private readonly ConnectionLogScope _logScope;
         private readonly ConnectionLogScope _logScope;
         private readonly ILoggerFactory _loggerFactory;
         private readonly ILoggerFactory _loggerFactory;
-        private Func<Task<string>> _accessTokenProvider;
+        private readonly Uri _url;
+        private Func<Task<string?>>? _accessTokenProvider;
 
 
         /// <inheritdoc />
         /// <inheritdoc />
         public override IDuplexPipe Transport
         public override IDuplexPipe Transport
@@ -75,14 +75,16 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// If the connection was created with <see cref="HttpConnectionOptions.SkipNegotiation"/> set to <c>true</c>
         /// If the connection was created with <see cref="HttpConnectionOptions.SkipNegotiation"/> set to <c>true</c>
         /// then the connection ID will be <c>null</c>.
         /// then the connection ID will be <c>null</c>.
         /// </remarks>
         /// </remarks>
-        public override string ConnectionId
+        public override string? ConnectionId
         {
         {
+#pragma warning disable CS8764 // Nullability of return type doesn't match overridden member (possibly because of nullability attributes).
             get => _connectionId;
             get => _connectionId;
+#pragma warning restore CS8764 // Nullability of return type doesn't match overridden member (possibly because of nullability attributes).
             set => throw new InvalidOperationException("The ConnectionId is set internally and should not be set by user code.");
             set => throw new InvalidOperationException("The ConnectionId is set internally and should not be set by user code.");
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override IDictionary<object, object> Items { get; set; } = new ConnectionItems();
+        public override IDictionary<object, object?> Items { get; set; } = new ConnectionItems();
 
 
         /// <inheritdoc />
         /// <inheritdoc />
         bool IConnectionInherentKeepAliveFeature.HasInherentKeepAlive => _hasInherentKeepAlive;
         bool IConnectionInherentKeepAliveFeature.HasInherentKeepAlive => _hasInherentKeepAlive;
@@ -111,7 +113,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// <param name="url">The URL to connect to.</param>
         /// <param name="url">The URL to connect to.</param>
         /// <param name="transports">A bitmask combining one or more <see cref="HttpTransportType"/> values that specify what transports the client should use.</param>
         /// <param name="transports">A bitmask combining one or more <see cref="HttpTransportType"/> values that specify what transports the client should use.</param>
         /// <param name="loggerFactory">The logger factory.</param>
         /// <param name="loggerFactory">The logger factory.</param>
-        public HttpConnection(Uri url, HttpTransportType transports, ILoggerFactory loggerFactory)
+        public HttpConnection(Uri url, HttpTransportType transports, ILoggerFactory? loggerFactory)
             : this(CreateHttpOptions(url, transports), loggerFactory)
             : this(CreateHttpOptions(url, transports), loggerFactory)
         {
         {
         }
         }
@@ -130,7 +132,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// </summary>
         /// </summary>
         /// <param name="httpConnectionOptions">The connection options to use.</param>
         /// <param name="httpConnectionOptions">The connection options to use.</param>
         /// <param name="loggerFactory">The logger factory.</param>
         /// <param name="loggerFactory">The logger factory.</param>
-        public HttpConnection(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory)
+        public HttpConnection(HttpConnectionOptions httpConnectionOptions, ILoggerFactory? loggerFactory)
         {
         {
             if (httpConnectionOptions == null)
             if (httpConnectionOptions == null)
             {
             {
@@ -147,6 +149,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
             _logger = _loggerFactory.CreateLogger<HttpConnection>();
             _logger = _loggerFactory.CreateLogger<HttpConnection>();
             _httpConnectionOptions = httpConnectionOptions;
             _httpConnectionOptions = httpConnectionOptions;
 
 
+            _url = _httpConnectionOptions.Url;
+
             if (!httpConnectionOptions.SkipNegotiation || httpConnectionOptions.Transports != HttpTransportType.WebSockets)
             if (!httpConnectionOptions.SkipNegotiation || httpConnectionOptions.Transports != HttpTransportType.WebSockets)
             {
             {
                 _httpClient = CreateHttpClient();
                 _httpClient = CreateHttpClient();
@@ -272,7 +276,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
                     // The transport should also have completed the pipe with this exception.
                     // The transport should also have completed the pipe with this exception.
                     try
                     try
                     {
                     {
-                        await _transport.StopAsync();
+                        await _transport!.StopAsync();
                     }
                     }
                     catch (Exception ex)
                     catch (Exception ex)
                     {
                     {
@@ -302,7 +306,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
 
 
         private async Task SelectAndStartTransport(TransferFormat transferFormat, CancellationToken cancellationToken)
         private async Task SelectAndStartTransport(TransferFormat transferFormat, CancellationToken cancellationToken)
         {
         {
-            var uri = _httpConnectionOptions.Url;
+            var uri = _url;
             // Set the initial access token provider back to the original one from options
             // Set the initial access token provider back to the original one from options
             _accessTokenProvider = _httpConnectionOptions.AccessTokenProvider;
             _accessTokenProvider = _httpConnectionOptions.AccessTokenProvider;
 
 
@@ -322,7 +326,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
             }
             }
             else
             else
             {
             {
-                NegotiationResponse negotiationResponse;
+                NegotiationResponse? negotiationResponse;
                 var redirects = 0;
                 var redirects = 0;
 
 
                 do
                 do
@@ -338,7 +342,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
                     {
                     {
                         string accessToken = negotiationResponse.AccessToken;
                         string accessToken = negotiationResponse.AccessToken;
                         // Set the current access token factory so that future requests use this access token
                         // Set the current access token factory so that future requests use this access token
-                        _accessTokenProvider = () => Task.FromResult(accessToken);
+                        _accessTokenProvider = () => Task.FromResult<string?>(accessToken);
                     }
                     }
 
 
                     redirects++;
                     redirects++;
@@ -358,12 +362,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
                 // we don't understand in the negotiate response.
                 // we don't understand in the negotiate response.
                 var transferFormatString = transferFormat.ToString();
                 var transferFormatString = transferFormat.ToString();
 
 
-                foreach (var transport in negotiationResponse.AvailableTransports)
+                foreach (var transport in negotiationResponse.AvailableTransports!)
                 {
                 {
                     if (!Enum.TryParse<HttpTransportType>(transport.Transport, out var transportType))
                     if (!Enum.TryParse<HttpTransportType>(transport.Transport, out var transportType))
                     {
                     {
-                        Log.TransportNotSupported(_logger, transport.Transport);
-                        transportExceptions.Add(new TransportFailedException(transport.Transport, "The transport is not supported by the client."));
+                        Log.TransportNotSupported(_logger, transport.Transport!);
+                        transportExceptions.Add(new TransportFailedException(transport.Transport!, "The transport is not supported by the client."));
                         continue;
                         continue;
                     }
                     }
 
 
@@ -388,7 +392,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
                             Log.TransportDisabledByClient(_logger, transportType);
                             Log.TransportDisabledByClient(_logger, transportType);
                             transportExceptions.Add(new TransportFailedException(transportType.ToString(), "The transport is disabled by the client."));
                             transportExceptions.Add(new TransportFailedException(transportType.ToString(), "The transport is disabled by the client."));
                         }
                         }
-                        else if (!transport.TransferFormats.Contains(transferFormatString, StringComparer.Ordinal))
+                        else if (!transport.TransferFormats!.Contains(transferFormatString, StringComparer.Ordinal))
                         {
                         {
                             Log.TransportDoesNotSupportTransferFormat(_logger, transportType, transferFormat);
                             Log.TransportDoesNotSupportTransferFormat(_logger, transportType, transferFormat);
                             transportExceptions.Add(new TransportFailedException(transportType.ToString(), $"The transport does not support the '{transferFormat}' transfer format."));
                             transportExceptions.Add(new TransportFailedException(transportType.ToString(), $"The transport does not support the '{transferFormat}' transfer format."));
@@ -473,7 +477,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
                         {
                         {
                             throw new Exception(negotiateResponse.Error);
                             throw new Exception(negotiateResponse.Error);
                         }
                         }
-                        Log.ConnectionEstablished(_logger, negotiateResponse.ConnectionId);
+                        Log.ConnectionEstablished(_logger, negotiateResponse.ConnectionId!);
                         return negotiateResponse;
                         return negotiateResponse;
                     }
                     }
                 }
                 }
@@ -485,7 +489,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
             }
             }
         }
         }
 
 
-        private static Uri CreateConnectUrl(Uri url, string connectionId)
+        private static Uri CreateConnectUrl(Uri url, string? connectionId)
         {
         {
             if (string.IsNullOrWhiteSpace(connectionId))
             if (string.IsNullOrWhiteSpace(connectionId))
             {
             {
@@ -632,7 +636,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
             return httpClient;
             return httpClient;
         }
         }
 
 
-        internal Task<string> GetAccessTokenAsync()
+        internal Task<string?> GetAccessTokenAsync()
         {
         {
             if (_accessTokenProvider == null)
             if (_accessTokenProvider == null)
             {
             {
@@ -669,11 +673,11 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
 
 
         private async Task<NegotiationResponse> GetNegotiationResponseAsync(Uri uri, CancellationToken cancellationToken)
         private async Task<NegotiationResponse> GetNegotiationResponseAsync(Uri uri, CancellationToken cancellationToken)
         {
         {
-            var negotiationResponse = await NegotiateAsync(uri, _httpClient, _logger, cancellationToken);
+            var negotiationResponse = await NegotiateAsync(uri, _httpClient!, _logger, cancellationToken);
             // If the negotiationVersion is greater than zero then we know that the negotiation response contains a
             // If the negotiationVersion is greater than zero then we know that the negotiation response contains a
             // connectionToken that will be required to conenct. Otherwise we just set the connectionId and the
             // connectionToken that will be required to conenct. Otherwise we just set the connectionId and the
             // connectionToken on the client to the same value.
             // connectionToken on the client to the same value.
-            _connectionId = negotiationResponse.ConnectionId;
+            _connectionId = negotiationResponse.ConnectionId!;
             if (negotiationResponse.Version == 0)
             if (negotiationResponse.Version == 0)
             {
             {
                 negotiationResponse.ConnectionToken = _connectionId;
                 negotiationResponse.ConnectionToken = _connectionId;

+ 0 - 1
src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs

@@ -3,7 +3,6 @@
 
 
 using System;
 using System;
 using System.Net;
 using System.Net;
-using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Connections;
 using Microsoft.AspNetCore.Connections;

+ 11 - 12
src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs

@@ -6,7 +6,6 @@ using System.Collections.Generic;
 using System.Net;
 using System.Net;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.WebSockets;
 using System.Net.WebSockets;
-using System.Runtime.InteropServices;
 using System.Runtime.Versioning;
 using System.Runtime.Versioning;
 using System.Security.Cryptography.X509Certificates;
 using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Threading;
@@ -21,12 +20,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
     public class HttpConnectionOptions
     public class HttpConnectionOptions
     {
     {
         private IDictionary<string, string> _headers;
         private IDictionary<string, string> _headers;
-        private X509CertificateCollection _clientCertificates;
+        private X509CertificateCollection? _clientCertificates;
         private CookieContainer _cookies;
         private CookieContainer _cookies;
-        private ICredentials _credentials;
-        private IWebProxy _proxy;
+        private ICredentials? _credentials;
+        private IWebProxy? _proxy;
         private bool? _useDefaultCredentials;
         private bool? _useDefaultCredentials;
-        private Action<ClientWebSocketOptions> _webSocketConfiguration;
+        private Action<ClientWebSocketOptions>? _webSocketConfiguration;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="HttpConnectionOptions"/> class.
         /// Initializes a new instance of the <see cref="HttpConnectionOptions"/> class.
@@ -50,7 +49,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// Gets or sets a delegate for wrapping or replacing the <see cref="HttpMessageHandlerFactory"/>
         /// Gets or sets a delegate for wrapping or replacing the <see cref="HttpMessageHandlerFactory"/>
         /// that will make HTTP requests.
         /// that will make HTTP requests.
         /// </summary>
         /// </summary>
-        public Func<HttpMessageHandler, HttpMessageHandler> HttpMessageHandlerFactory { get; set; }
+        public Func<HttpMessageHandler, HttpMessageHandler>? HttpMessageHandlerFactory { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets or sets a collection of headers that will be sent with HTTP requests.
         /// Gets or sets a collection of headers that will be sent with HTTP requests.
@@ -65,7 +64,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// Gets or sets a collection of client certificates that will be sent with HTTP requests.
         /// Gets or sets a collection of client certificates that will be sent with HTTP requests.
         /// </summary>
         /// </summary>
         [UnsupportedOSPlatform("browser")]
         [UnsupportedOSPlatform("browser")]
-        public X509CertificateCollection ClientCertificates
+        public X509CertificateCollection? ClientCertificates
         {
         {
             get
             get
             {
             {
@@ -100,7 +99,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// <summary>
         /// <summary>
         /// Gets or sets the URL used to send HTTP requests.
         /// Gets or sets the URL used to send HTTP requests.
         /// </summary>
         /// </summary>
-        public Uri Url { get; set; }
+        public Uri? Url { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets or sets a bitmask combining one or more <see cref="HttpTransportType"/> values that specify what transports the client should use to send HTTP requests.
         /// Gets or sets a bitmask combining one or more <see cref="HttpTransportType"/> values that specify what transports the client should use to send HTTP requests.
@@ -118,7 +117,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// <summary>
         /// <summary>
         /// Gets or sets an access token provider that will be called to return a token for each HTTP request.
         /// Gets or sets an access token provider that will be called to return a token for each HTTP request.
         /// </summary>
         /// </summary>
-        public Func<Task<string>> AccessTokenProvider { get; set; }
+        public Func<Task<string?>>? AccessTokenProvider { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets or sets a close timeout.
         /// Gets or sets a close timeout.
@@ -129,7 +128,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// Gets or sets the credentials used when making HTTP requests.
         /// Gets or sets the credentials used when making HTTP requests.
         /// </summary>
         /// </summary>
         [UnsupportedOSPlatform("browser")]
         [UnsupportedOSPlatform("browser")]
-        public ICredentials Credentials
+        public ICredentials? Credentials
         {
         {
             get
             get
             {
             {
@@ -147,7 +146,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// Gets or sets the proxy used when making HTTP requests.
         /// Gets or sets the proxy used when making HTTP requests.
         /// </summary>
         /// </summary>
         [UnsupportedOSPlatform("browser")]
         [UnsupportedOSPlatform("browser")]
-        public IWebProxy Proxy
+        public IWebProxy? Proxy
         {
         {
             get
             get
             {
             {
@@ -194,7 +193,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// has been applied.
         /// has been applied.
         /// </remarks>
         /// </remarks>
         [UnsupportedOSPlatform("browser")]
         [UnsupportedOSPlatform("browser")]
-        public Action<ClientWebSocketOptions> WebSocketConfiguration
+        public Action<ClientWebSocketOptions>? WebSocketConfiguration
         {
         {
             get
             get
             {
             {

+ 7 - 8
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ConnectionLogScope.cs

@@ -4,19 +4,18 @@
 using System;
 using System;
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Globalization;
 
 
 namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 {
 {
-    internal class ConnectionLogScope : IReadOnlyList<KeyValuePair<string, object>>
+    internal class ConnectionLogScope : IReadOnlyList<KeyValuePair<string, object?>>
     {
     {
         // Name chosen so as not to collide with Kestrel's "ConnectionId"
         // Name chosen so as not to collide with Kestrel's "ConnectionId"
         private const string ClientConnectionIdKey = "ClientConnectionId";
         private const string ClientConnectionIdKey = "ClientConnectionId";
 
 
-        private string _cachedToString;
-        private string _connectionId;
+        private string? _cachedToString;
+        private string? _connectionId;
 
 
-        public string ConnectionId
+        public string? ConnectionId
         {
         {
             get => _connectionId;
             get => _connectionId;
             set
             set
@@ -26,13 +25,13 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
             }
             }
         }
         }
 
 
-        public KeyValuePair<string, object> this[int index]
+        public KeyValuePair<string, object?> this[int index]
         {
         {
             get
             get
             {
             {
                 if (Count == 1 && index == 0)
                 if (Count == 1 && index == 0)
                 {
                 {
-                    return new KeyValuePair<string, object>(ClientConnectionIdKey, ConnectionId);
+                    return new KeyValuePair<string, object?>(ClientConnectionIdKey, ConnectionId);
                 }
                 }
 
 
                 throw new ArgumentOutOfRangeException(nameof(index));
                 throw new ArgumentOutOfRangeException(nameof(index));
@@ -41,7 +40,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         public int Count => string.IsNullOrEmpty(ConnectionId) ? 0 : 1;
         public int Count => string.IsNullOrEmpty(ConnectionId) ? 0 : 1;
 
 
-        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+        public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
         {
         {
             for (var i = 0; i < Count; ++i)
             for (var i = 0; i < Count; ++i)
             {
             {

+ 1 - 1
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Constants.cs

@@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
             var runtime = ".NET";
             var runtime = ".NET";
             var runtimeVersion = RuntimeInformation.FrameworkDescription;
             var runtimeVersion = RuntimeInformation.FrameworkDescription;
 
 
-            UserAgentHeader = ConstructUserAgent(typeof(Constants).Assembly.GetName().Version, assemblyVersion?.InformationalVersion, GetOS(), runtime, runtimeVersion);
+            UserAgentHeader = ConstructUserAgent(typeof(Constants).Assembly.GetName().Version!, assemblyVersion.InformationalVersion, GetOS(), runtime, runtimeVersion);
         }
         }
 
 
         private static string GetOS()
         private static string GetOS()

+ 5 - 5
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/DefaultTransportFactory.cs

@@ -10,14 +10,14 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 {
 {
     internal class DefaultTransportFactory : ITransportFactory
     internal class DefaultTransportFactory : ITransportFactory
     {
     {
-        private readonly HttpClient _httpClient;
+        private readonly HttpClient? _httpClient;
         private readonly HttpConnectionOptions _httpConnectionOptions;
         private readonly HttpConnectionOptions _httpConnectionOptions;
-        private readonly Func<Task<string>> _accessTokenProvider;
+        private readonly Func<Task<string?>> _accessTokenProvider;
         private readonly HttpTransportType _requestedTransportType;
         private readonly HttpTransportType _requestedTransportType;
         private readonly ILoggerFactory _loggerFactory;
         private readonly ILoggerFactory _loggerFactory;
         private static volatile bool _websocketsSupported = true;
         private static volatile bool _websocketsSupported = true;
 
 
-        public DefaultTransportFactory(HttpTransportType requestedTransportType, ILoggerFactory loggerFactory, HttpClient httpClient, HttpConnectionOptions httpConnectionOptions, Func<Task<string>> accessTokenProvider)
+        public DefaultTransportFactory(HttpTransportType requestedTransportType, ILoggerFactory loggerFactory, HttpClient? httpClient, HttpConnectionOptions httpConnectionOptions, Func<Task<string?>> accessTokenProvider)
         {
         {
             if (httpClient == null && requestedTransportType != HttpTransportType.WebSockets)
             if (httpClient == null && requestedTransportType != HttpTransportType.WebSockets)
             {
             {
@@ -49,13 +49,13 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
             if ((availableServerTransports & HttpTransportType.ServerSentEvents & _requestedTransportType) == HttpTransportType.ServerSentEvents)
             if ((availableServerTransports & HttpTransportType.ServerSentEvents & _requestedTransportType) == HttpTransportType.ServerSentEvents)
             {
             {
                 // We don't need to give the transport the accessTokenProvider because the HttpClient has a message handler that does the work for us.
                 // We don't need to give the transport the accessTokenProvider because the HttpClient has a message handler that does the work for us.
-                return new ServerSentEventsTransport(_httpClient, _loggerFactory);
+                return new ServerSentEventsTransport(_httpClient!, _loggerFactory);
             }
             }
 
 
             if ((availableServerTransports & HttpTransportType.LongPolling & _requestedTransportType) == HttpTransportType.LongPolling)
             if ((availableServerTransports & HttpTransportType.LongPolling & _requestedTransportType) == HttpTransportType.LongPolling)
             {
             {
                 // We don't need to give the transport the accessTokenProvider because the HttpClient has a message handler that does the work for us.
                 // We don't need to give the transport the accessTokenProvider because the HttpClient has a message handler that does the work for us.
-                return new LongPollingTransport(_httpClient, _loggerFactory);
+                return new LongPollingTransport(_httpClient!, _loggerFactory);
             }
             }
 
 
             throw new InvalidOperationException("No requested transports available on the server.");
             throw new InvalidOperationException("No requested transports available on the server.");

+ 4 - 4
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LoggingHttpMessageHandler.cs

@@ -26,13 +26,13 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
         protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
         {
         {
-            Log.SendingHttpRequest(_logger, request.Method, request.RequestUri);
+            Log.SendingHttpRequest(_logger, request.Method, request.RequestUri!);
 
 
             var response = await base.SendAsync(request, cancellationToken);
             var response = await base.SendAsync(request, cancellationToken);
 
 
             if (!response.IsSuccessStatusCode)
             if (!response.IsSuccessStatusCode)
             {
             {
-                Log.UnsuccessfulHttpResponse(_logger, response.StatusCode, request.Method, request.RequestUri);
+                Log.UnsuccessfulHttpResponse(_logger, response.StatusCode, request.Method, request.RequestUri!);
             }
             }
 
 
             return response;
             return response;
@@ -40,10 +40,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, HttpMethod, Uri, Exception> _sendingHttpRequest =
+            private static readonly Action<ILogger, HttpMethod, Uri, Exception?> _sendingHttpRequest =
                 LoggerMessage.Define<HttpMethod, Uri>(LogLevel.Trace, new EventId(1, "SendingHttpRequest"), "Sending HTTP request {RequestMethod} '{RequestUrl}'.");
                 LoggerMessage.Define<HttpMethod, Uri>(LogLevel.Trace, new EventId(1, "SendingHttpRequest"), "Sending HTTP request {RequestMethod} '{RequestUrl}'.");
 
 
-            private static readonly Action<ILogger, int, HttpMethod, Uri, Exception> _unsuccessfulHttpResponse =
+            private static readonly Action<ILogger, int, HttpMethod, Uri, Exception?> _unsuccessfulHttpResponse =
                 LoggerMessage.Define<int, HttpMethod, Uri>(LogLevel.Warning, new EventId(2, "UnsuccessfulHttpResponse"), "Unsuccessful HTTP response {StatusCode} return from {RequestMethod} '{RequestUrl}'.");
                 LoggerMessage.Define<int, HttpMethod, Uri>(LogLevel.Warning, new EventId(2, "UnsuccessfulHttpResponse"), "Unsuccessful HTTP response {StatusCode} return from {RequestMethod} '{RequestUrl}'.");
 
 
             public static void SendingHttpRequest(ILogger logger, HttpMethod requestMethod, Uri requestUrl)
             public static void SendingHttpRequest(ILogger logger, HttpMethod requestMethod, Uri requestUrl)

+ 13 - 13
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.Log.cs

@@ -12,48 +12,48 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
     {
     {
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, TransferFormat, Exception> _startTransport =
+            private static readonly Action<ILogger, TransferFormat, Exception?> _startTransport =
                 LoggerMessage.Define<TransferFormat>(LogLevel.Information, new EventId(1, "StartTransport"), "Starting transport. Transfer mode: {TransferFormat}.");
                 LoggerMessage.Define<TransferFormat>(LogLevel.Information, new EventId(1, "StartTransport"), "Starting transport. Transfer mode: {TransferFormat}.");
 
 
-            private static readonly Action<ILogger, Exception> _transportStopped =
+            private static readonly Action<ILogger, Exception?> _transportStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "TransportStopped"), "Transport stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "TransportStopped"), "Transport stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _startReceive =
+            private static readonly Action<ILogger, Exception?> _startReceive =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(3, "StartReceive"), "Starting receive loop.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(3, "StartReceive"), "Starting receive loop.");
 
 
-            private static readonly Action<ILogger, Exception> _receiveStopped =
+            private static readonly Action<ILogger, Exception?> _receiveStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "ReceiveStopped"), "Receive loop stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "ReceiveStopped"), "Receive loop stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _receiveCanceled =
+            private static readonly Action<ILogger, Exception?> _receiveCanceled =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "ReceiveCanceled"), "Receive loop canceled.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "ReceiveCanceled"), "Receive loop canceled.");
 
 
-            private static readonly Action<ILogger, Exception> _transportStopping =
+            private static readonly Action<ILogger, Exception?> _transportStopping =
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "TransportStopping"), "Transport is stopping.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "TransportStopping"), "Transport is stopping.");
 
 
-            private static readonly Action<ILogger, Exception> _closingConnection =
+            private static readonly Action<ILogger, Exception?> _closingConnection =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(7, "ClosingConnection"), "The server is closing the connection.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(7, "ClosingConnection"), "The server is closing the connection.");
 
 
-            private static readonly Action<ILogger, Exception> _receivedMessages =
+            private static readonly Action<ILogger, Exception?> _receivedMessages =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(8, "ReceivedMessages"), "Received messages from the server.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(8, "ReceivedMessages"), "Received messages from the server.");
 
 
             private static readonly Action<ILogger, Uri, Exception> _errorPolling =
             private static readonly Action<ILogger, Uri, Exception> _errorPolling =
                 LoggerMessage.Define<Uri>(LogLevel.Error, new EventId(9, "ErrorPolling"), "Error while polling '{PollUrl}'.");
                 LoggerMessage.Define<Uri>(LogLevel.Error, new EventId(9, "ErrorPolling"), "Error while polling '{PollUrl}'.");
 
 
             // long? does properly format as "(null)" when null.
             // long? does properly format as "(null)" when null.
-            private static readonly Action<ILogger, int, long?, Exception> _pollResponseReceived =
+            private static readonly Action<ILogger, int, long?, Exception?> _pollResponseReceived =
                 LoggerMessage.Define<int, long?>(LogLevel.Trace, new EventId(10, "PollResponseReceived"),
                 LoggerMessage.Define<int, long?>(LogLevel.Trace, new EventId(10, "PollResponseReceived"),
                     "Poll response with status code {StatusCode} received from server. Content length: {ContentLength}.");
                     "Poll response with status code {StatusCode} received from server. Content length: {ContentLength}.");
 
 
-            private static readonly Action<ILogger, Uri, Exception> _sendingDeleteRequest =
+            private static readonly Action<ILogger, Uri, Exception?> _sendingDeleteRequest =
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(11, "SendingDeleteRequest"), "Sending DELETE request to '{PollUrl}'.");
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(11, "SendingDeleteRequest"), "Sending DELETE request to '{PollUrl}'.");
 
 
-            private static readonly Action<ILogger, Uri, Exception> _deleteRequestAccepted =
+            private static readonly Action<ILogger, Uri, Exception?> _deleteRequestAccepted =
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(12, "DeleteRequestAccepted"), "DELETE request to '{PollUrl}' accepted.");
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(12, "DeleteRequestAccepted"), "DELETE request to '{PollUrl}' accepted.");
 
 
             private static readonly Action<ILogger, Uri, Exception> _errorSendingDeleteRequest =
             private static readonly Action<ILogger, Uri, Exception> _errorSendingDeleteRequest =
                 LoggerMessage.Define<Uri>(LogLevel.Error, new EventId(13, "ErrorSendingDeleteRequest"), "Error sending DELETE request to '{PollUrl}'.");
                 LoggerMessage.Define<Uri>(LogLevel.Error, new EventId(13, "ErrorSendingDeleteRequest"), "Error sending DELETE request to '{PollUrl}'.");
 
 
-            private static readonly Action<ILogger, Uri, Exception> _connectionAlreadyClosedSendingDeleteRequest =
+            private static readonly Action<ILogger, Uri, Exception?> _connectionAlreadyClosedSendingDeleteRequest =
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(14, "ConnectionAlreadyClosedSendingDeleteRequest"), "A 404 response was returned from sending DELETE request to '{PollUrl}', likely because the transport was already closed on the server.");
                 LoggerMessage.Define<Uri>(LogLevel.Debug, new EventId(14, "ConnectionAlreadyClosedSendingDeleteRequest"), "A 404 response was returned from sending DELETE request to '{PollUrl}', likely because the transport was already closed on the server.");
 
 
             // EventIds 100 - 106 used in SendUtils
             // EventIds 100 - 106 used in SendUtils
@@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                 _startTransport(logger, transferFormat, null);
                 _startTransport(logger, transferFormat, null);
             }
             }
 
 
-            public static void TransportStopped(ILogger logger, Exception exception)
+            public static void TransportStopped(ILogger logger, Exception? exception)
             {
             {
                 _transportStopped(logger, exception);
                 _transportStopped(logger, exception);
             }
             }

+ 14 - 11
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.cs

@@ -2,16 +2,15 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
 using System;
 using System;
+using System.Diagnostics;
 using System.IO.Pipelines;
 using System.IO.Pipelines;
 using System.Net;
 using System.Net;
 using System.Net.Http;
 using System.Net.Http;
-using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Connections;
 using Microsoft.AspNetCore.Connections;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging.Abstractions;
 using Microsoft.Extensions.Logging.Abstractions;
-using static Microsoft.AspNetCore.Http.Connections.Client.Internal.Utils;
 
 
 namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 {
 {
@@ -19,24 +18,24 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
     {
     {
         private readonly HttpClient _httpClient;
         private readonly HttpClient _httpClient;
         private readonly ILogger _logger;
         private readonly ILogger _logger;
-        private IDuplexPipe _application;
-        private IDuplexPipe _transport;
+        private IDuplexPipe? _application;
+        private IDuplexPipe? _transport;
         // Volatile so that the poll loop sees the updated value set from a different thread
         // Volatile so that the poll loop sees the updated value set from a different thread
-        private volatile Exception _error;
+        private volatile Exception? _error;
 
 
         private readonly CancellationTokenSource _transportCts = new CancellationTokenSource();
         private readonly CancellationTokenSource _transportCts = new CancellationTokenSource();
 
 
         internal Task Running { get; private set; } = Task.CompletedTask;
         internal Task Running { get; private set; } = Task.CompletedTask;
 
 
-        public PipeReader Input => _transport.Input;
+        public PipeReader Input => _transport!.Input;
 
 
-        public PipeWriter Output => _transport.Output;
+        public PipeWriter Output => _transport!.Output;
 
 
         public LongPollingTransport(HttpClient httpClient)
         public LongPollingTransport(HttpClient httpClient)
             : this(httpClient, null)
             : this(httpClient, null)
         { }
         { }
 
 
-        public LongPollingTransport(HttpClient httpClient, ILoggerFactory loggerFactory)
+        public LongPollingTransport(HttpClient httpClient, ILoggerFactory? loggerFactory)
         {
         {
             _httpClient = httpClient;
             _httpClient = httpClient;
             _logger = (loggerFactory ?? NullLoggerFactory.Instance).CreateLogger<LongPollingTransport>();
             _logger = (loggerFactory ?? NullLoggerFactory.Instance).CreateLogger<LongPollingTransport>();
@@ -71,6 +70,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private async Task ProcessAsync(Uri url)
         private async Task ProcessAsync(Uri url)
         {
         {
+            Debug.Assert(_application != null);
+
             // Start sending and polling (ask for binary if the server supports it)
             // Start sending and polling (ask for binary if the server supports it)
             var receiving = Poll(url, _transportCts.Token);
             var receiving = Poll(url, _transportCts.Token);
             var sending = SendUtils.SendMessages(url, _application, _httpClient, _logger);
             var sending = SendUtils.SendMessages(url, _application, _httpClient, _logger);
@@ -94,7 +95,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
             else
             else
             {
             {
                 // Set the sending error so we communicate that to the application
                 // Set the sending error so we communicate that to the application
-                _error = sending.IsFaulted ? sending.Exception.InnerException : null;
+                _error = sending.IsFaulted ? sending.Exception!.InnerException : null;
 
 
                 // Cancel the poll request
                 // Cancel the poll request
                 _transportCts.Cancel();
                 _transportCts.Cancel();
@@ -131,14 +132,16 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                 throw;
                 throw;
             }
             }
 
 
-            _transport.Output.Complete();
-            _transport.Input.Complete();
+            _transport!.Output.Complete();
+            _transport!.Input.Complete();
 
 
             Log.TransportStopped(_logger, null);
             Log.TransportStopped(_logger, null);
         }
         }
 
 
         private async Task Poll(Uri pollUrl, CancellationToken cancellationToken)
         private async Task Poll(Uri pollUrl, CancellationToken cancellationToken)
         {
         {
+            Debug.Assert(_application != null);
+
             Log.StartReceive(_logger);
             Log.StartReceive(_logger);
 
 
             // Allocate this once for the duration of the transport so we can continuously write to it
             // Allocate this once for the duration of the transport so we can continuously write to it

+ 7 - 7
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/SendUtils.cs

@@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                 _buffer = buffer;
                 _buffer = buffer;
             }
             }
 
 
-            protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
+            protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context)
             {
             {
                 return stream.WriteAsync(_buffer).AsTask();
                 return stream.WriteAsync(_buffer).AsTask();
             }
             }
@@ -111,22 +111,22 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, Exception> _sendStarted =
+            private static readonly Action<ILogger, Exception?> _sendStarted =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(100, "SendStarted"), "Starting the send loop.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(100, "SendStarted"), "Starting the send loop.");
 
 
-            private static readonly Action<ILogger, Exception> _sendStopped =
+            private static readonly Action<ILogger, Exception?> _sendStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(101, "SendStopped"), "Send loop stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(101, "SendStopped"), "Send loop stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _sendCanceled =
+            private static readonly Action<ILogger, Exception?> _sendCanceled =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(102, "SendCanceled"), "Send loop canceled.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(102, "SendCanceled"), "Send loop canceled.");
 
 
-            private static readonly Action<ILogger, long, Uri, Exception> _sendingMessages =
+            private static readonly Action<ILogger, long, Uri, Exception?> _sendingMessages =
                 LoggerMessage.Define<long, Uri>(LogLevel.Debug, new EventId(103, "SendingMessages"), "Sending {Count} bytes to the server using url: {Url}.");
                 LoggerMessage.Define<long, Uri>(LogLevel.Debug, new EventId(103, "SendingMessages"), "Sending {Count} bytes to the server using url: {Url}.");
 
 
-            private static readonly Action<ILogger, Exception> _sentSuccessfully =
+            private static readonly Action<ILogger, Exception?> _sentSuccessfully =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(104, "SentSuccessfully"), "Message(s) sent successfully.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(104, "SentSuccessfully"), "Message(s) sent successfully.");
 
 
-            private static readonly Action<ILogger, Exception> _noMessages =
+            private static readonly Action<ILogger, Exception?> _noMessages =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(105, "NoMessages"), "No messages in batch to send.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(105, "NoMessages"), "No messages in batch to send.");
 
 
             private static readonly Action<ILogger, Uri, Exception> _errorSending =
             private static readonly Action<ILogger, Uri, Exception> _errorSending =

+ 2 - 1
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsMessageParser.cs

@@ -4,6 +4,7 @@
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
 using System.Text;
 using System.Text;
 
 
@@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
         private InternalParseState _internalParserState = InternalParseState.ReadMessagePayload;
         private InternalParseState _internalParserState = InternalParseState.ReadMessagePayload;
         private readonly List<byte[]> _data = new List<byte[]>();
         private readonly List<byte[]> _data = new List<byte[]>();
 
 
-        public ParseResult ParseMessage(ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined, out byte[] message)
+        public ParseResult ParseMessage(ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined, out byte[]? message)
         {
         {
             consumed = buffer.Start;
             consumed = buffer.Start;
             examined = buffer.End;
             examined = buffer.End;

+ 10 - 10
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsTransport.Log.cs

@@ -11,31 +11,31 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
     {
     {
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, TransferFormat, Exception> _startTransport =
+            private static readonly Action<ILogger, TransferFormat, Exception?> _startTransport =
                 LoggerMessage.Define<TransferFormat>(LogLevel.Information, new EventId(1, "StartTransport"), "Starting transport. Transfer mode: {TransferFormat}.");
                 LoggerMessage.Define<TransferFormat>(LogLevel.Information, new EventId(1, "StartTransport"), "Starting transport. Transfer mode: {TransferFormat}.");
 
 
-            private static readonly Action<ILogger, Exception> _transportStopped =
+            private static readonly Action<ILogger, Exception?> _transportStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "TransportStopped"), "Transport stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "TransportStopped"), "Transport stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _startReceive =
+            private static readonly Action<ILogger, Exception?> _startReceive =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(3, "StartReceive"), "Starting receive loop.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(3, "StartReceive"), "Starting receive loop.");
 
 
-            private static readonly Action<ILogger, Exception> _receiveStopped =
+            private static readonly Action<ILogger, Exception?> _receiveStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "ReceiveStopped"), "Receive loop stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "ReceiveStopped"), "Receive loop stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _receiveCanceled =
+            private static readonly Action<ILogger, Exception?> _receiveCanceled =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "ReceiveCanceled"), "Receive loop canceled.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "ReceiveCanceled"), "Receive loop canceled.");
 
 
-            private static readonly Action<ILogger, Exception> _transportStopping =
+            private static readonly Action<ILogger, Exception?> _transportStopping =
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "TransportStopping"), "Transport is stopping.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "TransportStopping"), "Transport is stopping.");
 
 
-            private static readonly Action<ILogger, int, Exception> _messageToApplication =
+            private static readonly Action<ILogger, int, Exception?> _messageToApplication =
                 LoggerMessage.Define<int>(LogLevel.Debug, new EventId(7, "MessageToApplication"), "Passing message to application. Payload size: {Count}.");
                 LoggerMessage.Define<int>(LogLevel.Debug, new EventId(7, "MessageToApplication"), "Passing message to application. Payload size: {Count}.");
 
 
-            private static readonly Action<ILogger, Exception> _eventStreamEnded =
+            private static readonly Action<ILogger, Exception?> _eventStreamEnded =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(8, "EventStreamEnded"), "Server-Sent Event Stream ended.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(8, "EventStreamEnded"), "Server-Sent Event Stream ended.");
 
 
-            private static readonly Action<ILogger, long, Exception> _parsingSSE =
+            private static readonly Action<ILogger, long, Exception?> _parsingSSE =
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(9, "ParsingSSE"), "Received {Count} bytes. Parsing SSE frame.");
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(9, "ParsingSSE"), "Received {Count} bytes. Parsing SSE frame.");
 
 
             // EventIds 100 - 106 used in SendUtils
             // EventIds 100 - 106 used in SendUtils
@@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                 _startTransport(logger, transferFormat, null);
                 _startTransport(logger, transferFormat, null);
             }
             }
 
 
-            public static void TransportStopped(ILogger logger, Exception exception)
+            public static void TransportStopped(ILogger logger, Exception? exception)
             {
             {
                 _transportStopped(logger, exception);
                 _transportStopped(logger, exception);
             }
             }

+ 18 - 13
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsTransport.cs

@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
 using System;
 using System;
+using System.Diagnostics;
 using System.IO.Pipelines;
 using System.IO.Pipelines;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.Http.Headers;
 using System.Net.Http.Headers;
@@ -19,24 +20,24 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
         private readonly ILogger _logger;
         private readonly ILogger _logger;
 
 
         // Volatile so that the SSE loop sees the updated value set from a different thread
         // Volatile so that the SSE loop sees the updated value set from a different thread
-        private volatile Exception _error;
+        private volatile Exception? _error;
         private readonly CancellationTokenSource _transportCts = new CancellationTokenSource();
         private readonly CancellationTokenSource _transportCts = new CancellationTokenSource();
         private readonly CancellationTokenSource _inputCts = new CancellationTokenSource();
         private readonly CancellationTokenSource _inputCts = new CancellationTokenSource();
         private readonly ServerSentEventsMessageParser _parser = new ServerSentEventsMessageParser();
         private readonly ServerSentEventsMessageParser _parser = new ServerSentEventsMessageParser();
-        private IDuplexPipe _transport;
-        private IDuplexPipe _application;
+        private IDuplexPipe? _transport;
+        private IDuplexPipe? _application;
 
 
         internal Task Running { get; private set; } = Task.CompletedTask;
         internal Task Running { get; private set; } = Task.CompletedTask;
 
 
-        public PipeReader Input => _transport.Input;
+        public PipeReader Input => _transport!.Input;
 
 
-        public PipeWriter Output => _transport.Output;
+        public PipeWriter Output => _transport!.Output;
 
 
         public ServerSentEventsTransport(HttpClient httpClient)
         public ServerSentEventsTransport(HttpClient httpClient)
             : this(httpClient, null)
             : this(httpClient, null)
         { }
         { }
 
 
-        public ServerSentEventsTransport(HttpClient httpClient, ILoggerFactory loggerFactory)
+        public ServerSentEventsTransport(HttpClient httpClient, ILoggerFactory? loggerFactory)
         {
         {
             if (httpClient == null)
             if (httpClient == null)
             {
             {
@@ -59,7 +60,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
             var request = new HttpRequestMessage(HttpMethod.Get, url);
             var request = new HttpRequestMessage(HttpMethod.Get, url);
             request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));
             request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));
 
 
-            HttpResponseMessage response = null;
+            HttpResponseMessage? response = null;
 
 
             try
             try
             {
             {
@@ -92,6 +93,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private async Task ProcessAsync(Uri url, HttpResponseMessage response)
         private async Task ProcessAsync(Uri url, HttpResponseMessage response)
         {
         {
+            Debug.Assert(_application != null);
+
             // Start sending and polling (ask for binary if the server supports it)
             // Start sending and polling (ask for binary if the server supports it)
             var receiving = ProcessEventStream(response, _transportCts.Token);
             var receiving = ProcessEventStream(response, _transportCts.Token);
             var sending = SendUtils.SendMessages(url, _application, _httpClient, _logger, _inputCts.Token);
             var sending = SendUtils.SendMessages(url, _application, _httpClient, _logger, _inputCts.Token);
@@ -115,7 +118,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
             else
             else
             {
             {
                 // Set the sending error so we communicate that to the application
                 // Set the sending error so we communicate that to the application
-                _error = sending.IsFaulted ? sending.Exception.InnerException : null;
+                _error = sending.IsFaulted ? sending.Exception!.InnerException : null;
 
 
                 _transportCts.Cancel();
                 _transportCts.Cancel();
 
 
@@ -128,9 +131,11 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private async Task ProcessEventStream(HttpResponseMessage response, CancellationToken cancellationToken)
         private async Task ProcessEventStream(HttpResponseMessage response, CancellationToken cancellationToken)
         {
         {
+            Debug.Assert(_application != null);
+
             Log.StartReceive(_logger);
             Log.StartReceive(_logger);
-            
-            static void CancelReader(object state) => ((PipeReader)state).CancelPendingRead();
+
+            static void CancelReader(object? state) => ((PipeReader)state!).CancelPendingRead();
 
 
             using (response)
             using (response)
             using (var stream = await response.Content.ReadAsStreamAsync())
             using (var stream = await response.Content.ReadAsStreamAsync())
@@ -166,7 +171,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                                 switch (parseResult)
                                 switch (parseResult)
                                 {
                                 {
                                     case ServerSentEventsMessageParser.ParseResult.Completed:
                                     case ServerSentEventsMessageParser.ParseResult.Completed:
-                                        Log.MessageToApplication(_logger, message.Length);
+                                        Log.MessageToApplication(_logger, message!.Length);
 
 
                                         flushResult = await _application.Output.WriteAsync(message);
                                         flushResult = await _application.Output.WriteAsync(message);
 
 
@@ -224,8 +229,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                 return;
                 return;
             }
             }
 
 
-            _transport.Output.Complete();
-            _transport.Input.Complete();
+            _transport!.Output.Complete();
+            _transport!.Input.Complete();
 
 
             _application.Input.CancelPendingRead();
             _application.Input.CancelPendingRead();
 
 

+ 19 - 20
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.Log.cs

@@ -12,75 +12,74 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
     {
     {
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, TransferFormat, Uri, Exception> _startTransport =
+            private static readonly Action<ILogger, TransferFormat, Uri, Exception?> _startTransport =
                 LoggerMessage.Define<TransferFormat, Uri>(LogLevel.Information, new EventId(1, "StartTransport"), "Starting transport. Transfer mode: {TransferFormat}. Url: '{WebSocketUrl}'.");
                 LoggerMessage.Define<TransferFormat, Uri>(LogLevel.Information, new EventId(1, "StartTransport"), "Starting transport. Transfer mode: {TransferFormat}. Url: '{WebSocketUrl}'.");
 
 
-            private static readonly Action<ILogger, Exception> _transportStopped =
+            private static readonly Action<ILogger, Exception?> _transportStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "TransportStopped"), "Transport stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "TransportStopped"), "Transport stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _startReceive =
+            private static readonly Action<ILogger, Exception?> _startReceive =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(3, "StartReceive"), "Starting receive loop.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(3, "StartReceive"), "Starting receive loop.");
 
 
-            private static readonly Action<ILogger, Exception> _receiveStopped =
+            private static readonly Action<ILogger, Exception?> _receiveStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "ReceiveStopped"), "Receive loop stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "ReceiveStopped"), "Receive loop stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _receiveCanceled =
+            private static readonly Action<ILogger, Exception?> _receiveCanceled =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "ReceiveCanceled"), "Receive loop canceled.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "ReceiveCanceled"), "Receive loop canceled.");
 
 
-            private static readonly Action<ILogger, Exception> _transportStopping =
+            private static readonly Action<ILogger, Exception?> _transportStopping =
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "TransportStopping"), "Transport is stopping.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(6, "TransportStopping"), "Transport is stopping.");
 
 
-            private static readonly Action<ILogger, Exception> _sendStarted =
+            private static readonly Action<ILogger, Exception?> _sendStarted =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(7, "SendStarted"), "Starting the send loop.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(7, "SendStarted"), "Starting the send loop.");
 
 
-            private static readonly Action<ILogger, Exception> _sendStopped =
+            private static readonly Action<ILogger, Exception?> _sendStopped =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(8, "SendStopped"), "Send loop stopped.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(8, "SendStopped"), "Send loop stopped.");
 
 
-            private static readonly Action<ILogger, Exception> _sendCanceled =
+            private static readonly Action<ILogger, Exception?> _sendCanceled =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(9, "SendCanceled"), "Send loop canceled.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(9, "SendCanceled"), "Send loop canceled.");
 
 
-            private static readonly Action<ILogger, int, Exception> _messageToApp =
+            private static readonly Action<ILogger, int, Exception?> _messageToApp =
                 LoggerMessage.Define<int>(LogLevel.Debug, new EventId(10, "MessageToApp"), "Passing message to application. Payload size: {Count}.");
                 LoggerMessage.Define<int>(LogLevel.Debug, new EventId(10, "MessageToApp"), "Passing message to application. Payload size: {Count}.");
 
 
-            private static readonly Action<ILogger, WebSocketCloseStatus?, Exception> _webSocketClosed =
+            private static readonly Action<ILogger, WebSocketCloseStatus?, Exception?> _webSocketClosed =
                 LoggerMessage.Define<WebSocketCloseStatus?>(LogLevel.Information, new EventId(11, "WebSocketClosed"), "WebSocket closed by the server. Close status {CloseStatus}.");
                 LoggerMessage.Define<WebSocketCloseStatus?>(LogLevel.Information, new EventId(11, "WebSocketClosed"), "WebSocket closed by the server. Close status {CloseStatus}.");
 
 
-            private static readonly Action<ILogger, WebSocketMessageType, int, bool, Exception> _messageReceived =
+            private static readonly Action<ILogger, WebSocketMessageType, int, bool, Exception?> _messageReceived =
                 LoggerMessage.Define<WebSocketMessageType, int, bool>(LogLevel.Debug, new EventId(12, "MessageReceived"), "Message received. Type: {MessageType}, size: {Count}, EndOfMessage: {EndOfMessage}.");
                 LoggerMessage.Define<WebSocketMessageType, int, bool>(LogLevel.Debug, new EventId(12, "MessageReceived"), "Message received. Type: {MessageType}, size: {Count}, EndOfMessage: {EndOfMessage}.");
 
 
-            private static readonly Action<ILogger, long, Exception> _receivedFromApp =
+            private static readonly Action<ILogger, long, Exception?> _receivedFromApp =
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(13, "ReceivedFromApp"), "Received message from application. Payload size: {Count}.");
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(13, "ReceivedFromApp"), "Received message from application. Payload size: {Count}.");
 
 
-            private static readonly Action<ILogger, Exception> _sendMessageCanceled =
+            private static readonly Action<ILogger, Exception?> _sendMessageCanceled =
                 LoggerMessage.Define(LogLevel.Information, new EventId(14, "SendMessageCanceled"), "Sending a message canceled.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(14, "SendMessageCanceled"), "Sending a message canceled.");
 
 
             private static readonly Action<ILogger, Exception> _errorSendingMessage =
             private static readonly Action<ILogger, Exception> _errorSendingMessage =
                 LoggerMessage.Define(LogLevel.Error, new EventId(15, "ErrorSendingMessage"), "Error while sending a message.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(15, "ErrorSendingMessage"), "Error while sending a message.");
 
 
-            private static readonly Action<ILogger, Exception> _closingWebSocket =
+            private static readonly Action<ILogger, Exception?> _closingWebSocket =
                 LoggerMessage.Define(LogLevel.Information, new EventId(16, "ClosingWebSocket"), "Closing WebSocket.");
                 LoggerMessage.Define(LogLevel.Information, new EventId(16, "ClosingWebSocket"), "Closing WebSocket.");
 
 
             private static readonly Action<ILogger, Exception> _closingWebSocketFailed =
             private static readonly Action<ILogger, Exception> _closingWebSocketFailed =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(17, "ClosingWebSocketFailed"), "Closing webSocket failed.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(17, "ClosingWebSocketFailed"), "Closing webSocket failed.");
 
 
-            private static readonly Action<ILogger, Exception> _cancelMessage =
+            private static readonly Action<ILogger, Exception?> _cancelMessage =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(18, "CancelMessage"), "Canceled passing message to application.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(18, "CancelMessage"), "Canceled passing message to application.");
 
 
-            private static readonly Action<ILogger, Exception> _startedTransport =
+            private static readonly Action<ILogger, Exception?> _startedTransport =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(19, "StartedTransport"), "Started transport.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(19, "StartedTransport"), "Started transport.");
 
 
-            private static readonly Action<ILogger, Exception> _headersNotSupported =
+            private static readonly Action<ILogger, Exception?> _headersNotSupported =
                 LoggerMessage.Define(LogLevel.Warning, new EventId(20, "HeadersNotSupported"),
                 LoggerMessage.Define(LogLevel.Warning, new EventId(20, "HeadersNotSupported"),
                     $"Configuring request headers using {nameof(HttpConnectionOptions)}.{nameof(HttpConnectionOptions.Headers)} is not supported when using websockets transport " +
                     $"Configuring request headers using {nameof(HttpConnectionOptions)}.{nameof(HttpConnectionOptions.Headers)} is not supported when using websockets transport " +
                     "on the browser platform.");
                     "on the browser platform.");
 
 
-
             public static void StartTransport(ILogger logger, TransferFormat transferFormat, Uri webSocketUrl)
             public static void StartTransport(ILogger logger, TransferFormat transferFormat, Uri webSocketUrl)
             {
             {
                 _startTransport(logger, transferFormat, webSocketUrl, null);
                 _startTransport(logger, transferFormat, webSocketUrl, null);
             }
             }
 
 
-            public static void TransportStopped(ILogger logger, Exception exception)
+            public static void TransportStopped(ILogger logger, Exception? exception)
             {
             {
                 _transportStopped(logger, exception);
                 _transportStopped(logger, exception);
             }
             }

+ 17 - 11
src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs

@@ -18,24 +18,26 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
     internal partial class WebSocketsTransport : ITransport
     internal partial class WebSocketsTransport : ITransport
     {
     {
         private readonly ClientWebSocket _webSocket;
         private readonly ClientWebSocket _webSocket;
-        private readonly Func<Task<string>> _accessTokenProvider;
-        private IDuplexPipe _application;
+        private readonly Func<Task<string?>> _accessTokenProvider;
+        private IDuplexPipe? _application;
         private WebSocketMessageType _webSocketMessageType;
         private WebSocketMessageType _webSocketMessageType;
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly TimeSpan _closeTimeout;
         private readonly TimeSpan _closeTimeout;
         private volatile bool _aborted;
         private volatile bool _aborted;
 
 
-        private IDuplexPipe _transport;
+        private IDuplexPipe? _transport;
 
 
         internal Task Running { get; private set; } = Task.CompletedTask;
         internal Task Running { get; private set; } = Task.CompletedTask;
 
 
-        public PipeReader Input => _transport.Input;
+        public PipeReader Input => _transport!.Input;
 
 
-        public PipeWriter Output => _transport.Output;
+        public PipeWriter Output => _transport!.Output;
 
 
-        public WebSocketsTransport(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory, Func<Task<string>> accessTokenProvider)
+        public WebSocketsTransport(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory, Func<Task<string?>> accessTokenProvider)
         {
         {
             _webSocket = new ClientWebSocket();
             _webSocket = new ClientWebSocket();
+            _logger = (loggerFactory ?? NullLoggerFactory.Instance).CreateLogger<WebSocketsTransport>();
+
             var isBrowser = OperatingSystem.IsBrowser();
             var isBrowser = OperatingSystem.IsBrowser();
             if (!isBrowser)
             if (!isBrowser)
             {
             {
@@ -103,8 +105,6 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
             _closeTimeout = httpConnectionOptions?.CloseTimeout ?? default;
             _closeTimeout = httpConnectionOptions?.CloseTimeout ?? default;
 
 
-            _logger = (loggerFactory ?? NullLoggerFactory.Instance).CreateLogger<WebSocketsTransport>();
-
             // Ignore the HttpConnectionOptions access token provider. We were given an updated delegate from the HttpConnection.
             // Ignore the HttpConnectionOptions access token provider. We were given an updated delegate from the HttpConnection.
             _accessTokenProvider = accessTokenProvider;
             _accessTokenProvider = accessTokenProvider;
         }
         }
@@ -177,6 +177,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private async Task ProcessSocketAsync(WebSocket socket)
         private async Task ProcessSocketAsync(WebSocket socket)
         {
         {
+            Debug.Assert(_application != null);
+
             using (socket)
             using (socket)
             {
             {
                 // Begin sending and receiving.
                 // Begin sending and receiving.
@@ -232,6 +234,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private async Task StartReceiving(WebSocket socket)
         private async Task StartReceiving(WebSocket socket)
         {
         {
+            Debug.Assert(_application != null);
+
             try
             try
             {
             {
                 while (true)
                 while (true)
@@ -314,7 +318,9 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
 
 
         private async Task StartSending(WebSocket socket)
         private async Task StartSending(WebSocket socket)
         {
         {
-            Exception error = null;
+            Debug.Assert(_application != null);
+
+            Exception? error = null;
 
 
             try
             try
             {
             {
@@ -424,8 +430,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                 return;
                 return;
             }
             }
 
 
-            _transport.Output.Complete();
-            _transport.Input.Complete();
+            _transport!.Output.Complete();
+            _transport!.Input.Complete();
 
 
             // Cancel any pending reads from the application, this should start the entire shutdown process
             // Cancel any pending reads from the application, this should start the entire shutdown process
             _application.Input.CancelPendingRead();
             _application.Input.CancelPendingRead();

+ 1 - 0
src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj

@@ -3,6 +3,7 @@
   <PropertyGroup>
   <PropertyGroup>
     <Description>Client for ASP.NET Core Connection Handlers</Description>
     <Description>Client for ASP.NET Core Connection Handlers</Description>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1</TargetFrameworks>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1</TargetFrameworks>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 72 - 0
src/SignalR/clients/csharp/Http.Connections.Client/src/PublicAPI.Unshipped.txt

@@ -1 +1,73 @@
 #nullable enable
 #nullable enable
+*REMOVED*~override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Transport.get -> System.IO.Pipelines.IDuplexPipe
+*REMOVED*~override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Transport.set -> void
+*REMOVED*~override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Features.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection
+*REMOVED*~override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.ConnectionId.get -> string
+*REMOVED*~override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.ConnectionId.set -> void
+*REMOVED*~override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Items.get -> System.Collections.Generic.IDictionary<object, object>
+*REMOVED*~override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Items.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions httpConnectionOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(System.Uri url) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.HttpConnectionFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions> options, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(System.Net.EndPoint endPoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext>
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.HttpMessageHandlerFactory.get -> System.Func<System.Net.Http.HttpMessageHandler, System.Net.Http.HttpMessageHandler>
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.HttpMessageHandlerFactory.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Headers.get -> System.Collections.Generic.IDictionary<string, string>
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Headers.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.ClientCertificates.get -> System.Security.Cryptography.X509Certificates.X509CertificateCollection
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.ClientCertificates.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Cookies.get -> System.Net.CookieContainer
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Cookies.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Url.get -> System.Uri
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Url.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.AccessTokenProvider.get -> System.Func<System.Threading.Tasks.Task<string>>
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.AccessTokenProvider.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Credentials.get -> System.Net.ICredentials
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Credentials.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Proxy.get -> System.Net.IWebProxy
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Proxy.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.WebSocketConfiguration.get -> System.Action<System.Net.WebSockets.ClientWebSocketOptions>
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.WebSocketConfiguration.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.NoTransportSupportedException.NoTransportSupportedException(string message) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException.TransportFailedException(string transportType, string message, System.Exception innerException = null) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException.TransportType.get -> string
+override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Transport.get -> System.IO.Pipelines.IDuplexPipe!
+override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Transport.set -> void
+override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Features.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection!
+override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.ConnectionId.get -> string?
+override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.ConnectionId.set -> void
+override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Items.get -> System.Collections.Generic.IDictionary<object!, object?>!
+override Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.Items.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions! httpConnectionOptions, Microsoft.Extensions.Logging.ILoggerFactory? loggerFactory) -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(System.Uri! url) -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(System.Uri! url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.HttpConnection(System.Uri! url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, Microsoft.Extensions.Logging.ILoggerFactory? loggerFactory) -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+~Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.HttpConnectionFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions!>! options, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(System.Net.EndPoint! endPoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext!>
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.HttpMessageHandlerFactory.get -> System.Func<System.Net.Http.HttpMessageHandler!, System.Net.Http.HttpMessageHandler!>?
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.HttpMessageHandlerFactory.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Headers.get -> System.Collections.Generic.IDictionary<string!, string!>!
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Headers.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.ClientCertificates.get -> System.Security.Cryptography.X509Certificates.X509CertificateCollection?
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.ClientCertificates.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Cookies.get -> System.Net.CookieContainer!
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Cookies.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Url.get -> System.Uri?
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Url.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.AccessTokenProvider.get -> System.Func<System.Threading.Tasks.Task<string?>!>?
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.AccessTokenProvider.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Credentials.get -> System.Net.ICredentials?
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Credentials.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Proxy.get -> System.Net.IWebProxy?
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.Proxy.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.WebSocketConfiguration.get -> System.Action<System.Net.WebSockets.ClientWebSocketOptions!>?
+Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions.WebSocketConfiguration.set -> void
+Microsoft.AspNetCore.Http.Connections.Client.NoTransportSupportedException.NoTransportSupportedException(string! message) -> void
+Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException.TransportFailedException(string! transportType, string! message, System.Exception? innerException = null) -> void
+Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException.TransportType.get -> string!

+ 1 - 1
src/SignalR/clients/csharp/Http.Connections.Client/src/TransportFailedException.cs

@@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         /// <param name="transportType">The name of the transport that failed to connect.</param>
         /// <param name="transportType">The name of the transport that failed to connect.</param>
         /// <param name="message">The reason the transport failed.</param>
         /// <param name="message">The reason the transport failed.</param>
         /// <param name="innerException">An optional extra exception if one was thrown while trying to connect.</param>
         /// <param name="innerException">An optional extra exception if one was thrown while trying to connect.</param>
-        public TransportFailedException(string transportType, string message, Exception innerException = null)
+        public TransportFailedException(string transportType, string message, Exception? innerException = null)
             : base($"{transportType} failed: {message}", innerException)
             : base($"{transportType} failed: {message}", innerException)
         {
         {
             TransportType = transportType;
             TransportType = transportType;

+ 2 - 2
src/SignalR/common/Http.Connections.Common/src/AvailableTransport.cs

@@ -13,11 +13,11 @@ namespace Microsoft.AspNetCore.Http.Connections
         /// <summary>
         /// <summary>
         /// A transport available on the server.
         /// A transport available on the server.
         /// </summary>
         /// </summary>
-        public string Transport { get; set; }
+        public string? Transport { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// A list of formats supported by the transport. Examples include "Text" and "Binary".
         /// A list of formats supported by the transport. Examples include "Text" and "Binary".
         /// </summary>
         /// </summary>
-        public IList<string> TransferFormats { get; set; }
+        public IList<string>? TransferFormats { get; set; }
     }
     }
 }
 }

+ 1 - 0
src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj

@@ -7,6 +7,7 @@
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
     <RootNamespace>Microsoft.AspNetCore.Http.Connections</RootNamespace>
     <RootNamespace>Microsoft.AspNetCore.Http.Connections</RootNamespace>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 7 - 7
src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs

@@ -146,12 +146,12 @@ namespace Microsoft.AspNetCore.Http.Connections
                 reader.CheckRead();
                 reader.CheckRead();
                 reader.EnsureObjectStart();
                 reader.EnsureObjectStart();
 
 
-                string connectionId = null;
-                string connectionToken = null;
-                string url = null;
-                string accessToken = null;
-                List<AvailableTransport> availableTransports = null;
-                string error = null;
+                string? connectionId = null;
+                string? connectionToken = null;
+                string? url = null;
+                string? accessToken = null;
+                List<AvailableTransport>? availableTransports = null;
+                string? error = null;
                 int version = 0;
                 int version = 0;
 
 
                 var completed = false;
                 var completed = false;
@@ -284,7 +284,7 @@ namespace Microsoft.AspNetCore.Http.Connections
                                 switch (reader.TokenType)
                                 switch (reader.TokenType)
                                 {
                                 {
                                     case JsonTokenType.String:
                                     case JsonTokenType.String:
-                                        availableTransport.TransferFormats.Add(reader.GetString());
+                                        availableTransport.TransferFormats.Add(reader.GetString()!);
                                         break;
                                         break;
                                     case JsonTokenType.EndArray:
                                     case JsonTokenType.EndArray:
                                         completed = true;
                                         completed = true;

+ 6 - 6
src/SignalR/common/Http.Connections.Common/src/NegotiationResponse.cs

@@ -13,22 +13,22 @@ namespace Microsoft.AspNetCore.Http.Connections
         /// <summary>
         /// <summary>
         /// An optional Url to redirect the client to another endpoint.
         /// An optional Url to redirect the client to another endpoint.
         /// </summary>
         /// </summary>
-        public string Url { get; set; }
+        public string? Url { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// An optional access token to go along with the Url.
         /// An optional access token to go along with the Url.
         /// </summary>
         /// </summary>
-        public string AccessToken { get; set; }
+        public string? AccessToken { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// The public ID for the connection.
         /// The public ID for the connection.
         /// </summary>
         /// </summary>
-        public string ConnectionId { get; set; }
+        public string? ConnectionId { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// The private ID for the connection.
         /// The private ID for the connection.
         /// </summary>
         /// </summary>
-        public string ConnectionToken { get; set; }
+        public string? ConnectionToken { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// The minimum value between the version the client sends and the maximum version the server supports.
         /// The minimum value between the version the client sends and the maximum version the server supports.
@@ -38,11 +38,11 @@ namespace Microsoft.AspNetCore.Http.Connections
         /// <summary>
         /// <summary>
         /// A list of transports the server supports.
         /// A list of transports the server supports.
         /// </summary>
         /// </summary>
-        public IList<AvailableTransport> AvailableTransports { get; set; }
+        public IList<AvailableTransport>? AvailableTransports { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// An optional error during the negotiate. If this is not null the other properties on the response can be ignored.
         /// An optional error during the negotiate. If this is not null the other properties on the response can be ignored.
         /// </summary>
         /// </summary>
-        public string Error { get; set; }
+        public string? Error { get; set; }
     }
     }
 }
 }

+ 36 - 0
src/SignalR/common/Http.Connections.Common/src/PublicAPI.Unshipped.txt

@@ -1,2 +1,38 @@
 #nullable enable
 #nullable enable
 *REMOVED*~static Microsoft.AspNetCore.Http.Connections.NegotiateProtocol.ParseResponse(System.IO.Stream content) -> Microsoft.AspNetCore.Http.Connections.NegotiationResponse
 *REMOVED*~static Microsoft.AspNetCore.Http.Connections.NegotiateProtocol.ParseResponse(System.IO.Stream content) -> Microsoft.AspNetCore.Http.Connections.NegotiationResponse
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.AvailableTransport.Transport.get -> string
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.AvailableTransport.Transport.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.AvailableTransport.TransferFormats.get -> System.Collections.Generic.IList<string>
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.AvailableTransport.TransferFormats.set -> void
+*REMOVED*~static Microsoft.AspNetCore.Http.Connections.NegotiateProtocol.WriteResponse(Microsoft.AspNetCore.Http.Connections.NegotiationResponse response, System.Buffers.IBufferWriter<byte> output) -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AccessToken.get -> string
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AccessToken.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AvailableTransports.get -> System.Collections.Generic.IList<Microsoft.AspNetCore.Http.Connections.AvailableTransport>
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AvailableTransports.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionId.get -> string
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionId.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionToken.get -> string
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionToken.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Error.get -> string
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Error.set -> void
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Url.get -> string
+*REMOVED*~Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Url.set -> void
+*REMOVED*~static Microsoft.AspNetCore.Http.Connections.NegotiateProtocol.ParseResponse(System.ReadOnlySpan<byte> content) -> Microsoft.AspNetCore.Http.Connections.NegotiationResponse
+Microsoft.AspNetCore.Http.Connections.AvailableTransport.Transport.get -> string?
+Microsoft.AspNetCore.Http.Connections.AvailableTransport.Transport.set -> void
+Microsoft.AspNetCore.Http.Connections.AvailableTransport.TransferFormats.get -> System.Collections.Generic.IList<string!>?
+Microsoft.AspNetCore.Http.Connections.AvailableTransport.TransferFormats.set -> void
+static Microsoft.AspNetCore.Http.Connections.NegotiateProtocol.WriteResponse(Microsoft.AspNetCore.Http.Connections.NegotiationResponse! response, System.Buffers.IBufferWriter<byte>! output) -> void
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AccessToken.get -> string?
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AccessToken.set -> void
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AvailableTransports.get -> System.Collections.Generic.IList<Microsoft.AspNetCore.Http.Connections.AvailableTransport!>?
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.AvailableTransports.set -> void
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionId.get -> string?
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionId.set -> void
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionToken.get -> string?
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.ConnectionToken.set -> void
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Error.get -> string?
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Error.set -> void
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Url.get -> string?
+Microsoft.AspNetCore.Http.Connections.NegotiationResponse.Url.set -> void
+static Microsoft.AspNetCore.Http.Connections.NegotiateProtocol.ParseResponse(System.ReadOnlySpan<byte> content) -> Microsoft.AspNetCore.Http.Connections.NegotiationResponse!

+ 2 - 6
src/SignalR/common/Http.Connections/src/Features/IHttpContextFeature.cs

@@ -1,11 +1,7 @@
 // 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.
 // 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.Connections;
-using Microsoft.AspNetCore.Http;
 
 
 namespace Microsoft.AspNetCore.Http.Connections.Features
 namespace Microsoft.AspNetCore.Http.Connections.Features
 {
 {
@@ -16,12 +12,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Features
     public interface IHttpContextFeature
     public interface IHttpContextFeature
     {
     {
         /// <summary>
         /// <summary>
-        /// The <see cref="Http.HttpContext"/> associated with the connection if available. 
+        /// The <see cref="Http.HttpContext"/> associated with the connection if available.
         /// </summary>
         /// </summary>
         /// <remarks>
         /// <remarks>
         /// Connections can run on top of HTTP transports like WebSockets or Long Polling, or other non-HTTP transports. As a result,
         /// 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 <see langword="null"/> depending on the configuration of your application.
         /// this API can sometimes return <see langword="null"/> depending on the configuration of your application.
         /// </remarks>
         /// </remarks>
-        HttpContext HttpContext { get; set; }
+        HttpContext? HttpContext { get; set; }
     }
     }
 }
 }

+ 8 - 10
src/SignalR/common/Http.Connections/src/Internal/ConnectionLogScope.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -10,24 +8,24 @@ using System.Globalization;
 
 
 namespace Microsoft.AspNetCore.Http.Connections.Internal
 namespace Microsoft.AspNetCore.Http.Connections.Internal
 {
 {
-    internal class ConnectionLogScope : IReadOnlyList<KeyValuePair<string, object>>
+    internal class ConnectionLogScope : IReadOnlyList<KeyValuePair<string, object?>>
     {
     {
-        private string _cachedToString;
+        private string? _cachedToString;
 
 
-        public string ConnectionId { get; set; }
+        public string? ConnectionId { get; set; }
 
 
-        public ConnectionLogScope(string connectionId)
+        public ConnectionLogScope(string? connectionId)
         {
         {
             ConnectionId = connectionId;
             ConnectionId = connectionId;
         }
         }
 
 
-        public KeyValuePair<string, object> this[int index]
+        public KeyValuePair<string, object?> this[int index]
         {
         {
             get
             get
             {
             {
                 if (Count == 1 && index == 0)
                 if (Count == 1 && index == 0)
                 {
                 {
-                    return new KeyValuePair<string, object>("TransportConnectionId", ConnectionId);
+                    return new KeyValuePair<string, object?>("TransportConnectionId", ConnectionId);
                 }
                 }
 
 
                 throw new ArgumentOutOfRangeException(nameof(index));
                 throw new ArgumentOutOfRangeException(nameof(index));
@@ -36,7 +34,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
 
 
         public int Count => string.IsNullOrEmpty(ConnectionId) ? 0 : 1;
         public int Count => string.IsNullOrEmpty(ConnectionId) ? 0 : 1;
 
 
-        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+        public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
         {
         {
             for (var i = 0; i < Count; ++i)
             for (var i = 0; i < Count; ++i)
             {
             {
@@ -49,7 +47,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             return GetEnumerator();
             return GetEnumerator();
         }
         }
 
 
-        public override string ToString()
+        public override string? ToString()
         {
         {
             if (_cachedToString == null)
             if (_cachedToString == null)
             {
             {

+ 36 - 42
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionContext.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -40,14 +38,14 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
         private readonly object _stateLock = new object();
         private readonly object _stateLock = new object();
         private readonly object _itemsLock = new object();
         private readonly object _itemsLock = new object();
         private readonly object _heartbeatLock = new object();
         private readonly object _heartbeatLock = new object();
-        private List<(Action<object> handler, object state)> _heartbeatHandlers;
+        private List<(Action<object> handler, object state)>? _heartbeatHandlers;
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private PipeWriterStream _applicationStream;
         private PipeWriterStream _applicationStream;
         private IDuplexPipe _application;
         private IDuplexPipe _application;
-        private IDictionary<object, object> _items;
+        private IDictionary<object, object?>? _items;
         private CancellationTokenSource _connectionClosedTokenSource;
         private CancellationTokenSource _connectionClosedTokenSource;
 
 
-        private CancellationTokenSource _sendCts;
+        private CancellationTokenSource? _sendCts;
         private bool _activeSend;
         private bool _activeSend;
         private long _startedSendTime;
         private long _startedSendTime;
         private readonly object _sendingLock = new object();
         private readonly object _sendingLock = new object();
@@ -61,11 +59,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
         /// Creates the DefaultConnectionContext without Pipes to avoid upfront allocations.
         /// Creates the DefaultConnectionContext without Pipes to avoid upfront allocations.
         /// The caller is expected to set the <see cref="Transport"/> and <see cref="Application"/> pipes manually.
         /// The caller is expected to set the <see cref="Transport"/> and <see cref="Application"/> pipes manually.
         /// </summary>
         /// </summary>
-        /// <param name="connectionId"></param>
-        /// <param name="connectionToken"></param>
-        /// <param name="logger"></param>
-        public HttpConnectionContext(string connectionId, string connectionToken, ILogger logger)
+        public HttpConnectionContext(string connectionId, string connectionToken, ILogger logger, IDuplexPipe transport, IDuplexPipe application)
         {
         {
+            Transport = transport;
+            _applicationStream = new PipeWriterStream(application.Output);
+            _application = application;
+
             ConnectionId = connectionId;
             ConnectionId = connectionId;
             ConnectionToken = connectionToken;
             ConnectionToken = connectionToken;
             LastSeenUtc = DateTime.UtcNow;
             LastSeenUtc = DateTime.UtcNow;
@@ -93,23 +92,23 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             ConnectionClosed = _connectionClosedTokenSource.Token;
             ConnectionClosed = _connectionClosedTokenSource.Token;
         }
         }
 
 
-        public CancellationTokenSource Cancellation { get; set; }
+        public CancellationTokenSource? Cancellation { get; set; }
 
 
         public HttpTransportType TransportType { get; set; }
         public HttpTransportType TransportType { get; set; }
 
 
         public SemaphoreSlim WriteLock { get; } = new SemaphoreSlim(1, 1);
         public SemaphoreSlim WriteLock { get; } = new SemaphoreSlim(1, 1);
 
 
         // Used for testing only
         // Used for testing only
-        internal Task DisposeAndRemoveTask { get; set; }
+        internal Task? DisposeAndRemoveTask { get; set; }
 
 
         // Used for LongPolling because we need to create a scope that spans the lifetime of multiple requests on the cloned HttpContext
         // Used for LongPolling because we need to create a scope that spans the lifetime of multiple requests on the cloned HttpContext
-        internal IServiceScope ServiceScope { get; set; }
+        internal IServiceScope? ServiceScope { get; set; }
 
 
-        public Task TransportTask { get; set; }
+        public Task? TransportTask { get; set; }
 
 
         public Task PreviousPollTask { get; set; } = Task.CompletedTask;
         public Task PreviousPollTask { get; set; } = Task.CompletedTask;
 
 
-        public Task ApplicationTask { get; set; }
+        public Task? ApplicationTask { get; set; }
 
 
         public DateTime LastSeenUtc { get; set; }
         public DateTime LastSeenUtc { get; set; }
 
 
@@ -132,11 +131,11 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
 
 
         public override IFeatureCollection Features { get; }
         public override IFeatureCollection Features { get; }
 
 
-        public ClaimsPrincipal User { get; set; }
+        public ClaimsPrincipal? User { get; set; }
 
 
         public bool HasInherentKeepAlive { get; set; }
         public bool HasInherentKeepAlive { get; set; }
 
 
-        public override IDictionary<object, object> Items
+        public override IDictionary<object, object?> Items
         {
         {
             get
             get
             {
             {
@@ -146,7 +145,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                     {
                     {
                         if (_items == null)
                         if (_items == null)
                         {
                         {
-                            _items = new ConnectionItems(new ConcurrentDictionary<object, object>());
+                            _items = new ConnectionItems(new ConcurrentDictionary<object, object?>());
                         }
                         }
                     }
                     }
                 }
                 }
@@ -160,14 +159,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             get => _application;
             get => _application;
             set
             set
             {
             {
-                if (value != null)
-                {
-                    _applicationStream = new PipeWriterStream(value.Output);
-                }
-                else
-                {
-                    _applicationStream = null;
-                }
+                _applicationStream = new PipeWriterStream(value.Output);
                 _application = value;
                 _application = value;
             }
             }
         }
         }
@@ -180,13 +172,13 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
 
 
         public TransferFormat ActiveFormat { get; set; }
         public TransferFormat ActiveFormat { get; set; }
 
 
-        public HttpContext HttpContext { get; set; }
+        public HttpContext? HttpContext { get; set; }
 
 
         public override CancellationToken ConnectionClosed { get; set; }
         public override CancellationToken ConnectionClosed { get; set; }
 
 
         public override void Abort()
         public override void Abort()
         {
         {
-            ThreadPool.UnsafeQueueUserWorkItem(cts => ((CancellationTokenSource)cts).Cancel(), _connectionClosedTokenSource);
+            ThreadPool.UnsafeQueueUserWorkItem(cts => ((CancellationTokenSource)cts!).Cancel(), _connectionClosedTokenSource);
 
 
             HttpContext?.Abort();
             HttpContext?.Abort();
         }
         }
@@ -330,7 +322,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                         Application?.Input.Complete();
                         Application?.Input.Complete();
 
 
                         // Trigger ConnectionClosed
                         // Trigger ConnectionClosed
-                        ThreadPool.UnsafeQueueUserWorkItem(cts => ((CancellationTokenSource)cts).Cancel(), _connectionClosedTokenSource);
+                        ThreadPool.UnsafeQueueUserWorkItem(cts => ((CancellationTokenSource)cts!).Cancel(), _connectionClosedTokenSource);
                     }
                     }
                 }
                 }
                 else
                 else
@@ -340,7 +332,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                     Application?.Input.Complete();
                     Application?.Input.Complete();
 
 
                     // Trigger ConnectionClosed
                     // Trigger ConnectionClosed
-                    ThreadPool.UnsafeQueueUserWorkItem(cts => ((CancellationTokenSource)cts).Cancel(), _connectionClosedTokenSource);
+                    ThreadPool.UnsafeQueueUserWorkItem(cts => ((CancellationTokenSource)cts!).Cancel(), _connectionClosedTokenSource);
 
 
                     try
                     try
                     {
                     {
@@ -378,6 +370,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
         internal bool TryActivatePersistentConnection(
         internal bool TryActivatePersistentConnection(
             ConnectionDelegate connectionDelegate,
             ConnectionDelegate connectionDelegate,
             IHttpTransport transport,
             IHttpTransport transport,
+            HttpContext context,
             ILogger dispatcherLogger)
             ILogger dispatcherLogger)
         {
         {
             lock (_stateLock)
             lock (_stateLock)
@@ -390,13 +383,13 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                     ApplicationTask = ExecuteApplication(connectionDelegate);
                     ApplicationTask = ExecuteApplication(connectionDelegate);
 
 
                     // Start the transport
                     // Start the transport
-                    TransportTask = transport.ProcessRequestAsync(HttpContext, HttpContext.RequestAborted);
+                    TransportTask = transport.ProcessRequestAsync(context, context.RequestAborted);
 
 
                     return true;
                     return true;
                 }
                 }
                 else
                 else
                 {
                 {
-                    FailActivationUnsynchronized(HttpContext, dispatcherLogger);
+                    FailActivationUnsynchronized(context, dispatcherLogger);
 
 
                     return false;
                     return false;
                 }
                 }
@@ -473,7 +466,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
         {
         {
             if (Status == HttpConnectionStatus.Active)
             if (Status == HttpConnectionStatus.Active)
             {
             {
-                HttpConnectionDispatcher.Log.ConnectionAlreadyActive(dispatcherLogger, ConnectionId, HttpContext.TraceIdentifier);
+                HttpConnectionDispatcher.Log.ConnectionAlreadyActive(dispatcherLogger, ConnectionId, HttpContext!.TraceIdentifier);
 
 
                 // Reject the request with a 409 conflict
                 // Reject the request with a 409 conflict
                 nonClonedContext.Response.StatusCode = StatusCodes.Status409Conflict;
                 nonClonedContext.Response.StatusCode = StatusCodes.Status409Conflict;
@@ -493,7 +486,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
 
 
         internal async Task<bool> CancelPreviousPoll(HttpContext context)
         internal async Task<bool> CancelPreviousPoll(HttpContext context)
         {
         {
-            CancellationTokenSource cts;
+            CancellationTokenSource? cts;
             lock (_stateLock)
             lock (_stateLock)
             {
             {
                 // Need to sync cts access with DisposeAsync as that will dispose the cts
                 // Need to sync cts access with DisposeAsync as that will dispose the cts
@@ -576,7 +569,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                 {
                 {
                     if (currentTicks - _startedSendTime > _tenSeconds)
                     if (currentTicks - _startedSendTime > _tenSeconds)
                     {
                     {
-                        _sendCts.Cancel();
+                        _sendCts!.Cancel();
                     }
                     }
                 }
                 }
             }
             }
@@ -591,28 +584,28 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
 
 
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, string, Exception> _disposingConnection =
+            private static readonly Action<ILogger, string, Exception?> _disposingConnection =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(1, "DisposingConnection"), "Disposing connection {TransportConnectionId}.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(1, "DisposingConnection"), "Disposing connection {TransportConnectionId}.");
 
 
-            private static readonly Action<ILogger, Exception> _waitingForApplication =
+            private static readonly Action<ILogger, Exception?> _waitingForApplication =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(2, "WaitingForApplication"), "Waiting for application to complete.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(2, "WaitingForApplication"), "Waiting for application to complete.");
 
 
-            private static readonly Action<ILogger, Exception> _applicationComplete =
+            private static readonly Action<ILogger, Exception?> _applicationComplete =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(3, "ApplicationComplete"), "Application complete.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(3, "ApplicationComplete"), "Application complete.");
 
 
-            private static readonly Action<ILogger, HttpTransportType, Exception> _waitingForTransport =
+            private static readonly Action<ILogger, HttpTransportType, Exception?> _waitingForTransport =
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(4, "WaitingForTransport"), "Waiting for {TransportType} transport to complete.");
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(4, "WaitingForTransport"), "Waiting for {TransportType} transport to complete.");
 
 
-            private static readonly Action<ILogger, HttpTransportType, Exception> _transportComplete =
+            private static readonly Action<ILogger, HttpTransportType, Exception?> _transportComplete =
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(5, "TransportComplete"), "{TransportType} transport complete.");
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(5, "TransportComplete"), "{TransportType} transport complete.");
 
 
-            private static readonly Action<ILogger, HttpTransportType, Exception> _shuttingDownTransportAndApplication =
+            private static readonly Action<ILogger, HttpTransportType, Exception?> _shuttingDownTransportAndApplication =
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(6, "ShuttingDownTransportAndApplication"), "Shutting down both the application and the {TransportType} transport.");
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(6, "ShuttingDownTransportAndApplication"), "Shutting down both the application and the {TransportType} transport.");
 
 
-            private static readonly Action<ILogger, HttpTransportType, Exception> _waitingForTransportAndApplication =
+            private static readonly Action<ILogger, HttpTransportType, Exception?> _waitingForTransportAndApplication =
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(7, "WaitingForTransportAndApplication"), "Waiting for both the application and {TransportType} transport to complete.");
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(7, "WaitingForTransportAndApplication"), "Waiting for both the application and {TransportType} transport to complete.");
 
 
-            private static readonly Action<ILogger, HttpTransportType, Exception> _transportAndApplicationComplete =
+            private static readonly Action<ILogger, HttpTransportType, Exception?> _transportAndApplicationComplete =
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(8, "TransportAndApplicationComplete"), "The application and {TransportType} transport are both complete.");
                 LoggerMessage.Define<HttpTransportType>(LogLevel.Trace, new EventId(8, "TransportAndApplicationComplete"), "The application and {TransportType} transport are both complete.");
 
 
             public static void DisposingConnection(ILogger logger, string connectionId)
             public static void DisposingConnection(ILogger logger, string connectionId)
@@ -664,6 +657,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
 
 
                 _transportComplete(logger, transportType, null);
                 _transportComplete(logger, transportType, null);
             }
             }
+
             public static void ShuttingDownTransportAndApplication(ILogger logger, HttpTransportType transportType)
             public static void ShuttingDownTransportAndApplication(ILogger logger, HttpTransportType transportType)
             {
             {
                 if (logger == null)
                 if (logger == null)

+ 16 - 18
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -63,7 +61,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             // the Connection ID metadata. If this is the negotiate request then the Connection ID for the scope will
             // the Connection ID metadata. If this is the negotiate request then the Connection ID for the scope will
             // be set a little later.
             // be set a little later.
 
 
-            HttpConnectionContext connectionContext = null;
+            HttpConnectionContext? connectionContext = null;
             var connectionToken = GetConnectionToken(context);
             var connectionToken = GetConnectionToken(context);
             if (connectionToken != null)
             if (connectionToken != null)
             {
             {
@@ -208,7 +206,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                     return;
                     return;
                 }
                 }
 
 
-                var resultTask = await Task.WhenAny(connection.ApplicationTask, connection.TransportTask);
+                var resultTask = await Task.WhenAny(connection.ApplicationTask!, connection.TransportTask!);
 
 
                 try
                 try
                 {
                 {
@@ -221,7 +219,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                         // Wait for the transport to run
                         // Wait for the transport to run
                         // Ignore exceptions, it has been logged if there is one and the application has finished
                         // Ignore exceptions, it has been logged if there is one and the application has finished
                         // So there is no one to give the exception to
                         // So there is no one to give the exception to
-                        await connection.TransportTask.NoThrow();
+                        await connection.TransportTask!.NoThrow();
 
 
                         // If the status code is a 204 it means the connection is done
                         // If the status code is a 204 it means the connection is done
                         if (context.Response.StatusCode == StatusCodes.Status204NoContent)
                         if (context.Response.StatusCode == StatusCodes.Status204NoContent)
@@ -267,10 +265,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                                                   HttpContext context,
                                                   HttpContext context,
                                                   HttpConnectionContext connection)
                                                   HttpConnectionContext connection)
         {
         {
-            if (connection.TryActivatePersistentConnection(connectionDelegate, transport, _logger))
+            if (connection.TryActivatePersistentConnection(connectionDelegate, transport, context, _logger))
             {
             {
                 // Wait for any of them to end
                 // Wait for any of them to end
-                await Task.WhenAny(connection.ApplicationTask, connection.TransportTask);
+                await Task.WhenAny(connection.ApplicationTask!, connection.TransportTask!);
 
 
                 await _manager.DisposeAndRemoveAsync(connection, closeGracefully: true);
                 await _manager.DisposeAndRemoveAsync(connection, closeGracefully: true);
             }
             }
@@ -279,7 +277,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
         private async Task ProcessNegotiate(HttpContext context, HttpConnectionDispatcherOptions options, ConnectionLogScope logScope)
         private async Task ProcessNegotiate(HttpContext context, HttpConnectionDispatcherOptions options, ConnectionLogScope logScope)
         {
         {
             context.Response.ContentType = "application/json";
             context.Response.ContentType = "application/json";
-            string error = null;
+            string? error = null;
             int clientProtocolVersion = 0;
             int clientProtocolVersion = 0;
             if (context.Request.Query.TryGetValue("NegotiateVersion", out var queryStringVersion))
             if (context.Request.Query.TryGetValue("NegotiateVersion", out var queryStringVersion))
             {
             {
@@ -308,7 +306,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             }
             }
 
 
             // Establish the connection
             // Establish the connection
-            HttpConnectionContext connection = null;
+            HttpConnectionContext? connection = null;
             if (error == null)
             if (error == null)
             {
             {
                 connection = CreateConnection(options, clientProtocolVersion);
                 connection = CreateConnection(options, clientProtocolVersion);
@@ -338,8 +336,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             }
             }
         }
         }
 
 
-        private void WriteNegotiatePayload(IBufferWriter<byte> writer, string connectionId, string connectionToken, HttpContext context, HttpConnectionDispatcherOptions options,
-            int clientProtocolVersion, string error)
+        private void WriteNegotiatePayload(IBufferWriter<byte> writer, string? connectionId, string? connectionToken, HttpContext context, HttpConnectionDispatcherOptions options,
+            int clientProtocolVersion, string? error)
         {
         {
             var response = new NegotiationResponse();
             var response = new NegotiationResponse();
 
 
@@ -563,7 +561,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             }
             }
 
 
             // Setup the connection state from the http context
             // Setup the connection state from the http context
-            connection.User = connection.HttpContext.User;
+            connection.User = connection.HttpContext?.User;
 
 
             // Set the Connection ID on the logging scope so that logs from now on will have the
             // Set the Connection ID on the logging scope so that logs from now on will have the
             // Connection ID metadata set.
             // Connection ID metadata set.
@@ -613,7 +611,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             // The reason we're copying the base features instead of the HttpContext properties is
             // The reason we're copying the base features instead of the HttpContext properties is
             // so that we can get all of the logic built into DefaultHttpContext to extract higher level
             // so that we can get all of the logic built into DefaultHttpContext to extract higher level
             // structure from the low level properties
             // structure from the low level properties
-            var existingRequestFeature = context.Features.Get<IHttpRequestFeature>();
+            var existingRequestFeature = context.Features.Get<IHttpRequestFeature>()!;
 
 
             var requestFeature = new HttpRequestFeature();
             var requestFeature = new HttpRequestFeature();
             requestFeature.Protocol = existingRequestFeature.Protocol;
             requestFeature.Protocol = existingRequestFeature.Protocol;
@@ -666,12 +664,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             newHttpContext.RequestServices = connection.ServiceScope.ServiceProvider;
             newHttpContext.RequestServices = connection.ServiceScope.ServiceProvider;
 
 
             // REVIEW: This extends the lifetime of anything that got put into HttpContext.Items
             // REVIEW: This extends the lifetime of anything that got put into HttpContext.Items
-            newHttpContext.Items = new Dictionary<object, object>(context.Items);
+            newHttpContext.Items = new Dictionary<object, object?>(context.Items);
 
 
             connection.HttpContext = newHttpContext;
             connection.HttpContext = newHttpContext;
         }
         }
 
 
-        private async Task<HttpConnectionContext> GetConnectionAsync(HttpContext context)
+        private async Task<HttpConnectionContext?> GetConnectionAsync(HttpContext context)
         {
         {
             var connectionToken = GetConnectionToken(context);
             var connectionToken = GetConnectionToken(context);
 
 
@@ -697,10 +695,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
         }
         }
 
 
         // This is only used for WebSockets connections, which can connect directly without negotiating
         // This is only used for WebSockets connections, which can connect directly without negotiating
-        private async Task<HttpConnectionContext> GetOrCreateConnectionAsync(HttpContext context, HttpConnectionDispatcherOptions options)
+        private async Task<HttpConnectionContext?> GetOrCreateConnectionAsync(HttpContext context, HttpConnectionDispatcherOptions options)
         {
         {
             var connectionToken = GetConnectionToken(context);
             var connectionToken = GetConnectionToken(context);
-            HttpConnectionContext connection;
+            HttpConnectionContext? connection;
 
 
             // There's no connection id so this is a brand new connection
             // There's no connection id so this is a brand new connection
             if (StringValues.IsNullOrEmpty(connectionToken))
             if (StringValues.IsNullOrEmpty(connectionToken))
@@ -728,7 +726,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
         private class EmptyServiceProvider : IServiceProvider
         private class EmptyServiceProvider : IServiceProvider
         {
         {
             public static EmptyServiceProvider Instance { get; } = new EmptyServiceProvider();
             public static EmptyServiceProvider Instance { get; } = new EmptyServiceProvider();
-            public object GetService(Type serviceType) => null;
+            public object? GetService(Type serviceType) => null;
         }
         }
     }
     }
 }
 }

+ 1 - 3
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs

@@ -87,10 +87,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
 
 
             Log.CreatedNewConnection(_logger, id);
             Log.CreatedNewConnection(_logger, id);
             var connectionTimer = HttpConnectionsEventSource.Log.ConnectionStart(id);
             var connectionTimer = HttpConnectionsEventSource.Log.ConnectionStart(id);
-            var connection = new HttpConnectionContext(id, connectionToken, _connectionLogger);
             var pair = DuplexPipe.CreateConnectionPair(transportPipeOptions, appPipeOptions);
             var pair = DuplexPipe.CreateConnectionPair(transportPipeOptions, appPipeOptions);
-            connection.Transport = pair.Application;
-            connection.Application = pair.Transport;
+            var connection = new HttpConnectionContext(id, connectionToken, _connectionLogger, pair.Application, pair.Transport);
 
 
             _connections.TryAdd(connectionToken, (connection, connectionTimer));
             _connections.TryAdd(connectionToken, (connection, connectionTimer));
 
 

+ 6 - 8
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionsEventSource.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System.Diagnostics.Tracing;
 using System.Diagnostics.Tracing;
 using System.Threading;
 using System.Threading;
 using Microsoft.Extensions.Internal;
 using Microsoft.Extensions.Internal;
@@ -13,11 +11,11 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
     {
     {
         public static readonly HttpConnectionsEventSource Log = new HttpConnectionsEventSource();
         public static readonly HttpConnectionsEventSource Log = new HttpConnectionsEventSource();
 
 
-        private PollingCounter _connectionsStartedCounter;
-        private PollingCounter _connectionsStoppedCounter;
-        private PollingCounter _connectionsTimedOutCounter;
-        private PollingCounter _currentConnectionsCounter;
-        private EventCounter _connectionDuration;
+        private PollingCounter? _connectionsStartedCounter;
+        private PollingCounter? _connectionsStoppedCounter;
+        private PollingCounter? _connectionsTimedOutCounter;
+        private PollingCounter? _currentConnectionsCounter;
+        private EventCounter? _connectionDuration;
 
 
         private long _connectionsStarted;
         private long _connectionsStarted;
         private long _connectionsStopped;
         private long _connectionsStopped;
@@ -46,7 +44,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
             if (IsEnabled())
             if (IsEnabled())
             {
             {
                 var duration = timer.IsActive ? timer.GetElapsedTime().TotalMilliseconds : 0.0;
                 var duration = timer.IsActive ? timer.GetElapsedTime().TotalMilliseconds : 0.0;
-                _connectionDuration.WriteMetric(duration);
+                _connectionDuration!.WriteMetric(duration);
 
 
                 if (IsEnabled(EventLevel.Informational, EventKeywords.None))
                 if (IsEnabled(EventLevel.Informational, EventKeywords.None))
                 {
                 {

+ 2 - 0
src/SignalR/common/Http.Connections/src/PublicAPI.Unshipped.txt

@@ -1 +1,3 @@
 #nullable enable
 #nullable enable
+*REMOVED*Microsoft.AspNetCore.Http.Connections.Features.IHttpContextFeature.HttpContext.get -> Microsoft.AspNetCore.Http.HttpContext!
+Microsoft.AspNetCore.Http.Connections.Features.IHttpContextFeature.HttpContext.get -> Microsoft.AspNetCore.Http.HttpContext?

+ 19 - 65
src/SignalR/common/Http.Connections/test/WebSocketsTests.cs

@@ -14,7 +14,6 @@ using Microsoft.AspNetCore.Http.Connections.Internal;
 using Microsoft.AspNetCore.Http.Connections.Internal.Transports;
 using Microsoft.AspNetCore.Http.Connections.Internal.Transports;
 using Microsoft.AspNetCore.Http.Features;
 using Microsoft.AspNetCore.Http.Features;
 using Microsoft.AspNetCore.SignalR.Tests;
 using Microsoft.AspNetCore.SignalR.Tests;
-using Microsoft.Extensions.Logging;
 using Microsoft.Net.Http.Headers;
 using Microsoft.Net.Http.Headers;
 using Xunit;
 using Xunit;
 
 
@@ -31,16 +30,11 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext1"))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext1"), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
-                    var connectionContext = new HttpConnectionContext(string.Empty, connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext2"));
-                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connection, LoggerFactory);
 
 
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
@@ -83,17 +77,12 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext1"))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext1"), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
-                    var connectionContext = new HttpConnectionContext(string.Empty, connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext2"));
-                    connectionContext.ActiveFormat = transferFormat;
-                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connectionContext, LoggerFactory);
+                    connection.ActiveFormat = transferFormat;
+                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connection, LoggerFactory);
 
 
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
@@ -124,11 +113,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext1"))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext1"), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
@@ -151,8 +136,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
                         }
                         }
                     }
                     }
 
 
-                    var connectionContext = new HttpConnectionContext(string.Empty, connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext2"));
-                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connection, LoggerFactory);
 
 
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
@@ -181,16 +165,11 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
-                    var connectionContext = new HttpConnectionContext(string.Empty, null, null);
-                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connection, LoggerFactory);
 
 
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
                     var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
@@ -217,11 +196,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
@@ -230,8 +205,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
                         CloseTimeout = TimeSpan.FromSeconds(1)
                         CloseTimeout = TimeSpan.FromSeconds(1)
                     };
                     };
 
 
-                    var connectionContext = new HttpConnectionContext(string.Empty, null, null);
-                    var ws = new WebSocketsServerTransport(options, connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(options, connection.Application, connection, LoggerFactory);
 
 
                     var serverSocket = await feature.AcceptAsync();
                     var serverSocket = await feature.AcceptAsync();
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
@@ -256,11 +230,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
@@ -269,8 +239,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
                         CloseTimeout = TimeSpan.FromSeconds(1)
                         CloseTimeout = TimeSpan.FromSeconds(1)
                     };
                     };
 
 
-                    var connectionContext = new HttpConnectionContext(string.Empty, null, null);
-                    var ws = new WebSocketsServerTransport(options, connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(options, connection.Application, connection, LoggerFactory);
 
 
                     var serverSocket = await feature.AcceptAsync();
                     var serverSocket = await feature.AcceptAsync();
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
@@ -295,11 +264,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
@@ -309,8 +274,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
                         CloseTimeout = TimeSpan.FromSeconds(20)
                         CloseTimeout = TimeSpan.FromSeconds(20)
                     };
                     };
 
 
-                    var connectionContext = new HttpConnectionContext(string.Empty, null, null);
-                    var ws = new WebSocketsServerTransport(options, connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(options, connection.Application, connection, LoggerFactory);
 
 
                     var serverSocket = await feature.AcceptAsync();
                     var serverSocket = await feature.AcceptAsync();
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
@@ -339,11 +303,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
@@ -353,8 +313,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
                         CloseTimeout = TimeSpan.FromSeconds(20)
                         CloseTimeout = TimeSpan.FromSeconds(20)
                     };
                     };
 
 
-                    var connectionContext = new HttpConnectionContext(string.Empty, null, null);
-                    var ws = new WebSocketsServerTransport(options, connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(options, connection.Application, connection, LoggerFactory);
 
 
                     var serverSocket = await feature.AcceptAsync();
                     var serverSocket = await feature.AcceptAsync();
                     // Give the server socket to the transport and run it
                     // Give the server socket to the transport and run it
@@ -386,11 +345,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
             using (StartVerifiableLog())
             using (StartVerifiableLog())
             {
             {
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                 var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
-                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)))
-                {
-                    Transport = pair.Transport,
-                    Application = pair.Application,
-                };
+                var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext)), pair.Transport, pair.Application);
 
 
                 using (var feature = new TestWebSocketConnectionFeature())
                 using (var feature = new TestWebSocketConnectionFeature())
                 {
                 {
@@ -404,8 +359,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests
                         },
                         },
                     };
                     };
 
 
-                    var connectionContext = new HttpConnectionContext(string.Empty, null, null);
-                    var ws = new WebSocketsServerTransport(options, connection.Application, connectionContext, LoggerFactory);
+                    var ws = new WebSocketsServerTransport(options, connection.Application, connection, LoggerFactory);
 
 
                     // Create an HttpContext
                     // Create an HttpContext
                     var context = new DefaultHttpContext();
                     var context = new DefaultHttpContext();

+ 55 - 32
src/SignalR/common/Protocols.Json/src/Protocol/JsonHubProtocol.cs

@@ -1,12 +1,11 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.IO;
 using System.Runtime.ExceptionServices;
 using System.Runtime.ExceptionServices;
 using System.Text.Encodings.Web;
 using System.Text.Encodings.Web;
@@ -84,7 +83,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, out HubMessage message)
+        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, [NotNullWhen(true)] out HubMessage? message)
         {
         {
             if (!TextMessageParser.TryParseMessage(ref input, out var payload))
             if (!TextMessageParser.TryParseMessage(ref input, out var payload))
             {
             {
@@ -110,7 +109,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return HubProtocolExtensions.GetMessageBytes(this, message);
             return HubProtocolExtensions.GetMessageBytes(this, message);
         }
         }
 
 
-        private HubMessage ParseMessage(ReadOnlySequence<byte> input, IInvocationBinder binder)
+        private HubMessage? ParseMessage(ReadOnlySequence<byte> input, IInvocationBinder binder)
         {
         {
             try
             try
             {
             {
@@ -119,24 +118,24 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 // if we're lucky and the state we need to directly parse is available, then we'll use it.
                 // if we're lucky and the state we need to directly parse is available, then we'll use it.
 
 
                 int? type = null;
                 int? type = null;
-                string invocationId = null;
-                string target = null;
-                string error = null;
+                string? invocationId = null;
+                string? target = null;
+                string? error = null;
                 var hasItem = false;
                 var hasItem = false;
-                object item = null;
+                object? item = null;
                 var hasResult = false;
                 var hasResult = false;
-                object result = null;
+                object? result = null;
                 var hasArguments = false;
                 var hasArguments = false;
-                object[] arguments = null;
-                string[] streamIds = null;
+                object?[]? arguments = null;
+                string[]? streamIds = null;
                 bool hasArgumentsToken = false;
                 bool hasArgumentsToken = false;
                 Utf8JsonReader argumentsToken = default;
                 Utf8JsonReader argumentsToken = default;
                 bool hasItemsToken = false;
                 bool hasItemsToken = false;
                 Utf8JsonReader itemsToken = default;
                 Utf8JsonReader itemsToken = default;
                 bool hasResultToken = false;
                 bool hasResultToken = false;
                 Utf8JsonReader resultToken = default;
                 Utf8JsonReader resultToken = default;
-                ExceptionDispatchInfo argumentBindingException = null;
-                Dictionary<string, string> headers = null;
+                ExceptionDispatchInfo? argumentBindingException = null;
+                Dictionary<string, string>? headers = null;
                 var completed = false;
                 var completed = false;
                 var allowReconnect = false;
                 var allowReconnect = false;
 
 
@@ -179,7 +178,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                                 reader.Read();
                                 reader.Read();
                                 while (reader.TokenType != JsonTokenType.EndArray)
                                 while (reader.TokenType != JsonTokenType.EndArray)
                                 {
                                 {
-                                    newStreamIds.Add(reader.GetString());
+                                    newStreamIds.Add(reader.GetString() ?? throw new InvalidDataException($"Null value for '{StreamIdsPropertyName}' is not valid."));
                                     reader.Read();
                                     reader.Read();
                                 }
                                 }
 
 
@@ -223,7 +222,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
 
 
                                 hasItem = true;
                                 hasItem = true;
 
 
-                                string id = null;
+                                string? id = null;
                                 if (!string.IsNullOrEmpty(invocationId))
                                 if (!string.IsNullOrEmpty(invocationId))
                                 {
                                 {
                                     id = invocationId;
                                     id = invocationId;
@@ -311,6 +310,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 {
                 {
                     case HubProtocolConstants.InvocationMessageType:
                     case HubProtocolConstants.InvocationMessageType:
                         {
                         {
+                            if (target is null)
+                            {
+                                throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
+                            }
+
                             if (hasArgumentsToken)
                             if (hasArgumentsToken)
                             {
                             {
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
@@ -327,11 +331,16 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
 
 
                             message = argumentBindingException != null
                             message = argumentBindingException != null
                                 ? new InvocationBindingFailureMessage(invocationId, target, argumentBindingException)
                                 ? new InvocationBindingFailureMessage(invocationId, target, argumentBindingException)
-                                : BindInvocationMessage(invocationId, target, arguments, hasArguments, streamIds, binder);
+                                : BindInvocationMessage(invocationId, target, arguments, hasArguments, streamIds);
                         }
                         }
                         break;
                         break;
                     case HubProtocolConstants.StreamInvocationMessageType:
                     case HubProtocolConstants.StreamInvocationMessageType:
                         {
                         {
+                            if (target is null)
+                            {
+                                throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
+                            }
+
                             if (hasArgumentsToken)
                             if (hasArgumentsToken)
                             {
                             {
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
@@ -348,10 +357,15 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
 
 
                             message = argumentBindingException != null
                             message = argumentBindingException != null
                                 ? new InvocationBindingFailureMessage(invocationId, target, argumentBindingException)
                                 ? new InvocationBindingFailureMessage(invocationId, target, argumentBindingException)
-                                : BindStreamInvocationMessage(invocationId, target, arguments, hasArguments, streamIds, binder);
+                                : BindStreamInvocationMessage(invocationId, target, arguments, hasArguments, streamIds);
                         }
                         }
                         break;
                         break;
                     case HubProtocolConstants.StreamItemMessageType:
                     case HubProtocolConstants.StreamItemMessageType:
+                        if (invocationId is null)
+                        {
+                            throw new InvalidDataException($"Missing required property '{InvocationIdPropertyName}'.");
+                        }
+
                         if (hasItemsToken)
                         if (hasItemsToken)
                         {
                         {
                             try
                             try
@@ -369,6 +383,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                         message = BindStreamItemMessage(invocationId, item, hasItem, binder);
                         message = BindStreamItemMessage(invocationId, item, hasItem, binder);
                         break;
                         break;
                     case HubProtocolConstants.CompletionMessageType:
                     case HubProtocolConstants.CompletionMessageType:
+                        if (invocationId is null)
+                        {
+                            throw new InvalidDataException($"Missing required property '{InvocationIdPropertyName}'.");
+                        }
+
                         if (hasResultToken)
                         if (hasResultToken)
                         {
                         {
                             var returnType = binder.GetReturnType(invocationId);
                             var returnType = binder.GetReturnType(invocationId);
@@ -413,7 +432,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 switch (reader.TokenType)
                 switch (reader.TokenType)
                 {
                 {
                     case JsonTokenType.PropertyName:
                     case JsonTokenType.PropertyName:
-                        var propertyName = reader.GetString();
+                        var propertyName = reader.GetString()!;
 
 
                         reader.CheckRead();
                         reader.CheckRead();
 
 
@@ -422,7 +441,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                             throw new InvalidDataException($"Expected header '{propertyName}' to be of type {JsonTokenType.String}.");
                             throw new InvalidDataException($"Expected header '{propertyName}' to be of type {JsonTokenType.String}.");
                         }
                         }
 
 
-                        headers[propertyName] = reader.GetString();
+                        headers[propertyName] = reader.GetString()!;
                         break;
                         break;
                     case JsonTokenType.Comment:
                     case JsonTokenType.Comment:
                         break;
                         break;
@@ -576,7 +595,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             }
             }
         }
         }
 
 
-        private void WriteArguments(object[] arguments, Utf8JsonWriter writer)
+        private void WriteArguments(object?[] arguments, Utf8JsonWriter writer)
         {
         {
             writer.WriteStartArray(ArgumentsPropertyNameBytes);
             writer.WriteStartArray(ArgumentsPropertyNameBytes);
             foreach (var argument in arguments)
             foreach (var argument in arguments)
@@ -593,7 +612,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             writer.WriteEndArray();
             writer.WriteEndArray();
         }
         }
 
 
-        private void WriteStreamIds(string[] streamIds, Utf8JsonWriter writer)
+        private void WriteStreamIds(string[]? streamIds, Utf8JsonWriter writer)
         {
         {
             if (streamIds == null)
             if (streamIds == null)
             {
             {
@@ -621,7 +640,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             writer.WriteNumber(TypePropertyNameBytes, type);
             writer.WriteNumber(TypePropertyNameBytes, type);
         }
         }
 
 
-        private HubMessage BindCancelInvocationMessage(string invocationId)
+        private HubMessage BindCancelInvocationMessage(string? invocationId)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -631,7 +650,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new CancelInvocationMessage(invocationId);
             return new CancelInvocationMessage(invocationId);
         }
         }
 
 
-        private HubMessage BindCompletionMessage(string invocationId, string error, object result, bool hasResult, IInvocationBinder binder)
+        private HubMessage BindCompletionMessage(string invocationId, string? error, object? result, bool hasResult, IInvocationBinder binder)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -651,7 +670,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new CompletionMessage(invocationId, error, result: null, hasResult: false);
             return new CompletionMessage(invocationId, error, result: null, hasResult: false);
         }
         }
 
 
-        private HubMessage BindStreamItemMessage(string invocationId, object item, bool hasItem, IInvocationBinder binder)
+        private HubMessage BindStreamItemMessage(string invocationId, object? item, bool hasItem, IInvocationBinder binder)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -666,7 +685,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new StreamItemMessage(invocationId, item);
             return new StreamItemMessage(invocationId, item);
         }
         }
 
 
-        private HubMessage BindStreamInvocationMessage(string invocationId, string target, object[] arguments, bool hasArguments, string[] streamIds, IInvocationBinder binder)
+        private HubMessage BindStreamInvocationMessage(string? invocationId, string target, object?[]? arguments, bool hasArguments, string[]? streamIds)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -683,10 +702,12 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
                 throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
             }
             }
 
 
+            Debug.Assert(arguments != null);
+
             return new StreamInvocationMessage(invocationId, target, arguments, streamIds);
             return new StreamInvocationMessage(invocationId, target, arguments, streamIds);
         }
         }
 
 
-        private HubMessage BindInvocationMessage(string invocationId, string target, object[] arguments, bool hasArguments, string[] streamIds, IInvocationBinder binder)
+        private HubMessage BindInvocationMessage(string? invocationId, string target, object?[]? arguments, bool hasArguments, string[]? streamIds)
         {
         {
             if (string.IsNullOrEmpty(target))
             if (string.IsNullOrEmpty(target))
             {
             {
@@ -698,17 +719,19 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 throw new InvalidDataException($"Missing required property '{ArgumentsPropertyName}'.");
                 throw new InvalidDataException($"Missing required property '{ArgumentsPropertyName}'.");
             }
             }
 
 
+            Debug.Assert(arguments != null);
+
             return new InvocationMessage(invocationId, target, arguments, streamIds);
             return new InvocationMessage(invocationId, target, arguments, streamIds);
         }
         }
 
 
-        private object BindType(ref Utf8JsonReader reader, Type type)
+        private object? BindType(ref Utf8JsonReader reader, Type type)
         {
         {
             return JsonSerializer.Deserialize(ref reader, type, _payloadSerializerOptions);
             return JsonSerializer.Deserialize(ref reader, type, _payloadSerializerOptions);
         }
         }
 
 
-        private object[] BindTypes(ref Utf8JsonReader reader, IReadOnlyList<Type> paramTypes)
+        private object?[] BindTypes(ref Utf8JsonReader reader, IReadOnlyList<Type> paramTypes)
         {
         {
-            object[] arguments = null;
+            object?[]? arguments = null;
             var paramIndex = 0;
             var paramIndex = 0;
             var paramCount = paramTypes.Count;
             var paramCount = paramTypes.Count;
 
 
@@ -719,7 +742,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             {
             {
                 if (paramIndex < paramCount)
                 if (paramIndex < paramCount)
                 {
                 {
-                    arguments ??= new object[paramCount];
+                    arguments ??= new object?[paramCount];
 
 
                     try
                     try
                     {
                     {
@@ -747,7 +770,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return arguments ?? Array.Empty<object>();
             return arguments ?? Array.Empty<object>();
         }
         }
 
 
-        private CloseMessage BindCloseMessage(string error, bool allowReconnect)
+        private CloseMessage BindCloseMessage(string? error, bool allowReconnect)
         {
         {
             // An empty string is still an error
             // An empty string is still an error
             if (error == null && !allowReconnect)
             if (error == null && !allowReconnect)
@@ -758,7 +781,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new CloseMessage(error, allowReconnect);
             return new CloseMessage(error, allowReconnect);
         }
         }
 
 
-        private HubMessage ApplyHeaders(HubMessage message, Dictionary<string, string> headers)
+        private HubMessage ApplyHeaders(HubMessage message, Dictionary<string, string>? headers)
         {
         {
             if (headers != null && message is HubInvocationMessage invocationMessage)
             if (headers != null && message is HubInvocationMessage invocationMessage)
             {
             {

+ 10 - 0
src/SignalR/common/Protocols.Json/src/PublicAPI.Unshipped.txt

@@ -1 +1,11 @@
 #nullable enable
 #nullable enable
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.JsonHubProtocol(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.JsonHubProtocolOptions> options) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.Name.get -> string
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) -> bool
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.WriteMessage(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message, System.Buffers.IBufferWriter<byte> output) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.GetMessageBytes(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) -> System.ReadOnlyMemory<byte>
+~Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.JsonHubProtocol(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.JsonHubProtocolOptions!>! options) -> void
+Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.Name.get -> string!
+Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder! binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage? message) -> bool
+Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.WriteMessage(Microsoft.AspNetCore.SignalR.Protocol.HubMessage! message, System.Buffers.IBufferWriter<byte>! output) -> void
+Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.GetMessageBytes(Microsoft.AspNetCore.SignalR.Protocol.HubMessage! message) -> System.ReadOnlyMemory<byte>

+ 4 - 5
src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocol.cs

@@ -1,11 +1,10 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using MessagePack;
 using MessagePack;
 using MessagePack.Formatters;
 using MessagePack.Formatters;
 using MessagePack.Resolvers;
 using MessagePack.Resolvers;
@@ -60,7 +59,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, out HubMessage message)
+        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, [NotNullWhen(true)] out HubMessage? message)
             => _worker.TryParseMessage(ref input, binder, out message);
             => _worker.TryParseMessage(ref input, binder, out message);
 
 
         /// <inheritdoc />
         /// <inheritdoc />
@@ -88,14 +87,14 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 ContractlessStandardResolver.Instance,
                 ContractlessStandardResolver.Instance,
             };
             };
 
 
-            public IMessagePackFormatter<T> GetFormatter<T>()
+            public IMessagePackFormatter<T>? GetFormatter<T>()
             {
             {
                 return Cache<T>.Formatter;
                 return Cache<T>.Formatter;
             }
             }
 
 
             private static class Cache<T>
             private static class Cache<T>
             {
             {
-                public static readonly IMessagePackFormatter<T> Formatter;
+                public static readonly IMessagePackFormatter<T>? Formatter;
 
 
                 static Cache()
                 static Cache()
                 {
                 {

+ 3 - 2
src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocolWorker.cs

@@ -5,6 +5,7 @@ using System;
 using System.Buffers;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.IO;
 using System.Runtime.ExceptionServices;
 using System.Runtime.ExceptionServices;
 using MessagePack;
 using MessagePack;
@@ -21,7 +22,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         private const int VoidResult = 2;
         private const int VoidResult = 2;
         private const int NonVoidResult = 3;
         private const int NonVoidResult = 3;
 
 
-        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, out HubMessage? message)
+        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, [NotNullWhen(true)] out HubMessage? message)
         {
         {
             if (!BinaryMessageParser.TryParseMessage(ref input, out var payload))
             if (!BinaryMessageParser.TryParseMessage(ref input, out var payload))
             {
             {
@@ -31,7 +32,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
 
 
             var reader = new MessagePackReader(payload);
             var reader = new MessagePackReader(payload);
             message = ParseMessage(ref reader, binder);
             message = ParseMessage(ref reader, binder);
-            return true;
+            return message != null;
         }
         }
 
 
         private HubMessage? ParseMessage(ref MessagePackReader reader, IInvocationBinder binder)
         private HubMessage? ParseMessage(ref MessagePackReader reader, IInvocationBinder binder)

+ 10 - 0
src/SignalR/common/Protocols.MessagePack/src/PublicAPI.Unshipped.txt

@@ -1 +1,11 @@
 #nullable enable
 #nullable enable
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.Name.get -> string
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.MessagePackHubProtocol(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.MessagePackHubProtocolOptions> options) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) -> bool
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.WriteMessage(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message, System.Buffers.IBufferWriter<byte> output) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.GetMessageBytes(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) -> System.ReadOnlyMemory<byte>
+Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.Name.get -> string!
+~Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.MessagePackHubProtocol(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.MessagePackHubProtocolOptions!>! options) -> void
+Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder! binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage? message) -> bool
+Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.WriteMessage(Microsoft.AspNetCore.SignalR.Protocol.HubMessage! message, System.Buffers.IBufferWriter<byte>! output) -> void
+Microsoft.AspNetCore.SignalR.Protocol.MessagePackHubProtocol.GetMessageBytes(Microsoft.AspNetCore.SignalR.Protocol.HubMessage! message) -> System.ReadOnlyMemory<byte>

+ 61 - 36
src/SignalR/common/Protocols.NewtonsoftJson/src/Protocol/NewtonsoftJsonHubProtocol.cs

@@ -1,11 +1,11 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.IO;
 using System.Runtime.ExceptionServices;
 using System.Runtime.ExceptionServices;
 using Microsoft.AspNetCore.Connections;
 using Microsoft.AspNetCore.Connections;
@@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, out HubMessage message)
+        public bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, [NotNullWhen(true)] out HubMessage? message)
         {
         {
             if (!TextMessageParser.TryParseMessage(ref input, out var payload))
             if (!TextMessageParser.TryParseMessage(ref input, out var payload))
             {
             {
@@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return HubProtocolExtensions.GetMessageBytes(this, message);
             return HubProtocolExtensions.GetMessageBytes(this, message);
         }
         }
 
 
-        private HubMessage ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
+        private HubMessage? ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
         {
         {
             try
             try
             {
             {
@@ -118,21 +118,21 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 // if we're lucky and the state we need to directly parse is available, then we'll use it.
                 // if we're lucky and the state we need to directly parse is available, then we'll use it.
 
 
                 int? type = null;
                 int? type = null;
-                string invocationId = null;
-                string target = null;
-                string error = null;
+                string? invocationId = null;
+                string? target = null;
+                string? error = null;
                 var hasItem = false;
                 var hasItem = false;
-                object item = null;
-                JToken itemToken = null;
+                object? item = null;
+                JToken? itemToken = null;
                 var hasResult = false;
                 var hasResult = false;
-                object result = null;
-                JToken resultToken = null;
+                object? result = null;
+                JToken? resultToken = null;
                 var hasArguments = false;
                 var hasArguments = false;
-                object[] arguments = null;
-                string[] streamIds = null;
-                JArray argumentsToken = null;
-                ExceptionDispatchInfo argumentBindingException = null;
-                Dictionary<string, string> headers = null;
+                object?[]? arguments = null;
+                string[]? streamIds = null;
+                JArray? argumentsToken = null;
+                ExceptionDispatchInfo? argumentBindingException = null;
+                Dictionary<string, string>? headers = null;
                 var completed = false;
                 var completed = false;
                 var allowReconnect = false;
                 var allowReconnect = false;
 
 
@@ -179,7 +179,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                                         reader.Read();
                                         reader.Read();
                                         while (reader.TokenType != JsonToken.EndArray)
                                         while (reader.TokenType != JsonToken.EndArray)
                                         {
                                         {
-                                            newStreamIds.Add(reader.Value?.ToString());
+                                            newStreamIds.Add(reader.Value?.ToString() ?? throw new InvalidDataException($"Null value for '{StreamIdsPropertyName}' is not valid."));
                                             reader.Read();
                                             reader.Read();
                                         }
                                         }
 
 
@@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                                         hasItem = true;
                                         hasItem = true;
 
 
 
 
-                                        string id = null;
+                                        string? id = null;
                                         if (!string.IsNullOrEmpty(invocationId))
                                         if (!string.IsNullOrEmpty(invocationId))
                                         {
                                         {
                                             id = invocationId;
                                             id = invocationId;
@@ -308,6 +308,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 {
                 {
                     case HubProtocolConstants.InvocationMessageType:
                     case HubProtocolConstants.InvocationMessageType:
                         {
                         {
+                            if (target is null)
+                            {
+                                throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
+                            }
+
                             if (argumentsToken != null)
                             if (argumentsToken != null)
                             {
                             {
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
@@ -329,6 +334,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                         break;
                         break;
                     case HubProtocolConstants.StreamInvocationMessageType:
                     case HubProtocolConstants.StreamInvocationMessageType:
                         {
                         {
+                            if (target is null)
+                            {
+                                throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
+                            }
+
                             if (argumentsToken != null)
                             if (argumentsToken != null)
                             {
                             {
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
                                 // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
@@ -349,6 +359,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                         }
                         }
                         break;
                         break;
                     case HubProtocolConstants.StreamItemMessageType:
                     case HubProtocolConstants.StreamItemMessageType:
+                        if (invocationId is null)
+                        {
+                            throw new InvalidDataException($"Missing required property '{InvocationIdPropertyName}'.");
+                        }
+
                         if (itemToken != null)
                         if (itemToken != null)
                         {
                         {
                             try
                             try
@@ -366,6 +381,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                         message = BindStreamItemMessage(invocationId, item, hasItem, binder);
                         message = BindStreamItemMessage(invocationId, item, hasItem, binder);
                         break;
                         break;
                     case HubProtocolConstants.CompletionMessageType:
                     case HubProtocolConstants.CompletionMessageType:
+                        if (invocationId is null)
+                        {
+                            throw new InvalidDataException($"Missing required property '{InvocationIdPropertyName}'.");
+                        }
+
                         if (resultToken != null)
                         if (resultToken != null)
                         {
                         {
                             var returnType = binder.GetReturnType(invocationId);
                             var returnType = binder.GetReturnType(invocationId);
@@ -410,7 +430,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 switch (reader.TokenType)
                 switch (reader.TokenType)
                 {
                 {
                     case JsonToken.PropertyName:
                     case JsonToken.PropertyName:
-                        var propertyName = reader.Value.ToString();
+                        var propertyName = reader.Value.ToString()!;
 
 
                         JsonUtils.CheckRead(reader);
                         JsonUtils.CheckRead(reader);
 
 
@@ -419,7 +439,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                             throw new InvalidDataException($"Expected header '{propertyName}' to be of type {JTokenType.String}.");
                             throw new InvalidDataException($"Expected header '{propertyName}' to be of type {JTokenType.String}.");
                         }
                         }
 
 
-                        headers[propertyName] = reader.Value?.ToString();
+                        headers[propertyName] = reader.Value.ToString()!;
                         break;
                         break;
                     case JsonToken.Comment:
                     case JsonToken.Comment:
                         break;
                         break;
@@ -565,10 +585,11 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             }
             }
         }
         }
 
 
-        private void WriteArguments(object[] arguments, JsonTextWriter writer)
+        private void WriteArguments(object?[] arguments, JsonTextWriter writer)
         {
         {
             writer.WritePropertyName(ArgumentsPropertyName);
             writer.WritePropertyName(ArgumentsPropertyName);
             writer.WriteStartArray();
             writer.WriteStartArray();
+
             foreach (var argument in arguments)
             foreach (var argument in arguments)
             {
             {
                 PayloadSerializer.Serialize(writer, argument);
                 PayloadSerializer.Serialize(writer, argument);
@@ -576,7 +597,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             writer.WriteEndArray();
             writer.WriteEndArray();
         }
         }
 
 
-        private void WriteStreamIds(string[] streamIds, JsonTextWriter writer)
+        private void WriteStreamIds(string[]? streamIds, JsonTextWriter writer)
         {
         {
             if (streamIds == null)
             if (streamIds == null)
             {
             {
@@ -607,7 +628,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             writer.WriteValue(type);
             writer.WriteValue(type);
         }
         }
 
 
-        private HubMessage BindCancelInvocationMessage(string invocationId)
+        private HubMessage BindCancelInvocationMessage(string? invocationId)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -617,7 +638,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new CancelInvocationMessage(invocationId);
             return new CancelInvocationMessage(invocationId);
         }
         }
 
 
-        private HubMessage BindCompletionMessage(string invocationId, string error, object result, bool hasResult, IInvocationBinder binder)
+        private HubMessage BindCompletionMessage(string invocationId, string? error, object? result, bool hasResult, IInvocationBinder binder)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -637,7 +658,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new CompletionMessage(invocationId, error, result: null, hasResult: false);
             return new CompletionMessage(invocationId, error, result: null, hasResult: false);
         }
         }
 
 
-        private HubMessage BindStreamItemMessage(string invocationId, object item, bool hasItem, IInvocationBinder binder)
+        private HubMessage BindStreamItemMessage(string invocationId, object? item, bool hasItem, IInvocationBinder binder)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -652,7 +673,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new StreamItemMessage(invocationId, item);
             return new StreamItemMessage(invocationId, item);
         }
         }
 
 
-        private HubMessage BindStreamInvocationMessage(string invocationId, string target, object[] arguments, bool hasArguments, string[] streamIds, IInvocationBinder binder)
+        private HubMessage BindStreamInvocationMessage(string? invocationId, string target, object?[]? arguments, bool hasArguments, string[]? streamIds, IInvocationBinder binder)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
             {
             {
@@ -669,10 +690,12 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
                 throw new InvalidDataException($"Missing required property '{TargetPropertyName}'.");
             }
             }
 
 
+            Debug.Assert(arguments != null);
+
             return new StreamInvocationMessage(invocationId, target, arguments, streamIds);
             return new StreamInvocationMessage(invocationId, target, arguments, streamIds);
         }
         }
 
 
-        private HubMessage BindInvocationMessage(string invocationId, string target, object[] arguments, bool hasArguments, string[] streamIds, IInvocationBinder binder)
+        private HubMessage BindInvocationMessage(string? invocationId, string target, object?[]? arguments, bool hasArguments, string[]? streamIds, IInvocationBinder binder)
         {
         {
             if (string.IsNullOrEmpty(target))
             if (string.IsNullOrEmpty(target))
             {
             {
@@ -684,6 +707,8 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                 throw new InvalidDataException($"Missing required property '{ArgumentsPropertyName}'.");
                 throw new InvalidDataException($"Missing required property '{ArgumentsPropertyName}'.");
             }
             }
 
 
+            Debug.Assert(arguments != null);
+
             return new InvocationMessage(invocationId, target, arguments, streamIds);
             return new InvocationMessage(invocationId, target, arguments, streamIds);
         }
         }
 
 
@@ -699,9 +724,9 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return reader.Read();
             return reader.Read();
         }
         }
 
 
-        private object[] BindArguments(JsonTextReader reader, IReadOnlyList<Type> paramTypes)
+        private object?[] BindArguments(JsonTextReader reader, IReadOnlyList<Type> paramTypes)
         {
         {
-            object[] arguments = null;
+            object?[]? arguments = null;
             var paramIndex = 0;
             var paramIndex = 0;
             var argumentsCount = 0;
             var argumentsCount = 0;
             var paramCount = paramTypes.Count;
             var paramCount = paramTypes.Count;
@@ -715,12 +740,12 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
                         throw new InvalidDataException($"Invocation provides {argumentsCount} argument(s) but target expects {paramCount}.");
                         throw new InvalidDataException($"Invocation provides {argumentsCount} argument(s) but target expects {paramCount}.");
                     }
                     }
 
 
-                    return arguments ?? Array.Empty<object>();
+                    return arguments ?? Array.Empty<object?>();
                 }
                 }
 
 
                 if (arguments == null)
                 if (arguments == null)
                 {
                 {
-                    arguments = new object[paramCount];
+                    arguments = new object?[paramCount];
                 }
                 }
 
 
                 try
                 try
@@ -746,7 +771,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             throw new JsonReaderException("Unexpected end when reading JSON");
             throw new JsonReaderException("Unexpected end when reading JSON");
         }
         }
 
 
-        private CloseMessage BindCloseMessage(string error, bool allowReconnect)
+        private CloseMessage BindCloseMessage(string? error, bool allowReconnect)
         {
         {
             // An empty string is still an error
             // An empty string is still an error
             if (error == null && !allowReconnect)
             if (error == null && !allowReconnect)
@@ -757,7 +782,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             return new CloseMessage(error, allowReconnect);
             return new CloseMessage(error, allowReconnect);
         }
         }
 
 
-        private object[] BindArguments(JArray args, IReadOnlyList<Type> paramTypes)
+        private object?[] BindArguments(JArray args, IReadOnlyList<Type> paramTypes)
         {
         {
             var paramCount = paramTypes.Count;
             var paramCount = paramTypes.Count;
             var argCount = args.Count;
             var argCount = args.Count;
@@ -768,10 +793,10 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
 
 
             if (paramCount == 0)
             if (paramCount == 0)
             {
             {
-                return Array.Empty<object>();
+                return Array.Empty<object?>();
             }
             }
 
 
-            var arguments = new object[argCount];
+            var arguments = new object?[argCount];
 
 
             try
             try
             {
             {
@@ -789,7 +814,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
             }
             }
         }
         }
 
 
-        private HubMessage ApplyHeaders(HubMessage message, Dictionary<string, string> headers)
+        private HubMessage ApplyHeaders(HubMessage message, Dictionary<string, string>? headers)
         {
         {
             if (headers != null && message is HubInvocationMessage invocationMessage)
             if (headers != null && message is HubInvocationMessage invocationMessage)
             {
             {

+ 12 - 0
src/SignalR/common/Protocols.NewtonsoftJson/src/PublicAPI.Unshipped.txt

@@ -1 +1,13 @@
 #nullable enable
 #nullable enable
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.Name.get -> string
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.NewtonsoftJsonHubProtocol(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.NewtonsoftJsonHubProtocolOptions> options) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.PayloadSerializer.get -> Newtonsoft.Json.JsonSerializer
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) -> bool
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.WriteMessage(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message, System.Buffers.IBufferWriter<byte> output) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.GetMessageBytes(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) -> System.ReadOnlyMemory<byte>
+Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.Name.get -> string!
+~Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.NewtonsoftJsonHubProtocol(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.NewtonsoftJsonHubProtocolOptions!>! options) -> void
+Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.PayloadSerializer.get -> Newtonsoft.Json.JsonSerializer!
+Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder! binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage? message) -> bool
+Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.WriteMessage(Microsoft.AspNetCore.SignalR.Protocol.HubMessage! message, System.Buffers.IBufferWriter<byte>! output) -> void
+Microsoft.AspNetCore.SignalR.Protocol.NewtonsoftJsonHubProtocol.GetMessageBytes(Microsoft.AspNetCore.SignalR.Protocol.HubMessage! message) -> System.ReadOnlyMemory<byte>

+ 9 - 11
src/SignalR/common/Shared/AsyncEnumerableAdapters.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
@@ -15,7 +13,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
     // True-internal because this is a weird and tricky class to use :)
     // True-internal because this is a weird and tricky class to use :)
     internal static class AsyncEnumerableAdapters
     internal static class AsyncEnumerableAdapters
     {
     {
-        public static IAsyncEnumerable<object> MakeCancelableAsyncEnumerable<T>(IAsyncEnumerable<T> asyncEnumerable, CancellationToken cancellationToken = default)
+        public static IAsyncEnumerable<object?> MakeCancelableAsyncEnumerable<T>(IAsyncEnumerable<T> asyncEnumerable, CancellationToken cancellationToken = default)
         {
         {
             return new CancelableAsyncEnumerable<T>(asyncEnumerable, cancellationToken);
             return new CancelableAsyncEnumerable<T>(asyncEnumerable, cancellationToken);
         }
         }
@@ -26,7 +24,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
         }
         }
 
 
 #if NETCOREAPP
 #if NETCOREAPP
-        public static async IAsyncEnumerable<object> MakeAsyncEnumerableFromChannel<T>(ChannelReader<T> channel, [EnumeratorCancellation] CancellationToken cancellationToken = default)
+        public static async IAsyncEnumerable<object?> MakeAsyncEnumerableFromChannel<T>(ChannelReader<T> channel, [EnumeratorCancellation] CancellationToken cancellationToken = default)
         {
         {
             await foreach (var item in channel.ReadAllAsync(cancellationToken))
             await foreach (var item in channel.ReadAllAsync(cancellationToken))
             {
             {
@@ -36,7 +34,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 #else
 #else
         // System.Threading.Channels.ReadAllAsync() is not available on netstandard2.0 and netstandard2.1
         // System.Threading.Channels.ReadAllAsync() is not available on netstandard2.0 and netstandard2.1
         // But this is the exact same code that it uses
         // But this is the exact same code that it uses
-        public static async IAsyncEnumerable<object> MakeAsyncEnumerableFromChannel<T>(ChannelReader<T> channel, [EnumeratorCancellation] CancellationToken cancellationToken = default)
+        public static async IAsyncEnumerable<object?> MakeAsyncEnumerableFromChannel<T>(ChannelReader<T> channel, [EnumeratorCancellation] CancellationToken cancellationToken = default)
         {
         {
             while (await channel.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
             while (await channel.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
             {
             {
@@ -66,7 +64,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                 {
                 {
                     var registration = cancellationToken.Register((ctsState) =>
                     var registration = cancellationToken.Register((ctsState) =>
                     {
                     {
-                        ((CancellationTokenSource)ctsState).Cancel();
+                        ((CancellationTokenSource)ctsState!).Cancel();
                     }, _cts);
                     }, _cts);
 
 
                     return new CancelableEnumerator<TResult>(enumerator, registration);
                     return new CancelableEnumerator<TResult>(enumerator, registration);
@@ -102,7 +100,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
         }
         }
 
 
         /// <summary>Converts an IAsyncEnumerable of T to an IAsyncEnumerable of object.</summary>
         /// <summary>Converts an IAsyncEnumerable of T to an IAsyncEnumerable of object.</summary>
-        private class CancelableAsyncEnumerable<T> : IAsyncEnumerable<object>
+        private class CancelableAsyncEnumerable<T> : IAsyncEnumerable<object?>
         {
         {
             private readonly IAsyncEnumerable<T> _asyncEnumerable;
             private readonly IAsyncEnumerable<T> _asyncEnumerable;
             private readonly CancellationToken _cancellationToken;
             private readonly CancellationToken _cancellationToken;
@@ -113,17 +111,17 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                 _cancellationToken = cancellationToken;
                 _cancellationToken = cancellationToken;
             }
             }
 
 
-            public IAsyncEnumerator<object> GetAsyncEnumerator(CancellationToken cancellationToken = default)
+            public IAsyncEnumerator<object?> GetAsyncEnumerator(CancellationToken cancellationToken = default)
             {
             {
                 // Assume that this will be iterated through with await foreach which always passes a default token.
                 // Assume that this will be iterated through with await foreach which always passes a default token.
                 // Instead use the token from the ctor.
                 // Instead use the token from the ctor.
                 Debug.Assert(cancellationToken == default);
                 Debug.Assert(cancellationToken == default);
 
 
                 var enumeratorOfT = _asyncEnumerable.GetAsyncEnumerator(_cancellationToken);
                 var enumeratorOfT = _asyncEnumerable.GetAsyncEnumerator(_cancellationToken);
-                return enumeratorOfT as IAsyncEnumerator<object> ?? new BoxedAsyncEnumerator(enumeratorOfT);
+                return enumeratorOfT as IAsyncEnumerator<object?> ?? new BoxedAsyncEnumerator(enumeratorOfT);
             }
             }
 
 
-            private class BoxedAsyncEnumerator : IAsyncEnumerator<object>
+            private class BoxedAsyncEnumerator : IAsyncEnumerator<object?>
             {
             {
                 private IAsyncEnumerator<T> _asyncEnumerator;
                 private IAsyncEnumerator<T> _asyncEnumerator;
 
 
@@ -132,7 +130,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                     _asyncEnumerator = asyncEnumerator;
                     _asyncEnumerator = asyncEnumerator;
                 }
                 }
 
 
-                public object Current => _asyncEnumerator.Current;
+                public object? Current => _asyncEnumerator.Current;
 
 
                 public ValueTask<bool> MoveNextAsync()
                 public ValueTask<bool> MoveNextAsync()
                 {
                 {

+ 14 - 6
src/SignalR/common/Shared/MemoryBufferWriter.cs

@@ -1,12 +1,13 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
+#nullable enable
 
 
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.IO;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
@@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Internal
     internal sealed class MemoryBufferWriter : Stream, IBufferWriter<byte>
     internal sealed class MemoryBufferWriter : Stream, IBufferWriter<byte>
     {
     {
         [ThreadStatic]
         [ThreadStatic]
-        private static MemoryBufferWriter _cachedInstance;
+        private static MemoryBufferWriter? _cachedInstance;
 
 
 #if DEBUG
 #if DEBUG
         private bool _inUse;
         private bool _inUse;
@@ -25,8 +26,8 @@ namespace Microsoft.AspNetCore.Internal
         private readonly int _minimumSegmentSize;
         private readonly int _minimumSegmentSize;
         private int _bytesWritten;
         private int _bytesWritten;
 
 
-        private List<CompletedBuffer> _completedSegments;
-        private byte[] _currentSegment;
+        private List<CompletedBuffer>? _completedSegments;
+        private byte[]? _currentSegment;
         private int _position;
         private int _position;
 
 
         public MemoryBufferWriter(int minimumSegmentSize = 4096)
         public MemoryBufferWriter(int minimumSegmentSize = 4096)
@@ -136,7 +137,7 @@ namespace Microsoft.AspNetCore.Internal
 
 
         public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
         public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
         {
         {
-            if (_completedSegments == null)
+            if (_completedSegments == null && _currentSegment is not null)
             {
             {
                 // There is only one segment so write without awaiting.
                 // There is only one segment so write without awaiting.
                 return destination.WriteAsync(_currentSegment, 0, _position);
                 return destination.WriteAsync(_currentSegment, 0, _position);
@@ -145,6 +146,7 @@ namespace Microsoft.AspNetCore.Internal
             return CopyToSlowAsync(destination);
             return CopyToSlowAsync(destination);
         }
         }
 
 
+        [MemberNotNull(nameof(_currentSegment))]
         private void EnsureCapacity(int sizeHint)
         private void EnsureCapacity(int sizeHint)
         {
         {
             // This does the Right Thing. It only subtracts _position from the current segment length if it's non-null.
             // This does the Right Thing. It only subtracts _position from the current segment length if it's non-null.
@@ -156,12 +158,15 @@ namespace Microsoft.AspNetCore.Internal
             if ((sizeHint == 0 && remainingSize > 0) || (sizeHint > 0 && remainingSize >= sizeHint))
             if ((sizeHint == 0 && remainingSize > 0) || (sizeHint > 0 && remainingSize >= sizeHint))
             {
             {
                 // We have capacity in the current segment
                 // We have capacity in the current segment
+#pragma warning disable CS8774 // Member must have a non-null value when exiting.
                 return;
                 return;
+#pragma warning restore CS8774 // Member must have a non-null value when exiting.
             }
             }
 
 
             AddSegment(sizeHint);
             AddSegment(sizeHint);
         }
         }
 
 
+        [MemberNotNull(nameof(_currentSegment))]
         private void AddSegment(int sizeHint = 0)
         private void AddSegment(int sizeHint = 0)
         {
         {
             if (_currentSegment != null)
             if (_currentSegment != null)
@@ -196,7 +201,10 @@ namespace Microsoft.AspNetCore.Internal
                 }
                 }
             }
             }
 
 
-            await destination.WriteAsync(_currentSegment, 0, _position);
+            if (_currentSegment is not null)
+            {
+                await destination.WriteAsync(_currentSegment, 0, _position);
+            }
         }
         }
 
 
         public byte[] ToArray()
         public byte[] ToArray()

+ 0 - 2
src/SignalR/common/Shared/PipeWriterStream.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System.Buffers;
 using System.Buffers;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;

+ 6 - 5
src/SignalR/common/Shared/ReflectionHelper.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
@@ -22,15 +20,18 @@ namespace Microsoft.AspNetCore.SignalR
             {
             {
                 return true;
                 return true;
             }
             }
+
+            Type? nullableType = type;
+
             do
             do
             {
             {
-                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ChannelReader<>))
+                if (nullableType.IsGenericType && nullableType.GetGenericTypeDefinition() == typeof(ChannelReader<>))
                 {
                 {
                     return true;
                     return true;
                 }
                 }
 
 
-                type = type.BaseType;
-            } while (mustBeDirectType == false && type != null);
+                nullableType = nullableType.BaseType;
+            } while (mustBeDirectType == false && nullableType != null);
 
 
             return false;
             return false;
         }
         }

+ 1 - 3
src/SignalR/common/Shared/ReusableUtf8JsonWriter.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Text.Encodings.Web;
 using System.Text.Encodings.Web;
@@ -13,7 +11,7 @@ namespace Microsoft.AspNetCore.Internal
     internal sealed class ReusableUtf8JsonWriter
     internal sealed class ReusableUtf8JsonWriter
     {
     {
         [ThreadStatic]
         [ThreadStatic]
-        private static ReusableUtf8JsonWriter _cachedInstance;
+        private static ReusableUtf8JsonWriter? _cachedInstance;
 
 
         private readonly Utf8JsonWriter _writer;
         private readonly Utf8JsonWriter _writer;
 
 

+ 2 - 4
src/SignalR/common/Shared/SystemTextJsonExtensions.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable enable
-
 using System.IO;
 using System.IO;
 using System.Text.Json;
 using System.Text.Json;
 
 
@@ -71,7 +69,7 @@ namespace Microsoft.AspNetCore.Internal
             };
             };
         }
         }
 
 
-        public static string? ReadAsString(this ref Utf8JsonReader reader, string propertyName)
+        public static string ReadAsString(this ref Utf8JsonReader reader, string propertyName)
         {
         {
             reader.Read();
             reader.Read();
 
 
@@ -80,7 +78,7 @@ namespace Microsoft.AspNetCore.Internal
                 throw new InvalidDataException($"Expected '{propertyName}' to be of type {JsonTokenType.String}.");
                 throw new InvalidDataException($"Expected '{propertyName}' to be of type {JsonTokenType.String}.");
             }
             }
 
 
-            return reader.GetString();
+            return reader.GetString()!;
         }
         }
 
 
         public static int? ReadAsInt32(this ref Utf8JsonReader reader, string propertyName)
         public static int? ReadAsInt32(this ref Utf8JsonReader reader, string propertyName)

+ 0 - 2
src/SignalR/common/Shared/TimerAwaitable.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable enable
-
 using System;
 using System;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Threading;

+ 1 - 3
src/SignalR/common/Shared/Utf8BufferTextReader.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.IO;
 using System.IO;
@@ -17,7 +15,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
         private ReadOnlySequence<byte> _utf8Buffer;
         private ReadOnlySequence<byte> _utf8Buffer;
 
 
         [ThreadStatic]
         [ThreadStatic]
-        private static Utf8BufferTextReader _cachedInstance;
+        private static Utf8BufferTextReader? _cachedInstance;
 
 
 #if DEBUG
 #if DEBUG
         private bool _inUse;
         private bool _inUse;

+ 15 - 11
src/SignalR/common/Shared/Utf8BufferTextWriter.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Buffers;
 using System.Buffers;
 using System.Diagnostics;
 using System.Diagnostics;
@@ -19,10 +17,10 @@ namespace Microsoft.AspNetCore.Internal
         private static readonly int MaximumBytesPerUtf8Char = 4;
         private static readonly int MaximumBytesPerUtf8Char = 4;
 
 
         [ThreadStatic]
         [ThreadStatic]
-        private static Utf8BufferTextWriter _cachedInstance;
+        private static Utf8BufferTextWriter? _cachedInstance;
 
 
         private readonly Encoder _encoder;
         private readonly Encoder _encoder;
-        private IBufferWriter<byte> _bufferWriter;
+        private IBufferWriter<byte>? _bufferWriter;
         private Memory<byte> _memory;
         private Memory<byte> _memory;
         private int _memoryUsed;
         private int _memoryUsed;
 
 
@@ -83,9 +81,12 @@ namespace Microsoft.AspNetCore.Internal
             WriteInternal(buffer.AsSpan(index, count));
             WriteInternal(buffer.AsSpan(index, count));
         }
         }
 
 
-        public override void Write(char[] buffer)
+        public override void Write(char[]? buffer)
         {
         {
-            WriteInternal(buffer);
+            if (buffer is not null)
+            {
+                WriteInternal(buffer);
+            }
         }
         }
 
 
         public override void Write(char value)
         public override void Write(char value)
@@ -127,9 +128,12 @@ namespace Microsoft.AspNetCore.Internal
             _memoryUsed += bytesUsed;
             _memoryUsed += bytesUsed;
         }
         }
 
 
-        public override void Write(string value)
+        public override void Write(string? value)
         {
         {
-            WriteInternal(value.AsSpan());
+            if (value is not null)
+            {
+                WriteInternal(value.AsSpan());
+            }
         }
         }
 
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -152,10 +156,10 @@ namespace Microsoft.AspNetCore.Internal
                 // Used up the memory from the buffer writer so advance and get more
                 // Used up the memory from the buffer writer so advance and get more
                 if (_memoryUsed > 0)
                 if (_memoryUsed > 0)
                 {
                 {
-                    _bufferWriter.Advance(_memoryUsed);
+                    _bufferWriter!.Advance(_memoryUsed);
                 }
                 }
 
 
-                _memory = _bufferWriter.GetMemory(MaximumBytesPerUtf8Char);
+                _memory = _bufferWriter!.GetMemory(MaximumBytesPerUtf8Char);
                 _memoryUsed = 0;
                 _memoryUsed = 0;
             }
             }
         }
         }
@@ -191,7 +195,7 @@ namespace Microsoft.AspNetCore.Internal
         {
         {
             if (_memoryUsed > 0)
             if (_memoryUsed > 0)
             {
             {
-                _bufferWriter.Advance(_memoryUsed);
+                _bufferWriter!.Advance(_memoryUsed);
                 _memory = _memory.Slice(_memoryUsed, _memory.Length - _memoryUsed);
                 _memory = _memory.Slice(_memoryUsed, _memory.Length - _memoryUsed);
                 _memoryUsed = 0;
                 _memoryUsed = 0;
             }
             }

+ 2 - 2
src/SignalR/common/SignalR.Common/src/Protocol/CompletionMessage.cs

@@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="invocationId">The ID of the invocation that is being completed.</param>
         /// <param name="invocationId">The ID of the invocation that is being completed.</param>
         /// <param name="error">The error that occurred during the invocation.</param>
         /// <param name="error">The error that occurred during the invocation.</param>
         /// <returns>The constructed <see cref="CompletionMessage"/>.</returns>
         /// <returns>The constructed <see cref="CompletionMessage"/>.</returns>
-        public static CompletionMessage WithError(string invocationId, string error)
+        public static CompletionMessage WithError(string invocationId, string? error)
             => new CompletionMessage(invocationId, error, result: null, hasResult: false);
             => new CompletionMessage(invocationId, error, result: null, hasResult: false);
 
 
         /// <summary>
         /// <summary>
@@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="invocationId">The ID of the invocation that is being completed.</param>
         /// <param name="invocationId">The ID of the invocation that is being completed.</param>
         /// <param name="payload">The result from the invocation.</param>
         /// <param name="payload">The result from the invocation.</param>
         /// <returns>The constructed <see cref="CompletionMessage"/>.</returns>
         /// <returns>The constructed <see cref="CompletionMessage"/>.</returns>
-        public static CompletionMessage WithResult(string invocationId, object payload)
+        public static CompletionMessage WithResult(string invocationId, object? payload)
             => new CompletionMessage(invocationId, error: null, result: payload, hasResult: true);
             => new CompletionMessage(invocationId, error: null, result: payload, hasResult: true);
 
 
         /// <summary>
         /// <summary>

+ 8 - 8
src/SignalR/common/SignalR.Common/src/Protocol/HubMethodInvocationMessage.cs

@@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <summary>
         /// <summary>
         /// Gets the target method arguments.
         /// Gets the target method arguments.
         /// </summary>
         /// </summary>
-        public object?[]? Arguments { get; }
+        public object?[] Arguments { get; }
 
 
         /// <summary>
         /// <summary>
         /// The target methods stream IDs.
         /// The target methods stream IDs.
@@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="target">The target method name.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="streamIds">The target methods stream IDs.</param>
         /// <param name="streamIds">The target methods stream IDs.</param>
-        protected HubMethodInvocationMessage(string? invocationId, string target, object?[]? arguments, string[]? streamIds)
+        protected HubMethodInvocationMessage(string? invocationId, string target, object?[] arguments, string[]? streamIds)
             : this(invocationId, target, arguments)
             : this(invocationId, target, arguments)
         {
         {
             StreamIds = streamIds;
             StreamIds = streamIds;
@@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="invocationId">The invocation ID.</param>
         /// <param name="invocationId">The invocation ID.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="arguments">The target method arguments.</param>
-        protected HubMethodInvocationMessage(string? invocationId, string target, object?[]? arguments)
+        protected HubMethodInvocationMessage(string? invocationId, string target, object?[] arguments)
             : base(invocationId)
             : base(invocationId)
         {
         {
             if (string.IsNullOrEmpty(target))
             if (string.IsNullOrEmpty(target))
@@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// </summary>
         /// </summary>
         /// <param name="target">The target method name.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="arguments">The target method arguments.</param>
-        public InvocationMessage(string target, object?[]? arguments)
+        public InvocationMessage(string target, object?[] arguments)
             : this(null, target, arguments)
             : this(null, target, arguments)
         {
         {
         }
         }
@@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="invocationId">The invocation ID.</param>
         /// <param name="invocationId">The invocation ID.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="arguments">The target method arguments.</param>
-        public InvocationMessage(string? invocationId, string target, object?[]? arguments)
+        public InvocationMessage(string? invocationId, string target, object?[] arguments)
             : base(invocationId, target, arguments)
             : base(invocationId, target, arguments)
         {
         {
         }
         }
@@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="target">The target method name.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="streamIds">The target methods stream IDs.</param>
         /// <param name="streamIds">The target methods stream IDs.</param>
-        public InvocationMessage(string? invocationId, string target, object?[]? arguments, string[]? streamIds)
+        public InvocationMessage(string? invocationId, string target, object?[] arguments, string[]? streamIds)
             : base(invocationId, target, arguments, streamIds)
             : base(invocationId, target, arguments, streamIds)
         {
         {
         }
         }
@@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="invocationId">The invocation ID.</param>
         /// <param name="invocationId">The invocation ID.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="arguments">The target method arguments.</param>
-        public StreamInvocationMessage(string invocationId, string target, object[] arguments)
+        public StreamInvocationMessage(string invocationId, string target, object?[] arguments)
             : base(invocationId, target, arguments)
             : base(invocationId, target, arguments)
         {
         {
         }
         }
@@ -146,7 +146,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="target">The target method name.</param>
         /// <param name="target">The target method name.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="arguments">The target method arguments.</param>
         /// <param name="streamIds">The target methods stream IDs.</param>
         /// <param name="streamIds">The target methods stream IDs.</param>
-        public StreamInvocationMessage(string invocationId, string target, object[] arguments, string[]? streamIds)
+        public StreamInvocationMessage(string invocationId, string target, object?[] arguments, string[]? streamIds)
             : base(invocationId, target, arguments, streamIds)
             : base(invocationId, target, arguments, streamIds)
         {
         {
         }
         }

+ 1 - 1
src/SignalR/common/SignalR.Common/src/Protocol/IHubProtocol.cs

@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
         /// <param name="binder">The binder used to parse the message.</param>
         /// <param name="binder">The binder used to parse the message.</param>
         /// <param name="message">When this method returns <c>true</c>, contains the parsed message.</param>
         /// <param name="message">When this method returns <c>true</c>, contains the parsed message.</param>
         /// <returns>A value that is <c>true</c> if the <see cref="HubMessage"/> was successfully parsed; otherwise, <c>false</c>.</returns>
         /// <returns>A value that is <c>true</c> if the <see cref="HubMessage"/> was successfully parsed; otherwise, <c>false</c>.</returns>
-        bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, [NotNullWhen(true)] out HubMessage message);
+        bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder, [NotNullWhen(true)] out HubMessage? message);
 
 
         /// <summary>
         /// <summary>
         /// Writes the specified <see cref="HubMessage"/> to a writer.
         /// Writes the specified <see cref="HubMessage"/> to a writer.

+ 21 - 1
src/SignalR/common/SignalR.Common/src/PublicAPI.Unshipped.txt

@@ -1,5 +1,25 @@
 #nullable enable
 #nullable enable
 *REMOVED*Microsoft.AspNetCore.SignalR.Protocol.InvocationBindingFailureMessage.InvocationBindingFailureMessage(string! invocationId, string! target, System.Runtime.ExceptionServices.ExceptionDispatchInfo! bindingFailure) -> void
 *REMOVED*Microsoft.AspNetCore.SignalR.Protocol.InvocationBindingFailureMessage.InvocationBindingFailureMessage(string! invocationId, string! target, System.Runtime.ExceptionServices.ExceptionDispatchInfo! bindingFailure) -> void
+*REMOVED*static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage.WithError(string! invocationId, string! error) -> Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage!
+*REMOVED*static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage.WithResult(string! invocationId, object! payload) -> Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage!
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage.Arguments.get -> object?[]?
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage.HubMethodInvocationMessage(string? invocationId, string! target, object?[]? arguments) -> void
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage.HubMethodInvocationMessage(string? invocationId, string! target, object?[]? arguments, string![]? streamIds) -> void
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.InvocationMessage.InvocationMessage(string! target, object?[]? arguments) -> void
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.InvocationMessage.InvocationMessage(string? invocationId, string! target, object?[]? arguments) -> void
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.InvocationMessage.InvocationMessage(string? invocationId, string! target, object?[]? arguments, string![]? streamIds) -> void
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.StreamInvocationMessage.StreamInvocationMessage(string! invocationId, string! target, object![]! arguments) -> void
 *REMOVED*Microsoft.AspNetCore.SignalR.Protocol.StreamInvocationMessage.StreamInvocationMessage(string! invocationId, string! target, object![]! arguments, string![]! streamIds) -> void
 *REMOVED*Microsoft.AspNetCore.SignalR.Protocol.StreamInvocationMessage.StreamInvocationMessage(string! invocationId, string! target, object![]! arguments, string![]! streamIds) -> void
+*REMOVED*Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder! binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage! message) -> bool
 Microsoft.AspNetCore.SignalR.Protocol.InvocationBindingFailureMessage.InvocationBindingFailureMessage(string? invocationId, string! target, System.Runtime.ExceptionServices.ExceptionDispatchInfo! bindingFailure) -> void
 Microsoft.AspNetCore.SignalR.Protocol.InvocationBindingFailureMessage.InvocationBindingFailureMessage(string? invocationId, string! target, System.Runtime.ExceptionServices.ExceptionDispatchInfo! bindingFailure) -> void
-Microsoft.AspNetCore.SignalR.Protocol.StreamInvocationMessage.StreamInvocationMessage(string! invocationId, string! target, object![]! arguments, string![]? streamIds) -> void
+static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage.WithError(string! invocationId, string? error) -> Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage!
+static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage.WithResult(string! invocationId, object? payload) -> Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage!
+Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage.Arguments.get -> object?[]!
+Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage.HubMethodInvocationMessage(string? invocationId, string! target, object?[]! arguments) -> void
+Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage.HubMethodInvocationMessage(string? invocationId, string! target, object?[]! arguments, string![]? streamIds) -> void
+Microsoft.AspNetCore.SignalR.Protocol.InvocationMessage.InvocationMessage(string! target, object?[]! arguments) -> void
+Microsoft.AspNetCore.SignalR.Protocol.InvocationMessage.InvocationMessage(string? invocationId, string! target, object?[]! arguments) -> void
+Microsoft.AspNetCore.SignalR.Protocol.InvocationMessage.InvocationMessage(string? invocationId, string! target, object?[]! arguments, string![]? streamIds) -> void
+Microsoft.AspNetCore.SignalR.Protocol.StreamInvocationMessage.StreamInvocationMessage(string! invocationId, string! target, object?[]! arguments) -> void
+Microsoft.AspNetCore.SignalR.Protocol.StreamInvocationMessage.StreamInvocationMessage(string! invocationId, string! target, object?[]! arguments, string![]? streamIds) -> void
+Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol.TryParseMessage(ref System.Buffers.ReadOnlySequence<byte> input, Microsoft.AspNetCore.SignalR.IInvocationBinder! binder, out Microsoft.AspNetCore.SignalR.Protocol.HubMessage? message) -> bool

+ 2 - 2
src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTestsBase.cs

@@ -167,6 +167,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":42}", "Expected 'target' to be of type String.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":42}", "Expected 'target' to be of type String.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\"}", "Missing required property 'arguments'.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\"}", "Missing required property 'arguments'.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":{}}", "Expected 'arguments' to be of type Array.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":{}}", "Expected 'arguments' to be of type Array.")]
+        [InlineData("{\"type\":1,\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]},\"invocationId\":\"42\",\"target\":\"foo\"", "Missing required property 'target'.")]
 
 
         [InlineData("{\"type\":2}", "Missing required property 'invocationId'.")]
         [InlineData("{\"type\":2}", "Missing required property 'invocationId'.")]
         [InlineData("{\"type\":2,\"invocationId\":42}", "Expected 'invocationId' to be of type String.")]
         [InlineData("{\"type\":2,\"invocationId\":42}", "Expected 'invocationId' to be of type String.")]
@@ -176,7 +177,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
         [InlineData("{\"type\":3,\"invocationId\":42}", "Expected 'invocationId' to be of type String.")]
         [InlineData("{\"type\":3,\"invocationId\":42}", "Expected 'invocationId' to be of type String.")]
         [InlineData("{\"type\":3,\"invocationId\":\"42\",\"error\":[]}", "Expected 'error' to be of type String.")]
         [InlineData("{\"type\":3,\"invocationId\":\"42\",\"error\":[]}", "Expected 'error' to be of type String.")]
 
 
-        [InlineData("{\"type\":4}", "Missing required property 'invocationId'.")]
+        [InlineData("{\"type\":4}", "Missing required property 'target'.")]
         [InlineData("{\"type\":4,\"invocationId\":42}", "Expected 'invocationId' to be of type String.")]
         [InlineData("{\"type\":4,\"invocationId\":42}", "Expected 'invocationId' to be of type String.")]
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":42}", "Expected 'target' to be of type String.")]
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":42}", "Expected 'target' to be of type String.")]
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\"}", "Missing required property 'arguments'.")]
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\"}", "Missing required property 'arguments'.")]
@@ -229,7 +230,6 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[]}", "Invocation provides 0 argument(s) but target expects 2.")]
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[]}", "Invocation provides 0 argument(s) but target expects 2.")]
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[ \"abc\", \"xyz\"]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
         [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[ \"abc\", \"xyz\"]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]}", "Invocation provides 3 argument(s) but target expects 2.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]}", "Invocation provides 3 argument(s) but target expects 2.")]
-        [InlineData("{\"type\":1,\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]},\"invocationId\":\"42\",\"target\":\"foo\"", "Invocation provides 3 argument(s) but target expects 2.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[1]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[1]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
         [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
         public void ArgumentBindingErrors(string input, string expectedMessage)
         public void ArgumentBindingErrors(string input, string expectedMessage)

+ 13 - 13
src/SignalR/server/Core/src/DefaultHubLifetimeManager.cs

@@ -80,12 +80,12 @@ namespace Microsoft.AspNetCore.SignalR
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendAllAsync(string methodName, object?[]? args, CancellationToken cancellationToken = default)
+        public override Task SendAllAsync(string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return SendToAllConnections(methodName, args, include: null, state: null, cancellationToken);
             return SendToAllConnections(methodName, args, include: null, state: null, cancellationToken);
         }
         }
 
 
-        private Task SendToAllConnections(string methodName, object?[]? args, Func<HubConnectionContext, object?, bool>? include, object? state = null, CancellationToken cancellationToken = default)
+        private Task SendToAllConnections(string methodName, object?[] args, Func<HubConnectionContext, object?, bool>? include, object? state = null, CancellationToken cancellationToken = default)
         {
         {
             List<Task>? tasks = null;
             List<Task>? tasks = null;
             SerializedHubMessage? message = null;
             SerializedHubMessage? message = null;
@@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.SignalR
 
 
         // Tasks and message are passed by ref so they can be lazily created inside the method post-filtering,
         // Tasks and message are passed by ref so they can be lazily created inside the method post-filtering,
         // while still being re-usable when sending to multiple groups
         // while still being re-usable when sending to multiple groups
-        private void SendToGroupConnections(string methodName, object?[]? args, ConcurrentDictionary<string, HubConnectionContext> connections, Func<HubConnectionContext, object?, bool>? include, object? state, ref List<Task>? tasks, ref SerializedHubMessage? message, CancellationToken cancellationToken)
+        private void SendToGroupConnections(string methodName, object?[] args, ConcurrentDictionary<string, HubConnectionContext> connections, Func<HubConnectionContext, object?, bool>? include, object? state, ref List<Task>? tasks, ref SerializedHubMessage? message, CancellationToken cancellationToken)
         {
         {
             // foreach over ConcurrentDictionary avoids allocating an enumerator
             // foreach over ConcurrentDictionary avoids allocating an enumerator
             foreach (var connection in connections)
             foreach (var connection in connections)
@@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.SignalR
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendConnectionAsync(string connectionId, string methodName, object?[]? args, CancellationToken cancellationToken = default)
+        public override Task SendConnectionAsync(string connectionId, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             if (connectionId == null)
             if (connectionId == null)
             {
             {
@@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.SignalR
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendGroupAsync(string groupName, string methodName, object?[]? args, CancellationToken cancellationToken = default)
+        public override Task SendGroupAsync(string groupName, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             if (groupName == null)
             if (groupName == null)
             {
             {
@@ -217,7 +217,7 @@ namespace Microsoft.AspNetCore.SignalR
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object?[]? args, CancellationToken cancellationToken = default)
+        public override Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             // Each task represents the list of tasks for each of the writes within a group
             // Each task represents the list of tasks for each of the writes within a group
             List<Task>? tasks = null;
             List<Task>? tasks = null;
@@ -246,7 +246,7 @@ namespace Microsoft.AspNetCore.SignalR
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendGroupExceptAsync(string groupName, string methodName, object?[]? args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
+        public override Task SendGroupExceptAsync(string groupName, string methodName, object?[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
         {
         {
             if (groupName == null)
             if (groupName == null)
             {
             {
@@ -270,18 +270,18 @@ namespace Microsoft.AspNetCore.SignalR
             return Task.CompletedTask;
             return Task.CompletedTask;
         }
         }
 
 
-        private SerializedHubMessage CreateSerializedInvocationMessage(string methodName, object?[]? args)
+        private SerializedHubMessage CreateSerializedInvocationMessage(string methodName, object?[] args)
         {
         {
             return new SerializedHubMessage(CreateInvocationMessage(methodName, args));
             return new SerializedHubMessage(CreateInvocationMessage(methodName, args));
         }
         }
 
 
-        private HubMessage CreateInvocationMessage(string methodName, object?[]? args)
+        private HubMessage CreateInvocationMessage(string methodName, object?[] args)
         {
         {
             return new InvocationMessage(methodName, args);
             return new InvocationMessage(methodName, args);
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendUserAsync(string userId, string methodName, object?[]? args, CancellationToken cancellationToken = default)
+        public override Task SendUserAsync(string userId, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return SendToAllConnections(methodName, args, (connection, state) => string.Equals(connection.UserIdentifier, (string)state!, StringComparison.Ordinal), userId, cancellationToken);
             return SendToAllConnections(methodName, args, (connection, state) => string.Equals(connection.UserIdentifier, (string)state!, StringComparison.Ordinal), userId, cancellationToken);
         }
         }
@@ -302,19 +302,19 @@ namespace Microsoft.AspNetCore.SignalR
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendAllExceptAsync(string methodName, object?[]? args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
+        public override Task SendAllExceptAsync(string methodName, object?[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default)
         {
         {
             return SendToAllConnections(methodName, args, (connection, state) => !((IReadOnlyList<string>)state!).Contains(connection.ConnectionId), excludedConnectionIds, cancellationToken);
             return SendToAllConnections(methodName, args, (connection, state) => !((IReadOnlyList<string>)state!).Contains(connection.ConnectionId), excludedConnectionIds, cancellationToken);
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object?[]? args, CancellationToken cancellationToken = default)
+        public override Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return SendToAllConnections(methodName, args, (connection, state) => ((IReadOnlyList<string>)state!).Contains(connection.ConnectionId), connectionIds, cancellationToken);
             return SendToAllConnections(methodName, args, (connection, state) => ((IReadOnlyList<string>)state!).Contains(connection.ConnectionId), connectionIds, cancellationToken);
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public override Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object?[]? args, CancellationToken cancellationToken = default)
+        public override Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return SendToAllConnections(methodName, args, (connection, state) => ((IReadOnlyList<string>)state!).Contains(connection.UserIdentifier), userIds, cancellationToken);
             return SendToAllConnections(methodName, args, (connection, state) => ((IReadOnlyList<string>)state!).Contains(connection.UserIdentifier), userIds, cancellationToken);
         }
         }

+ 1 - 1
src/SignalR/server/Core/src/DefaultUserIdProvider.cs

@@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <inheritdoc />
         /// <inheritdoc />
         public virtual string? GetUserId(HubConnectionContext connection)
         public virtual string? GetUserId(HubConnectionContext connection)
         {
         {
-            return connection.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
+            return connection.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
         }
         }
     }
     }
 }
 }

+ 9 - 11
src/SignalR/server/Core/src/HubConnectionContext.Log.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
@@ -13,34 +11,34 @@ namespace Microsoft.AspNetCore.SignalR
         private static class Log
         private static class Log
         {
         {
             // Category: HubConnectionContext
             // Category: HubConnectionContext
-            private static readonly Action<ILogger, string, Exception> _handshakeComplete =
+            private static readonly Action<ILogger, string, Exception?> _handshakeComplete =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(1, "HandshakeComplete"), "Completed connection handshake. Using HubProtocol '{Protocol}'.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(1, "HandshakeComplete"), "Completed connection handshake. Using HubProtocol '{Protocol}'.");
 
 
-            private static readonly Action<ILogger, Exception> _handshakeCanceled =
+            private static readonly Action<ILogger, Exception?> _handshakeCanceled =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "HandshakeCanceled"), "Handshake was canceled.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(2, "HandshakeCanceled"), "Handshake was canceled.");
 
 
-            private static readonly Action<ILogger, Exception> _sentPing =
+            private static readonly Action<ILogger, Exception?> _sentPing =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(3, "SentPing"), "Sent a ping message to the client.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(3, "SentPing"), "Sent a ping message to the client.");
 
 
-            private static readonly Action<ILogger, Exception> _transportBufferFull =
+            private static readonly Action<ILogger, Exception?> _transportBufferFull =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "TransportBufferFull"), "Unable to send Ping message to client, the transport buffer is full.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(4, "TransportBufferFull"), "Unable to send Ping message to client, the transport buffer is full.");
 
 
-            private static readonly Action<ILogger, Exception> _handshakeFailed =
+            private static readonly Action<ILogger, Exception?> _handshakeFailed =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "HandshakeFailed"), "Failed connection handshake.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(5, "HandshakeFailed"), "Failed connection handshake.");
 
 
             private static readonly Action<ILogger, Exception> _failedWritingMessage =
             private static readonly Action<ILogger, Exception> _failedWritingMessage =
                 LoggerMessage.Define(LogLevel.Error, new EventId(6, "FailedWritingMessage"), "Failed writing message. Aborting connection.");
                 LoggerMessage.Define(LogLevel.Error, new EventId(6, "FailedWritingMessage"), "Failed writing message. Aborting connection.");
 
 
-            private static readonly Action<ILogger, string, int, Exception> _protocolVersionFailed =
+            private static readonly Action<ILogger, string, int, Exception?> _protocolVersionFailed =
                 LoggerMessage.Define<string, int>(LogLevel.Debug, new EventId(7, "ProtocolVersionFailed"), "Server does not support version {Version} of the {Protocol} protocol.");
                 LoggerMessage.Define<string, int>(LogLevel.Debug, new EventId(7, "ProtocolVersionFailed"), "Server does not support version {Version} of the {Protocol} protocol.");
 
 
             private static readonly Action<ILogger, Exception> _abortFailed =
             private static readonly Action<ILogger, Exception> _abortFailed =
                 LoggerMessage.Define(LogLevel.Trace, new EventId(8, "AbortFailed"), "Abort callback failed.");
                 LoggerMessage.Define(LogLevel.Trace, new EventId(8, "AbortFailed"), "Abort callback failed.");
 
 
-            private static readonly Action<ILogger, int, Exception> _clientTimeout =
+            private static readonly Action<ILogger, int, Exception?> _clientTimeout =
                 LoggerMessage.Define<int>(LogLevel.Debug, new EventId(9, "ClientTimeout"), "Client timeout ({ClientTimeout}ms) elapsed without receiving a message from the client. Closing connection.");
                 LoggerMessage.Define<int>(LogLevel.Debug, new EventId(9, "ClientTimeout"), "Client timeout ({ClientTimeout}ms) elapsed without receiving a message from the client. Closing connection.");
 
 
-            private static readonly Action<ILogger, long, Exception> _handshakeSizeLimitExceeded =
+            private static readonly Action<ILogger, long, Exception?> _handshakeSizeLimitExceeded =
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(10, "HandshakeSizeLimitExceeded"), "The maximum message size of {MaxMessageSize}B was exceeded while parsing the Handshake. The message size can be configured in AddHubOptions.");
                 LoggerMessage.Define<long>(LogLevel.Debug, new EventId(10, "HandshakeSizeLimitExceeded"), "The maximum message size of {MaxMessageSize}B was exceeded while parsing the Handshake. The message size can be configured in AddHubOptions.");
 
 
             public static void HandshakeComplete(ILogger logger, string hubProtocol)
             public static void HandshakeComplete(ILogger logger, string hubProtocol)
@@ -63,7 +61,7 @@ namespace Microsoft.AspNetCore.SignalR
                 _transportBufferFull(logger, null);
                 _transportBufferFull(logger, null);
             }
             }
 
 
-            public static void HandshakeFailed(ILogger logger, Exception exception)
+            public static void HandshakeFailed(ILogger logger, Exception? exception)
             {
             {
                 _handshakeFailed(logger, exception);
                 _handshakeFailed(logger, exception);
             }
             }

+ 12 - 1
src/SignalR/server/Core/src/HubConnectionContext.cs

@@ -51,6 +51,7 @@ namespace Microsoft.AspNetCore.SignalR
         private bool _receivedMessageTimeoutEnabled = false;
         private bool _receivedMessageTimeoutEnabled = false;
         private long _receivedMessageElapsedTicks = 0;
         private long _receivedMessageElapsedTicks = 0;
         private long _receivedMessageTimestamp;
         private long _receivedMessageTimestamp;
+        private ClaimsPrincipal? _user;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="HubConnectionContext"/> class.
         /// Initializes a new instance of the <see cref="HubConnectionContext"/> class.
@@ -116,7 +117,17 @@ namespace Microsoft.AspNetCore.SignalR
         /// <summary>
         /// <summary>
         /// Gets the user for this connection.
         /// Gets the user for this connection.
         /// </summary>
         /// </summary>
-        public virtual ClaimsPrincipal? User => Features.Get<IConnectionUserFeature>()?.User;
+        public virtual ClaimsPrincipal User
+        {
+            get
+            {
+                if (_user is null)
+                {
+                    _user = Features.Get<IConnectionUserFeature>()?.User ?? new ClaimsPrincipal();
+                }
+                return _user;
+            }
+        }
 
 
         /// <summary>
         /// <summary>
         /// Gets the collection of features available on this connection.
         /// Gets the collection of features available on this connection.

+ 0 - 1
src/SignalR/server/Core/src/HubInvocationContext.cs

@@ -3,7 +3,6 @@
 
 
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Linq;
 using System.Reflection;
 using System.Reflection;
 using Microsoft.Extensions.Internal;
 using Microsoft.Extensions.Internal;
 
 

+ 0 - 2
src/SignalR/server/Core/src/HubLifetimeContext.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable enable
-
 using System;
 using System;
 
 
 namespace Microsoft.AspNetCore.SignalR
 namespace Microsoft.AspNetCore.SignalR

+ 9 - 9
src/SignalR/server/Core/src/HubLifetimeManager.cs

@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">The invocation arguments.</param>
         /// <param name="args">The invocation arguments.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendAllAsync(string methodName, object?[]? args, CancellationToken cancellationToken = default);
+        public abstract Task SendAllAsync(string methodName, object?[] args, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to all hub connections excluding the specified connections.
         /// Sends an invocation message to all hub connections excluding the specified connections.
@@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="excludedConnectionIds">A collection of connection IDs to exclude.</param>
         /// <param name="excludedConnectionIds">A collection of connection IDs to exclude.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendAllExceptAsync(string methodName, object?[]? args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default);
+        public abstract Task SendAllExceptAsync(string methodName, object?[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to the specified connection.
         /// Sends an invocation message to the specified connection.
@@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">The invocation arguments.</param>
         /// <param name="args">The invocation arguments.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendConnectionAsync(string connectionId, string methodName, object?[]? args, CancellationToken cancellationToken = default);
+        public abstract Task SendConnectionAsync(string connectionId, string methodName, object?[] args, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to the specified connections.
         /// Sends an invocation message to the specified connections.
@@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">The invocation arguments.</param>
         /// <param name="args">The invocation arguments.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object?[]? args, CancellationToken cancellationToken = default);
+        public abstract Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object?[] args, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to the specified group.
         /// Sends an invocation message to the specified group.
@@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">The invocation arguments.</param>
         /// <param name="args">The invocation arguments.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendGroupAsync(string groupName, string methodName, object?[]? args, CancellationToken cancellationToken = default);
+        public abstract Task SendGroupAsync(string groupName, string methodName, object?[] args, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to the specified groups.
         /// Sends an invocation message to the specified groups.
@@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">The invocation arguments.</param>
         /// <param name="args">The invocation arguments.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object?[]? args, CancellationToken cancellationToken = default);
+        public abstract Task SendGroupsAsync(IReadOnlyList<string> groupNames, string methodName, object?[] args, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to the specified group excluding the specified connections.
         /// Sends an invocation message to the specified group excluding the specified connections.
@@ -96,7 +96,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="excludedConnectionIds">A collection of connection IDs to exclude.</param>
         /// <param name="excludedConnectionIds">A collection of connection IDs to exclude.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendGroupExceptAsync(string groupName, string methodName, object?[]? args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default);
+        public abstract Task SendGroupExceptAsync(string groupName, string methodName, object?[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to the specified user.
         /// Sends an invocation message to the specified user.
@@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">The invocation arguments.</param>
         /// <param name="args">The invocation arguments.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendUserAsync(string userId, string methodName, object?[]? args, CancellationToken cancellationToken = default);
+        public abstract Task SendUserAsync(string userId, string methodName, object?[] args, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Sends an invocation message to the specified users.
         /// Sends an invocation message to the specified users.
@@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">The invocation arguments.</param>
         /// <param name="args">The invocation arguments.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous send.</returns>
-        public abstract Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object?[]? args, CancellationToken cancellationToken = default);
+        public abstract Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object?[] args, CancellationToken cancellationToken = default);
 
 
         /// <summary>
         /// <summary>
         /// Adds a connection to the specified group.
         /// Adds a connection to the specified group.

+ 0 - 2
src/SignalR/server/Core/src/HubOptionsExtensions.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable enable
-
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.CodeAnalysis;

+ 1 - 1
src/SignalR/server/Core/src/IClientProxy.cs

@@ -23,6 +23,6 @@ namespace Microsoft.AspNetCore.SignalR
         /// <param name="args">A collection of arguments to pass to the client.</param>
         /// <param name="args">A collection of arguments to pass to the client.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
         /// <returns>A <see cref="Task"/> that represents the asynchronous invoke.</returns>
-        Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default);
+        Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default);
     }
     }
 }
 }

+ 27 - 29
src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.Log.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using Microsoft.AspNetCore.SignalR.Protocol;
 using Microsoft.AspNetCore.SignalR.Protocol;
 using Microsoft.Extensions.Internal;
 using Microsoft.Extensions.Internal;
@@ -14,72 +12,72 @@ namespace Microsoft.AspNetCore.SignalR.Internal
     {
     {
         private static class Log
         private static class Log
         {
         {
-            private static readonly Action<ILogger, InvocationMessage, Exception> _receivedHubInvocation =
+            private static readonly Action<ILogger, InvocationMessage, Exception?> _receivedHubInvocation =
                 LoggerMessage.Define<InvocationMessage>(LogLevel.Debug, new EventId(1, "ReceivedHubInvocation"), "Received hub invocation: {InvocationMessage}.");
                 LoggerMessage.Define<InvocationMessage>(LogLevel.Debug, new EventId(1, "ReceivedHubInvocation"), "Received hub invocation: {InvocationMessage}.");
 
 
-            private static readonly Action<ILogger, string, Exception> _unsupportedMessageReceived =
+            private static readonly Action<ILogger, string, Exception?> _unsupportedMessageReceived =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(2, "UnsupportedMessageReceived"), "Received unsupported message of type '{MessageType}'.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(2, "UnsupportedMessageReceived"), "Received unsupported message of type '{MessageType}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _unknownHubMethod =
+            private static readonly Action<ILogger, string, Exception?> _unknownHubMethod =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(3, "UnknownHubMethod"), "Unknown hub method '{HubMethod}'.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(3, "UnknownHubMethod"), "Unknown hub method '{HubMethod}'.");
 
 
             // 4, OutboundChannelClosed - removed
             // 4, OutboundChannelClosed - removed
 
 
-            private static readonly Action<ILogger, string, Exception> _hubMethodNotAuthorized =
+            private static readonly Action<ILogger, string, Exception?> _hubMethodNotAuthorized =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(5, "HubMethodNotAuthorized"), "Failed to invoke '{HubMethod}' because user is unauthorized.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(5, "HubMethodNotAuthorized"), "Failed to invoke '{HubMethod}' because user is unauthorized.");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _streamingResult =
+            private static readonly Action<ILogger, string, string, Exception?> _streamingResult =
                 LoggerMessage.Define<string, string>(LogLevel.Trace, new EventId(6, "StreamingResult"), "InvocationId {InvocationId}: Streaming result of type '{ResultType}'.");
                 LoggerMessage.Define<string, string>(LogLevel.Trace, new EventId(6, "StreamingResult"), "InvocationId {InvocationId}: Streaming result of type '{ResultType}'.");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _sendingResult =
-                LoggerMessage.Define<string, string>(LogLevel.Trace, new EventId(7, "SendingResult"), "InvocationId {InvocationId}: Sending result of type '{ResultType}'.");
+            private static readonly Action<ILogger, string?, string, Exception?> _sendingResult =
+                LoggerMessage.Define<string?, string>(LogLevel.Trace, new EventId(7, "SendingResult"), "InvocationId {InvocationId}: Sending result of type '{ResultType}'.");
 
 
             private static readonly Action<ILogger, string, Exception> _failedInvokingHubMethod =
             private static readonly Action<ILogger, string, Exception> _failedInvokingHubMethod =
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(8, "FailedInvokingHubMethod"), "Failed to invoke hub method '{HubMethod}'.");
                 LoggerMessage.Define<string>(LogLevel.Error, new EventId(8, "FailedInvokingHubMethod"), "Failed to invoke hub method '{HubMethod}'.");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _hubMethodBound =
+            private static readonly Action<ILogger, string, string, Exception?> _hubMethodBound =
                 LoggerMessage.Define<string, string>(LogLevel.Trace, new EventId(9, "HubMethodBound"), "'{HubName}' hub method '{HubMethod}' is bound.");
                 LoggerMessage.Define<string, string>(LogLevel.Trace, new EventId(9, "HubMethodBound"), "'{HubName}' hub method '{HubMethod}' is bound.");
 
 
-            private static readonly Action<ILogger, string, Exception> _cancelStream =
+            private static readonly Action<ILogger, string, Exception?> _cancelStream =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(10, "CancelStream"), "Canceling stream for invocation {InvocationId}.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(10, "CancelStream"), "Canceling stream for invocation {InvocationId}.");
 
 
-            private static readonly Action<ILogger, Exception> _unexpectedCancel =
+            private static readonly Action<ILogger, Exception?> _unexpectedCancel =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(11, "UnexpectedCancel"), "CancelInvocationMessage received unexpectedly.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(11, "UnexpectedCancel"), "CancelInvocationMessage received unexpectedly.");
 
 
-            private static readonly Action<ILogger, StreamInvocationMessage, Exception> _receivedStreamHubInvocation =
+            private static readonly Action<ILogger, StreamInvocationMessage, Exception?> _receivedStreamHubInvocation =
                 LoggerMessage.Define<StreamInvocationMessage>(LogLevel.Debug, new EventId(12, "ReceivedStreamHubInvocation"), "Received stream hub invocation: {InvocationMessage}.");
                 LoggerMessage.Define<StreamInvocationMessage>(LogLevel.Debug, new EventId(12, "ReceivedStreamHubInvocation"), "Received stream hub invocation: {InvocationMessage}.");
 
 
-            private static readonly Action<ILogger, HubMethodInvocationMessage, Exception> _streamingMethodCalledWithInvoke =
+            private static readonly Action<ILogger, HubMethodInvocationMessage, Exception?> _streamingMethodCalledWithInvoke =
                 LoggerMessage.Define<HubMethodInvocationMessage>(LogLevel.Debug, new EventId(13, "StreamingMethodCalledWithInvoke"), "A streaming method was invoked with a non-streaming invocation : {InvocationMessage}.");
                 LoggerMessage.Define<HubMethodInvocationMessage>(LogLevel.Debug, new EventId(13, "StreamingMethodCalledWithInvoke"), "A streaming method was invoked with a non-streaming invocation : {InvocationMessage}.");
 
 
-            private static readonly Action<ILogger, HubMethodInvocationMessage, Exception> _nonStreamingMethodCalledWithStream =
+            private static readonly Action<ILogger, HubMethodInvocationMessage, Exception?> _nonStreamingMethodCalledWithStream =
                 LoggerMessage.Define<HubMethodInvocationMessage>(LogLevel.Debug, new EventId(14, "NonStreamingMethodCalledWithStream"), "A non-streaming method was invoked with a streaming invocation : {InvocationMessage}.");
                 LoggerMessage.Define<HubMethodInvocationMessage>(LogLevel.Debug, new EventId(14, "NonStreamingMethodCalledWithStream"), "A non-streaming method was invoked with a streaming invocation : {InvocationMessage}.");
 
 
-            private static readonly Action<ILogger, string, Exception> _invalidReturnValueFromStreamingMethod =
+            private static readonly Action<ILogger, string, Exception?> _invalidReturnValueFromStreamingMethod =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(15, "InvalidReturnValueFromStreamingMethod"), "A streaming method returned a value that cannot be used to build enumerator {HubMethod}.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(15, "InvalidReturnValueFromStreamingMethod"), "A streaming method returned a value that cannot be used to build enumerator {HubMethod}.");
 
 
-            private static readonly Action<ILogger, string, Exception> _receivedStreamItem =
+            private static readonly Action<ILogger, string, Exception?> _receivedStreamItem =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(16, "ReceivedStreamItem"), "Received item for stream '{StreamId}'.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(16, "ReceivedStreamItem"), "Received item for stream '{StreamId}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _startingParameterStream =
+            private static readonly Action<ILogger, string, Exception?> _startingParameterStream =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(17, "StartingParameterStream"), "Creating streaming parameter channel '{StreamId}'.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(17, "StartingParameterStream"), "Creating streaming parameter channel '{StreamId}'.");
 
 
-            private static readonly Action<ILogger, string, Exception> _completingStream =
+            private static readonly Action<ILogger, string, Exception?> _completingStream =
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(18, "CompletingStream"), "Stream '{StreamId}' has been completed by client.");
                 LoggerMessage.Define<string>(LogLevel.Trace, new EventId(18, "CompletingStream"), "Stream '{StreamId}' has been completed by client.");
 
 
-            private static readonly Action<ILogger, string, string, Exception> _closingStreamWithBindingError =
+            private static readonly Action<ILogger, string, string, Exception?> _closingStreamWithBindingError =
                 LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(19, "ClosingStreamWithBindingError"), "Stream '{StreamId}' closed with error '{Error}'.");
                 LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(19, "ClosingStreamWithBindingError"), "Stream '{StreamId}' closed with error '{Error}'.");
 
 
-            private static readonly Action<ILogger, Exception> _unexpectedStreamCompletion =
+            private static readonly Action<ILogger, Exception?> _unexpectedStreamCompletion =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(20, "UnexpectedStreamCompletion"), "StreamCompletionMessage received unexpectedly.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(20, "UnexpectedStreamCompletion"), "StreamCompletionMessage received unexpectedly.");
 
 
-            private static readonly Action<ILogger, Exception> _unexpectedStreamItem =
+            private static readonly Action<ILogger, Exception?> _unexpectedStreamItem =
                 LoggerMessage.Define(LogLevel.Debug, new EventId(21, "UnexpectedStreamItem"), "StreamItemMessage received unexpectedly.");
                 LoggerMessage.Define(LogLevel.Debug, new EventId(21, "UnexpectedStreamItem"), "StreamItemMessage received unexpectedly.");
 
 
             private static readonly Action<ILogger, string, Exception> _invalidHubParameters =
             private static readonly Action<ILogger, string, Exception> _invalidHubParameters =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(22, "InvalidHubParameters"), "Parameters to hub method '{HubMethod}' are incorrect.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(22, "InvalidHubParameters"), "Parameters to hub method '{HubMethod}' are incorrect.");
 
 
-            private static readonly Action<ILogger, string, Exception> _invocationIdInUse =
+            private static readonly Action<ILogger, string, Exception?> _invocationIdInUse =
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(23, "InvocationIdInUse"), "Invocation ID '{InvocationId}' is already in use.");
                 LoggerMessage.Define<string>(LogLevel.Debug, new EventId(23, "InvocationIdInUse"), "Invocation ID '{InvocationId}' is already in use.");
 
 
             public static void ReceivedHubInvocation(ILogger logger, InvocationMessage invocationMessage)
             public static void ReceivedHubInvocation(ILogger logger, InvocationMessage invocationMessage)
@@ -105,15 +103,15 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             public static void StreamingResult(ILogger logger, string invocationId, ObjectMethodExecutor objectMethodExecutor)
             public static void StreamingResult(ILogger logger, string invocationId, ObjectMethodExecutor objectMethodExecutor)
             {
             {
                 var resultType = objectMethodExecutor.AsyncResultType == null ? objectMethodExecutor.MethodReturnType : objectMethodExecutor.AsyncResultType;
                 var resultType = objectMethodExecutor.AsyncResultType == null ? objectMethodExecutor.MethodReturnType : objectMethodExecutor.AsyncResultType;
-                _streamingResult(logger, invocationId, resultType.FullName, null);
+                _streamingResult(logger, invocationId, resultType.FullName!, null);
             }
             }
 
 
-            public static void SendingResult(ILogger logger, string invocationId, ObjectMethodExecutor objectMethodExecutor)
+            public static void SendingResult(ILogger logger, string? invocationId, ObjectMethodExecutor objectMethodExecutor)
             {
             {
                 if (logger.IsEnabled(LogLevel.Trace))
                 if (logger.IsEnabled(LogLevel.Trace))
                 {
                 {
                     var resultType = objectMethodExecutor.AsyncResultType == null ? objectMethodExecutor.MethodReturnType : objectMethodExecutor.AsyncResultType;
                     var resultType = objectMethodExecutor.AsyncResultType == null ? objectMethodExecutor.MethodReturnType : objectMethodExecutor.AsyncResultType;
-                    _sendingResult(logger, invocationId, resultType.FullName, null);
+                    _sendingResult(logger, invocationId, resultType.FullName!, null);
                 }
                 }
             }
             }
 
 
@@ -159,7 +157,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
             public static void ReceivedStreamItem(ILogger logger, StreamItemMessage message)
             public static void ReceivedStreamItem(ILogger logger, StreamItemMessage message)
             {
             {
-                _receivedStreamItem(logger, message.InvocationId, null);
+                _receivedStreamItem(logger, message.InvocationId!, null);
             }
             }
 
 
             public static void StartingParameterStream(ILogger logger, string streamId)
             public static void StartingParameterStream(ILogger logger, string streamId)
@@ -169,12 +167,12 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
             public static void CompletingStream(ILogger logger, CompletionMessage message)
             public static void CompletingStream(ILogger logger, CompletionMessage message)
             {
             {
-                _completingStream(logger, message.InvocationId, null);
+                _completingStream(logger, message.InvocationId!, null);
             }
             }
 
 
             public static void ClosingStreamWithBindingError(ILogger logger, CompletionMessage message)
             public static void ClosingStreamWithBindingError(ILogger logger, CompletionMessage message)
             {
             {
-                _closingStreamWithBindingError(logger, message.InvocationId, message.Error, null);
+                _closingStreamWithBindingError(logger, message.InvocationId!, message.Error!, null);
             }
             }
 
 
             public static void UnexpectedStreamCompletion(ILogger logger)
             public static void UnexpectedStreamCompletion(ILogger logger)

+ 56 - 51
src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
@@ -28,12 +26,12 @@ namespace Microsoft.AspNetCore.SignalR.Internal
         private readonly IHubContext<THub> _hubContext;
         private readonly IHubContext<THub> _hubContext;
         private readonly ILogger<HubDispatcher<THub>> _logger;
         private readonly ILogger<HubDispatcher<THub>> _logger;
         private readonly bool _enableDetailedErrors;
         private readonly bool _enableDetailedErrors;
-        private readonly Func<HubInvocationContext, ValueTask<object>> _invokeMiddleware;
-        private readonly Func<HubLifetimeContext, Task> _onConnectedMiddleware;
-        private readonly Func<HubLifetimeContext, Exception, Task> _onDisconnectedMiddleware;
+        private readonly Func<HubInvocationContext, ValueTask<object?>>? _invokeMiddleware;
+        private readonly Func<HubLifetimeContext, Task>? _onConnectedMiddleware;
+        private readonly Func<HubLifetimeContext, Exception?, Task>? _onDisconnectedMiddleware;
 
 
         public DefaultHubDispatcher(IServiceScopeFactory serviceScopeFactory, IHubContext<THub> hubContext, bool enableDetailedErrors,
         public DefaultHubDispatcher(IServiceScopeFactory serviceScopeFactory, IHubContext<THub> hubContext, bool enableDetailedErrors,
-            ILogger<DefaultHubDispatcher<THub>> logger, List<IHubFilter> hubFilters)
+            ILogger<DefaultHubDispatcher<THub>> logger, List<IHubFilter>? hubFilters)
         {
         {
             _serviceScopeFactory = serviceScopeFactory;
             _serviceScopeFactory = serviceScopeFactory;
             _hubContext = hubContext;
             _hubContext = hubContext;
@@ -46,7 +44,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             {
             {
                 _invokeMiddleware = (invocationContext) =>
                 _invokeMiddleware = (invocationContext) =>
                 {
                 {
-                    var arguments = invocationContext.HubMethodArguments as object[] ?? invocationContext.HubMethodArguments.ToArray();
+                    var arguments = invocationContext.HubMethodArguments as object?[] ?? invocationContext.HubMethodArguments.ToArray();
                     if (invocationContext.ObjectMethodExecutor != null)
                     if (invocationContext.ObjectMethodExecutor != null)
                     {
                     {
                         return ExecuteMethod(invocationContext.ObjectMethodExecutor, invocationContext.Hub, arguments);
                         return ExecuteMethod(invocationContext.ObjectMethodExecutor, invocationContext.Hub, arguments);
@@ -59,7 +57,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
                 for (var i = count - 1; i > -1; i--)
                 for (var i = count - 1; i > -1; i--)
                 {
                 {
-                    var resolvedFilter = hubFilters[i];
+                    var resolvedFilter = hubFilters![i];
                     var nextFilter = _invokeMiddleware;
                     var nextFilter = _invokeMiddleware;
                     _invokeMiddleware = (context) => resolvedFilter.InvokeMethodAsync(context, nextFilter);
                     _invokeMiddleware = (context) => resolvedFilter.InvokeMethodAsync(context, nextFilter);
 
 
@@ -74,12 +72,10 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
         public override async Task OnConnectedAsync(HubConnectionContext connection)
         public override async Task OnConnectedAsync(HubConnectionContext connection)
         {
         {
-            IServiceScope scope = null;
+            var scope = _serviceScopeFactory.CreateScope();
 
 
             try
             try
             {
             {
-                scope = _serviceScopeFactory.CreateScope();
-
                 var hubActivator = scope.ServiceProvider.GetRequiredService<IHubActivator<THub>>();
                 var hubActivator = scope.ServiceProvider.GetRequiredService<IHubActivator<THub>>();
                 var hub = hubActivator.Create();
                 var hub = hubActivator.Create();
                 try
                 try
@@ -107,14 +103,12 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             }
             }
         }
         }
 
 
-        public override async Task OnDisconnectedAsync(HubConnectionContext connection, Exception exception)
+        public override async Task OnDisconnectedAsync(HubConnectionContext connection, Exception? exception)
         {
         {
-            IServiceScope scope = null;
+            var scope = _serviceScopeFactory.CreateScope();
 
 
             try
             try
             {
             {
-                scope = _serviceScopeFactory.CreateScope();
-
                 var hubActivator = scope.ServiceProvider.GetRequiredService<IHubActivator<THub>>();
                 var hubActivator = scope.ServiceProvider.GetRequiredService<IHubActivator<THub>>();
                 var hub = hubActivator.Create();
                 var hub = hubActivator.Create();
                 try
                 try
@@ -168,9 +162,9 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                 case CancelInvocationMessage cancelInvocationMessage:
                 case CancelInvocationMessage cancelInvocationMessage:
                     // Check if there is an associated active stream and cancel it if it exists.
                     // Check if there is an associated active stream and cancel it if it exists.
                     // The cts will be removed when the streaming method completes executing
                     // The cts will be removed when the streaming method completes executing
-                    if (connection.ActiveRequestCancellationSources.TryGetValue(cancelInvocationMessage.InvocationId, out var cts))
+                    if (connection.ActiveRequestCancellationSources.TryGetValue(cancelInvocationMessage.InvocationId!, out var cts))
                     {
                     {
-                        Log.CancelStream(_logger, cancelInvocationMessage.InvocationId);
+                        Log.CancelStream(_logger, cancelInvocationMessage.InvocationId!);
                         cts.Cancel();
                         cts.Cancel();
                     }
                     }
                     else
                     else
@@ -202,7 +196,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
                 // Other kind of message we weren't expecting
                 // Other kind of message we weren't expecting
                 default:
                 default:
-                    Log.UnsupportedMessageReceived(_logger, hubMessage.GetType().FullName);
+                    Log.UnsupportedMessageReceived(_logger, hubMessage.GetType().FullName!);
                     throw new NotSupportedException($"Received unsupported message: {hubMessage}");
                     throw new NotSupportedException($"Received unsupported message: {hubMessage}");
             }
             }
 
 
@@ -251,10 +245,18 @@ namespace Microsoft.AspNetCore.SignalR.Internal
         {
         {
             if (!_methods.TryGetValue(hubMethodInvocationMessage.Target, out var descriptor))
             if (!_methods.TryGetValue(hubMethodInvocationMessage.Target, out var descriptor))
             {
             {
-                // Send an error to the client. Then let the normal completion process occur
                 Log.UnknownHubMethod(_logger, hubMethodInvocationMessage.Target);
                 Log.UnknownHubMethod(_logger, hubMethodInvocationMessage.Target);
-                return connection.WriteAsync(CompletionMessage.WithError(
-                    hubMethodInvocationMessage.InvocationId, $"Unknown hub method '{hubMethodInvocationMessage.Target}'")).AsTask();
+
+                if (!string.IsNullOrEmpty(hubMethodInvocationMessage.InvocationId))
+                {
+                    // Send an error to the client. Then let the normal completion process occur
+                    return connection.WriteAsync(CompletionMessage.WithError(
+                        hubMethodInvocationMessage.InvocationId, $"Unknown hub method '{hubMethodInvocationMessage.Target}'")).AsTask();
+                }
+                else
+                {
+                    return Task.CompletedTask;
+                }
             }
             }
             else
             else
             {
             {
@@ -281,8 +283,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
             var disposeScope = true;
             var disposeScope = true;
             var scope = _serviceScopeFactory.CreateScope();
             var scope = _serviceScopeFactory.CreateScope();
-            IHubActivator<THub> hubActivator = null;
-            THub hub = null;
+            IHubActivator<THub>? hubActivator = null;
+            THub? hub = null;
             try
             try
             {
             {
                 hubActivator = scope.ServiceProvider.GetRequiredService<IHubActivator<THub>>();
                 hubActivator = scope.ServiceProvider.GetRequiredService<IHubActivator<THub>>();
@@ -315,10 +317,10 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                     }
                     }
 
 
                     InitializeHub(hub, connection);
                     InitializeHub(hub, connection);
-                    Task invocation = null;
+                    Task? invocation = null;
 
 
                     var arguments = hubMethodInvocationMessage.Arguments;
                     var arguments = hubMethodInvocationMessage.Arguments;
-                    CancellationTokenSource cts = null;
+                    CancellationTokenSource? cts = null;
                     if (descriptor.HasSyntheticArguments)
                     if (descriptor.HasSyntheticArguments)
                     {
                     {
                         ReplaceArguments(descriptor, hubMethodInvocationMessage, isStreamCall, connection, ref arguments, out cts);
                         ReplaceArguments(descriptor, hubMethodInvocationMessage, isStreamCall, connection, ref arguments, out cts);
@@ -326,14 +328,14 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
                     if (isStreamResponse)
                     if (isStreamResponse)
                     {
                     {
-                        _ = StreamAsync(hubMethodInvocationMessage.InvocationId, connection, arguments, scope, hubActivator, hub, cts, hubMethodInvocationMessage, descriptor);
+                        _ = StreamAsync(hubMethodInvocationMessage.InvocationId!, connection, arguments, scope, hubActivator, hub, cts, hubMethodInvocationMessage, descriptor);
                     }
                     }
                     else
                     else
                     {
                     {
                         // Invoke or Send
                         // Invoke or Send
                         async Task ExecuteInvocation()
                         async Task ExecuteInvocation()
                         {
                         {
-                            object result;
+                            object? result;
                             try
                             try
                             {
                             {
                                 result = await ExecuteHubMethod(methodExecutor, hub, arguments, connection, scope.ServiceProvider);
                                 result = await ExecuteHubMethod(methodExecutor, hub, arguments, connection, scope.ServiceProvider);
@@ -375,14 +377,14 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                     else
                     else
                     {
                     {
                         // complete the non-streaming calls now
                         // complete the non-streaming calls now
-                        await invocation;
+                        await invocation!;
                     }
                     }
                 }
                 }
                 catch (TargetInvocationException ex)
                 catch (TargetInvocationException ex)
                 {
                 {
                     Log.FailedInvokingHubMethod(_logger, hubMethodInvocationMessage.Target, ex);
                     Log.FailedInvokingHubMethod(_logger, hubMethodInvocationMessage.Target, ex);
                     await SendInvocationError(hubMethodInvocationMessage.InvocationId, connection,
                     await SendInvocationError(hubMethodInvocationMessage.InvocationId, connection,
-                        ErrorMessageHelper.BuildErrorMessage($"An unexpected error occurred invoking '{hubMethodInvocationMessage.Target}' on the server.", ex.InnerException, _enableDetailedErrors));
+                        ErrorMessageHelper.BuildErrorMessage($"An unexpected error occurred invoking '{hubMethodInvocationMessage.Target}' on the server.", ex.InnerException ?? ex, _enableDetailedErrors));
                 }
                 }
                 catch (Exception ex)
                 catch (Exception ex)
                 {
                 {
@@ -400,8 +402,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             }
             }
         }
         }
 
 
-        private ValueTask CleanupInvocation(HubConnectionContext connection, HubMethodInvocationMessage hubMessage, IHubActivator<THub> hubActivator,
-            THub hub, IServiceScope scope)
+        private ValueTask CleanupInvocation(HubConnectionContext connection, HubMethodInvocationMessage hubMessage, IHubActivator<THub>? hubActivator,
+            THub? hub, IServiceScope scope)
         {
         {
             if (hubMessage.StreamIds != null)
             if (hubMessage.StreamIds != null)
             {
             {
@@ -411,17 +413,20 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                 }
                 }
             }
             }
 
 
-            hubActivator?.Release(hub);
+            if (hub != null)
+            {
+                hubActivator?.Release(hub);
+            }
 
 
             return scope.DisposeAsync();
             return scope.DisposeAsync();
         }
         }
 
 
-        private async Task StreamAsync(string invocationId, HubConnectionContext connection, object[] arguments, IServiceScope scope,
-            IHubActivator<THub> hubActivator, THub hub, CancellationTokenSource streamCts, HubMethodInvocationMessage hubMethodInvocationMessage, HubMethodDescriptor descriptor)
+        private async Task StreamAsync(string invocationId, HubConnectionContext connection, object?[] arguments, IServiceScope scope,
+            IHubActivator<THub> hubActivator, THub hub, CancellationTokenSource? streamCts, HubMethodInvocationMessage hubMethodInvocationMessage, HubMethodDescriptor descriptor)
         {
         {
-            string error = null;
+            string? error = null;
 
 
-            streamCts = streamCts ?? CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAborted);
+            streamCts ??= CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAborted);
 
 
             try
             try
             {
             {
@@ -432,7 +437,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                     return;
                     return;
                 }
                 }
 
 
-                object result;
+                object? result;
                 try
                 try
                 {
                 {
                     result = await ExecuteHubMethod(descriptor.MethodExecutor, hub, arguments, connection, scope.ServiceProvider);
                     result = await ExecuteHubMethod(descriptor.MethodExecutor, hub, arguments, connection, scope.ServiceProvider);
@@ -453,7 +458,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
                 var enumerable = descriptor.FromReturnedStream(result, streamCts.Token);
                 var enumerable = descriptor.FromReturnedStream(result, streamCts.Token);
 
 
-                Log.StreamingResult(_logger, hubMethodInvocationMessage.InvocationId, descriptor.MethodExecutor);
+                Log.StreamingResult(_logger, invocationId, descriptor.MethodExecutor);
 
 
                 await foreach (var streamItem in enumerable)
                 await foreach (var streamItem in enumerable)
                 {
                 {
@@ -485,7 +490,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             }
             }
         }
         }
 
 
-        private ValueTask<object> ExecuteHubMethod(ObjectMethodExecutor methodExecutor, THub hub, object[] arguments, HubConnectionContext connection, IServiceProvider serviceProvider)
+        private ValueTask<object?> ExecuteHubMethod(ObjectMethodExecutor methodExecutor, THub hub, object?[] arguments, HubConnectionContext connection, IServiceProvider serviceProvider)
         {
         {
             if (_invokeMiddleware != null)
             if (_invokeMiddleware != null)
             {
             {
@@ -497,7 +502,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             return ExecuteMethod(methodExecutor, hub, arguments);
             return ExecuteMethod(methodExecutor, hub, arguments);
         }
         }
 
 
-        private ValueTask<object> ExecuteMethod(string hubMethodName, Hub hub, object[] arguments)
+        private ValueTask<object?> ExecuteMethod(string hubMethodName, Hub hub, object?[] arguments)
         {
         {
             if (!_methods.TryGetValue(hubMethodName, out var methodDescriptor))
             if (!_methods.TryGetValue(hubMethodName, out var methodDescriptor))
             {
             {
@@ -507,13 +512,13 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             return ExecuteMethod(methodExecutor, hub, arguments);
             return ExecuteMethod(methodExecutor, hub, arguments);
         }
         }
 
 
-        private async ValueTask<object> ExecuteMethod(ObjectMethodExecutor methodExecutor, Hub hub, object[] arguments)
+        private async ValueTask<object?> ExecuteMethod(ObjectMethodExecutor methodExecutor, Hub hub, object?[] arguments)
         {
         {
             if (methodExecutor.IsMethodAsync)
             if (methodExecutor.IsMethodAsync)
             {
             {
                 if (methodExecutor.MethodReturnType == typeof(Task))
                 if (methodExecutor.MethodReturnType == typeof(Task))
                 {
                 {
-                    await (Task)methodExecutor.Execute(hub, arguments);
+                    await (Task)methodExecutor.Execute(hub, arguments)!;
                     return null;
                     return null;
                 }
                 }
                 else
                 else
@@ -527,7 +532,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             }
             }
         }
         }
 
 
-        private async Task SendInvocationError(string invocationId,
+        private async Task SendInvocationError(string? invocationId,
             HubConnectionContext connection, string errorMessage)
             HubConnectionContext connection, string errorMessage)
         {
         {
             if (string.IsNullOrEmpty(invocationId))
             if (string.IsNullOrEmpty(invocationId))
@@ -545,7 +550,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             hub.Groups = _hubContext.Groups;
             hub.Groups = _hubContext.Groups;
         }
         }
 
 
-        private Task<bool> IsHubMethodAuthorized(IServiceProvider provider, HubConnectionContext hubConnectionContext, HubMethodDescriptor descriptor, object[] hubMethodArguments, Hub hub)
+        private Task<bool> IsHubMethodAuthorized(IServiceProvider provider, HubConnectionContext hubConnectionContext, HubMethodDescriptor descriptor, object?[] hubMethodArguments, Hub hub)
         {
         {
             // If there are no policies we don't need to run auth
             // If there are no policies we don't need to run auth
             if (descriptor.Policies.Count == 0)
             if (descriptor.Policies.Count == 0)
@@ -589,7 +594,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             if (!hubMethodDescriptor.IsStreamResponse && isStreamResponse)
             if (!hubMethodDescriptor.IsStreamResponse && isStreamResponse)
             {
             {
                 Log.NonStreamingMethodCalledWithStream(_logger, hubMethodInvocationMessage);
                 Log.NonStreamingMethodCalledWithStream(_logger, hubMethodInvocationMessage);
-                await connection.WriteAsync(CompletionMessage.WithError(hubMethodInvocationMessage.InvocationId,
+                await connection.WriteAsync(CompletionMessage.WithError(hubMethodInvocationMessage.InvocationId!,
                     $"The client attempted to invoke the non-streaming '{hubMethodInvocationMessage.Target}' method with a streaming invocation."));
                     $"The client attempted to invoke the non-streaming '{hubMethodInvocationMessage.Target}' method with a streaming invocation."));
 
 
                 return false;
                 return false;
@@ -599,19 +604,19 @@ namespace Microsoft.AspNetCore.SignalR.Internal
         }
         }
 
 
         private void ReplaceArguments(HubMethodDescriptor descriptor, HubMethodInvocationMessage hubMethodInvocationMessage, bool isStreamCall,
         private void ReplaceArguments(HubMethodDescriptor descriptor, HubMethodInvocationMessage hubMethodInvocationMessage, bool isStreamCall,
-            HubConnectionContext connection, ref object[] arguments, out CancellationTokenSource cts)
+            HubConnectionContext connection, ref object?[] arguments, out CancellationTokenSource? cts)
         {
         {
             cts = null;
             cts = null;
             // In order to add the synthetic arguments we need a new array because the invocation array is too small (it doesn't know about synthetic arguments)
             // In order to add the synthetic arguments we need a new array because the invocation array is too small (it doesn't know about synthetic arguments)
-            arguments = new object[descriptor.OriginalParameterTypes.Count];
+            arguments = new object?[descriptor.OriginalParameterTypes!.Count];
 
 
             var streamPointer = 0;
             var streamPointer = 0;
             var hubInvocationArgumentPointer = 0;
             var hubInvocationArgumentPointer = 0;
             for (var parameterPointer = 0; parameterPointer < arguments.Length; parameterPointer++)
             for (var parameterPointer = 0; parameterPointer < arguments.Length; parameterPointer++)
             {
             {
-                if (hubMethodInvocationMessage.Arguments.Length > hubInvocationArgumentPointer &&
+                if (hubMethodInvocationMessage.Arguments?.Length > hubInvocationArgumentPointer &&
                     (hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer] == null ||
                     (hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer] == null ||
-                    descriptor.OriginalParameterTypes[parameterPointer].IsAssignableFrom(hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer].GetType())))
+                    descriptor.OriginalParameterTypes[parameterPointer].IsAssignableFrom(hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer]?.GetType())))
                 {
                 {
                     // The types match so it isn't a synthetic argument, just copy it into the arguments array
                     // The types match so it isn't a synthetic argument, just copy it into the arguments array
                     arguments[parameterPointer] = hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer];
                     arguments[parameterPointer] = hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer];
@@ -626,8 +631,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                     }
                     }
                     else if (isStreamCall && ReflectionHelper.IsStreamingType(descriptor.OriginalParameterTypes[parameterPointer], mustBeDirectType: true))
                     else if (isStreamCall && ReflectionHelper.IsStreamingType(descriptor.OriginalParameterTypes[parameterPointer], mustBeDirectType: true))
                     {
                     {
-                        Log.StartingParameterStream(_logger, hubMethodInvocationMessage.StreamIds[streamPointer]);
-                        var itemType = descriptor.StreamingParameters[streamPointer];
+                        Log.StartingParameterStream(_logger, hubMethodInvocationMessage.StreamIds![streamPointer]);
+                        var itemType = descriptor.StreamingParameters![streamPointer];
                         arguments[parameterPointer] = connection.StreamTracker.AddStream(hubMethodInvocationMessage.StreamIds[streamPointer],
                         arguments[parameterPointer] = connection.StreamTracker.AddStream(hubMethodInvocationMessage.StreamIds[streamPointer],
                             itemType, descriptor.OriginalParameterTypes[parameterPointer]);
                             itemType, descriptor.OriginalParameterTypes[parameterPointer]);
 
 

+ 1 - 1
src/SignalR/server/Core/src/Internal/DynamicClientProxy.cs

@@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
         public override bool TryInvokeMember(InvokeMemberBinder binder, object?[]? args, out object? result)
         public override bool TryInvokeMember(InvokeMemberBinder binder, object?[]? args, out object? result)
         {
         {
-            result = _clientProxy.SendCoreAsync(binder.Name, args);
+            result = _clientProxy.SendCoreAsync(binder.Name, args!);
             return true;
             return true;
         }
         }
     }
     }

+ 7 - 9
src/SignalR/server/Core/src/Internal/HubMethodDescriptor.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
@@ -25,15 +23,15 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             .GetRuntimeMethods()
             .GetRuntimeMethods()
             .Single(m => m.Name.Equals(nameof(AsyncEnumerableAdapters.MakeAsyncEnumerableFromChannel)) && m.IsGenericMethod);
             .Single(m => m.Name.Equals(nameof(AsyncEnumerableAdapters.MakeAsyncEnumerableFromChannel)) && m.IsGenericMethod);
 
 
-        private readonly MethodInfo _makeCancelableEnumerableMethodInfo;
-        private Func<object, CancellationToken, IAsyncEnumerable<object>> _makeCancelableEnumerable;
+        private readonly MethodInfo? _makeCancelableEnumerableMethodInfo;
+        private Func<object, CancellationToken, IAsyncEnumerable<object>>? _makeCancelableEnumerable;
 
 
         public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IEnumerable<IAuthorizeData> policies)
         public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IEnumerable<IAuthorizeData> policies)
         {
         {
             MethodExecutor = methodExecutor;
             MethodExecutor = methodExecutor;
 
 
             NonAsyncReturnType = (MethodExecutor.IsMethodAsync)
             NonAsyncReturnType = (MethodExecutor.IsMethodAsync)
-                ? MethodExecutor.AsyncResultType
+                ? MethodExecutor.AsyncResultType!
                 : MethodExecutor.MethodReturnType;
                 : MethodExecutor.MethodReturnType;
 
 
             foreach (var returnType in NonAsyncReturnType.GetInterfaces().Concat(NonAsyncReturnType.AllBaseTypes()))
             foreach (var returnType in NonAsyncReturnType.GetInterfaces().Concat(NonAsyncReturnType.AllBaseTypes()))
@@ -91,19 +89,19 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             Policies = policies.ToArray();
             Policies = policies.ToArray();
         }
         }
 
 
-        public List<Type> StreamingParameters { get; private set; }
+        public List<Type>? StreamingParameters { get; private set; }
 
 
         public ObjectMethodExecutor MethodExecutor { get; }
         public ObjectMethodExecutor MethodExecutor { get; }
 
 
         public IReadOnlyList<Type> ParameterTypes { get; }
         public IReadOnlyList<Type> ParameterTypes { get; }
 
 
-        public IReadOnlyList<Type> OriginalParameterTypes { get; }
+        public IReadOnlyList<Type>? OriginalParameterTypes { get; }
 
 
         public Type NonAsyncReturnType { get; }
         public Type NonAsyncReturnType { get; }
 
 
         public bool IsStreamResponse => StreamReturnType != null;
         public bool IsStreamResponse => StreamReturnType != null;
 
 
-        public Type StreamReturnType { get; }
+        public Type? StreamReturnType { get; }
 
 
         public IList<IAuthorizeData> Policies { get; }
         public IList<IAuthorizeData> Policies { get; }
 
 
@@ -114,7 +112,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             // there is the potential for compile to be called times but this has no harmful effect other than perf
             // there is the potential for compile to be called times but this has no harmful effect other than perf
             if (_makeCancelableEnumerable == null)
             if (_makeCancelableEnumerable == null)
             {
             {
-                _makeCancelableEnumerable = CompileConvertToEnumerable(_makeCancelableEnumerableMethodInfo, StreamReturnType);
+                _makeCancelableEnumerable = CompileConvertToEnumerable(_makeCancelableEnumerableMethodInfo!, StreamReturnType!);
             }
             }
 
 
             return _makeCancelableEnumerable.Invoke(stream, cancellationToken);
             return _makeCancelableEnumerable.Invoke(stream, cancellationToken);

+ 9 - 9
src/SignalR/server/Core/src/Internal/Proxies.cs

@@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _userId = userId;
             _userId = userId;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendUserAsync(_userId, method, args, cancellationToken);
             return _lifetimeManager.SendUserAsync(_userId, method, args, cancellationToken);
         }
         }
@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _userIds = userIds;
             _userIds = userIds;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendUsersAsync(_userIds, method, args, cancellationToken);
             return _lifetimeManager.SendUsersAsync(_userIds, method, args, cancellationToken);
         }
         }
@@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _groupName = groupName;
             _groupName = groupName;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendGroupAsync(_groupName, method, args, cancellationToken);
             return _lifetimeManager.SendGroupAsync(_groupName, method, args, cancellationToken);
         }
         }
@@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _groupNames = groupNames;
             _groupNames = groupNames;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendGroupsAsync(_groupNames, method, args, cancellationToken);
             return _lifetimeManager.SendGroupsAsync(_groupNames, method, args, cancellationToken);
         }
         }
@@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _excludedConnectionIds = excludedConnectionIds;
             _excludedConnectionIds = excludedConnectionIds;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendGroupExceptAsync(_groupName, method, args, _excludedConnectionIds, cancellationToken);
             return _lifetimeManager.SendGroupExceptAsync(_groupName, method, args, _excludedConnectionIds, cancellationToken);
         }
         }
@@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _lifetimeManager = lifetimeManager;
             _lifetimeManager = lifetimeManager;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendAllAsync(method, args, cancellationToken);
             return _lifetimeManager.SendAllAsync(method, args, cancellationToken);
         }
         }
@@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _excludedConnectionIds = excludedConnectionIds;
             _excludedConnectionIds = excludedConnectionIds;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendAllExceptAsync(method, args, _excludedConnectionIds, cancellationToken);
             return _lifetimeManager.SendAllExceptAsync(method, args, _excludedConnectionIds, cancellationToken);
         }
         }
@@ -137,7 +137,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _connectionId = connectionId;
             _connectionId = connectionId;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendConnectionAsync(_connectionId, method, args, cancellationToken);
             return _lifetimeManager.SendConnectionAsync(_connectionId, method, args, cancellationToken);
         }
         }
@@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             _connectionIds = connectionIds;
             _connectionIds = connectionIds;
         }
         }
 
 
-        public Task SendCoreAsync(string method, object?[]? args, CancellationToken cancellationToken = default)
+        public Task SendCoreAsync(string method, object?[] args, CancellationToken cancellationToken = default)
         {
         {
             return _lifetimeManager.SendConnectionsAsync(_connectionIds, method, args, cancellationToken);
             return _lifetimeManager.SendConnectionsAsync(_connectionIds, method, args, cancellationToken);
         }
         }

+ 7 - 9
src/SignalR/server/Core/src/Internal/TypedClientBuilder.cs

@@ -1,8 +1,6 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
@@ -20,7 +18,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
         // There is one static instance of _builder per T
         // There is one static instance of _builder per T
         private static readonly Lazy<Func<IClientProxy, T>> _builder = new Lazy<Func<IClientProxy, T>>(() => GenerateClientBuilder());
         private static readonly Lazy<Func<IClientProxy, T>> _builder = new Lazy<Func<IClientProxy, T>>(() => GenerateClientBuilder());
 
 
-        private static readonly PropertyInfo CancellationTokenNoneProperty = typeof(CancellationToken).GetProperty("None", BindingFlags.Public | BindingFlags.Static);
+        private static readonly PropertyInfo CancellationTokenNoneProperty = typeof(CancellationToken).GetProperty("None", BindingFlags.Public | BindingFlags.Static)!;
 
 
         private static readonly ConstructorInfo ObjectConstructor = typeof(object).GetConstructors().Single();
         private static readonly ConstructorInfo ObjectConstructor = typeof(object).GetConstructors().Single();
 
 
@@ -47,7 +45,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             var clientType = GenerateInterfaceImplementation(moduleBuilder);
             var clientType = GenerateInterfaceImplementation(moduleBuilder);
 
 
             var factoryMethod = clientType.GetMethod(nameof(Build), BindingFlags.Public | BindingFlags.Static);
             var factoryMethod = clientType.GetMethod(nameof(Build), BindingFlags.Public | BindingFlags.Static);
-            return (Func<IClientProxy, T>)factoryMethod.CreateDelegate(typeof(Func<IClientProxy, T>));
+            return (Func<IClientProxy, T>)factoryMethod!.CreateDelegate(typeof(Func<IClientProxy, T>));
         }
         }
 
 
         private static Type GenerateInterfaceImplementation(ModuleBuilder moduleBuilder)
         private static Type GenerateInterfaceImplementation(ModuleBuilder moduleBuilder)
@@ -70,7 +68,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                 BuildMethod(type, method, proxyField);
                 BuildMethod(type, method, proxyField);
             }
             }
 
 
-            return type.CreateTypeInfo();
+            return type.CreateTypeInfo()!;
         }
         }
 
 
         private static IEnumerable<MethodInfo> GetAllInterfaceMethods(Type interfaceType)
         private static IEnumerable<MethodInfo> GetAllInterfaceMethods(Type interfaceType)
@@ -124,7 +122,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
 
 
             var invokeMethod = typeof(IClientProxy).GetMethod(
             var invokeMethod = typeof(IClientProxy).GetMethod(
                 nameof(IClientProxy.SendCoreAsync), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
                 nameof(IClientProxy.SendCoreAsync), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
-                new[] { typeof(string), typeof(object[]), typeof(CancellationToken) }, null);
+                new[] { typeof(string), typeof(object[]), typeof(CancellationToken) }, null)!;
 
 
             methodBuilder.SetReturnType(interfaceMethodInfo.ReturnType);
             methodBuilder.SetReturnType(interfaceMethodInfo.ReturnType);
             methodBuilder.SetParameters(paramTypes);
             methodBuilder.SetParameters(paramTypes);
@@ -163,7 +161,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             generator.Emit(OpCodes.Ldstr, methodName);
             generator.Emit(OpCodes.Ldstr, methodName);
 
 
             // Create an new object array to hold all the parameters to this method
             // Create an new object array to hold all the parameters to this method
-            generator.Emit(OpCodes.Ldc_I4, paramTypes.Length); // Stack: 
+            generator.Emit(OpCodes.Ldc_I4, paramTypes.Length); // Stack:
             generator.Emit(OpCodes.Newarr, typeof(object)); // allocate object array
             generator.Emit(OpCodes.Newarr, typeof(object)); // allocate object array
             generator.Emit(OpCodes.Stloc_0);
             generator.Emit(OpCodes.Stloc_0);
 
 
@@ -172,7 +170,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             {
             {
                 generator.Emit(OpCodes.Ldloc_0); // Object array loaded
                 generator.Emit(OpCodes.Ldloc_0); // Object array loaded
                 generator.Emit(OpCodes.Ldc_I4, i);
                 generator.Emit(OpCodes.Ldc_I4, i);
-                generator.Emit(OpCodes.Ldarg, i + 1); // i + 1 
+                generator.Emit(OpCodes.Ldarg, i + 1); // i + 1
                 generator.Emit(OpCodes.Box, paramTypes[i]);
                 generator.Emit(OpCodes.Box, paramTypes[i]);
                 generator.Emit(OpCodes.Stelem_Ref);
                 generator.Emit(OpCodes.Stelem_Ref);
             }
             }
@@ -188,7 +186,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             else
             else
             {
             {
                 // Get 'CancellationToken.None' and put it on the stack, for when method does not have CancellationToken
                 // Get 'CancellationToken.None' and put it on the stack, for when method does not have CancellationToken
-                generator.Emit(OpCodes.Call, CancellationTokenNoneProperty.GetMethod);
+                generator.Emit(OpCodes.Call, CancellationTokenNoneProperty.GetMethod!);
             }
             }
 
 
             // Send!
             // Send!

+ 41 - 0
src/SignalR/server/Core/src/PublicAPI.Unshipped.txt

@@ -1,2 +1,43 @@
 #nullable enable
 #nullable enable
 *REMOVED*Microsoft.AspNetCore.SignalR.HubInvocationContext.HubInvocationContext(Microsoft.AspNetCore.SignalR.HubCallerContext! context, string! hubMethodName, object?[]! hubMethodArguments) -> void
 *REMOVED*Microsoft.AspNetCore.SignalR.HubInvocationContext.HubInvocationContext(Microsoft.AspNetCore.SignalR.HubCallerContext! context, string! hubMethodName, object?[]! hubMethodArguments) -> void
+*REMOVED*virtual Microsoft.AspNetCore.SignalR.HubConnectionContext.User.get -> System.Security.Claims.ClaimsPrincipal
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendAllAsync(string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendAllExceptAsync(string! methodName, object?[]? args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendConnectionAsync(string! connectionId, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendConnectionsAsync(System.Collections.Generic.IReadOnlyList<string!>! connectionIds, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendGroupAsync(string! groupName, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendGroupExceptAsync(string! groupName, string! methodName, object?[]? args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendGroupsAsync(System.Collections.Generic.IReadOnlyList<string!>! groupNames, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendUserAsync(string! userId, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendUsersAsync(System.Collections.Generic.IReadOnlyList<string!>! userIds, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendAllAsync(string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendAllExceptAsync(string! methodName, object?[]? args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendConnectionAsync(string! connectionId, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendConnectionsAsync(System.Collections.Generic.IReadOnlyList<string!>! connectionIds, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendGroupAsync(string! groupName, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendGroupExceptAsync(string! groupName, string! methodName, object?[]? args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendGroupsAsync(System.Collections.Generic.IReadOnlyList<string!>! groupNames, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendUserAsync(string! userId, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendUsersAsync(System.Collections.Generic.IReadOnlyList<string!>! userIds, string! methodName, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*Microsoft.AspNetCore.SignalR.IClientProxy.SendCoreAsync(string! method, object?[]? args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+*REMOVED*virtual Microsoft.AspNetCore.SignalR.HubConnectionContext.User.get -> System.Security.Claims.ClaimsPrincipal?
+virtual Microsoft.AspNetCore.SignalR.HubConnectionContext.User.get -> System.Security.Claims.ClaimsPrincipal!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendAllAsync(string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendAllExceptAsync(string! methodName, object?[]! args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendConnectionAsync(string! connectionId, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendConnectionsAsync(System.Collections.Generic.IReadOnlyList<string!>! connectionIds, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendGroupAsync(string! groupName, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendGroupExceptAsync(string! groupName, string! methodName, object?[]! args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendGroupsAsync(System.Collections.Generic.IReadOnlyList<string!>! groupNames, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendUserAsync(string! userId, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.DefaultHubLifetimeManager<THub>.SendUsersAsync(System.Collections.Generic.IReadOnlyList<string!>! userIds, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendAllAsync(string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendAllExceptAsync(string! methodName, object?[]! args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendConnectionAsync(string! connectionId, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendConnectionsAsync(System.Collections.Generic.IReadOnlyList<string!>! connectionIds, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendGroupAsync(string! groupName, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendGroupExceptAsync(string! groupName, string! methodName, object?[]! args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendGroupsAsync(System.Collections.Generic.IReadOnlyList<string!>! groupNames, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendUserAsync(string! userId, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+abstract Microsoft.AspNetCore.SignalR.HubLifetimeManager<THub>.SendUsersAsync(System.Collections.Generic.IReadOnlyList<string!>! userIds, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.AspNetCore.SignalR.IClientProxy.SendCoreAsync(string! method, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!

+ 13 - 15
src/SignalR/server/Core/src/StreamTracker.cs

@@ -1,16 +1,14 @@
 // 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.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 
-#nullable disable
-
 using System;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Linq;
 using System.Reflection;
 using System.Reflection;
 using System.Threading.Channels;
 using System.Threading.Channels;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using Microsoft.AspNetCore.Internal;
 using Microsoft.AspNetCore.SignalR.Protocol;
 using Microsoft.AspNetCore.SignalR.Protocol;
 
 
 namespace Microsoft.AspNetCore.SignalR
 namespace Microsoft.AspNetCore.SignalR
@@ -31,12 +29,12 @@ namespace Microsoft.AspNetCore.SignalR
         /// </summary>
         /// </summary>
         public object AddStream(string streamId, Type itemType, Type targetType)
         public object AddStream(string streamId, Type itemType, Type targetType)
         {
         {
-            var newConverter = (IStreamConverter)_buildConverterMethod.MakeGenericMethod(itemType).Invoke(null, _streamConverterArgs);
+            var newConverter = (IStreamConverter)_buildConverterMethod.MakeGenericMethod(itemType).Invoke(null, _streamConverterArgs)!;
             _lookup[streamId] = newConverter;
             _lookup[streamId] = newConverter;
             return newConverter.GetReaderAsObject(targetType);
             return newConverter.GetReaderAsObject(targetType);
         }
         }
 
 
-        private bool TryGetConverter(string streamId, out IStreamConverter converter)
+        private bool TryGetConverter(string streamId, [NotNullWhen(true)] out IStreamConverter? converter)
         {
         {
             if (_lookup.TryGetValue(streamId, out converter))
             if (_lookup.TryGetValue(streamId, out converter))
             {
             {
@@ -46,9 +44,9 @@ namespace Microsoft.AspNetCore.SignalR
             return false;
             return false;
         }
         }
 
 
-        public bool TryProcessItem(StreamItemMessage message, out Task task)
+        public bool TryProcessItem(StreamItemMessage message, [NotNullWhen(true)] out Task? task)
         {
         {
-            if (TryGetConverter(message.InvocationId, out var converter))
+            if (TryGetConverter(message.InvocationId!, out var converter))
             {
             {
                 task = converter.WriteToStream(message.Item);
                 task = converter.WriteToStream(message.Item);
                 return true;
                 return true;
@@ -70,7 +68,7 @@ namespace Microsoft.AspNetCore.SignalR
 
 
         public bool TryComplete(CompletionMessage message)
         public bool TryComplete(CompletionMessage message)
         {
         {
-            _lookup.TryRemove(message.InvocationId, out var converter);
+            _lookup.TryRemove(message.InvocationId!, out var converter);
             if (converter == null)
             if (converter == null)
             {
             {
                 return false;
                 return false;
@@ -96,17 +94,17 @@ namespace Microsoft.AspNetCore.SignalR
         {
         {
             Type GetItemType();
             Type GetItemType();
             object GetReaderAsObject(Type type);
             object GetReaderAsObject(Type type);
-            Task WriteToStream(object item);
-            void TryComplete(Exception ex);
+            Task WriteToStream(object? item);
+            void TryComplete(Exception? ex);
         }
         }
 
 
         private class ChannelConverter<T> : IStreamConverter
         private class ChannelConverter<T> : IStreamConverter
         {
         {
-            private Channel<T> _channel;
+            private Channel<T?> _channel;
 
 
             public ChannelConverter(int streamBufferCapacity)
             public ChannelConverter(int streamBufferCapacity)
             {
             {
-                _channel = Channel.CreateBounded<T>(streamBufferCapacity);
+                _channel = Channel.CreateBounded<T?>(streamBufferCapacity);
             }
             }
 
 
             public Type GetItemType()
             public Type GetItemType()
@@ -126,12 +124,12 @@ namespace Microsoft.AspNetCore.SignalR
                 }
                 }
             }
             }
 
 
-            public Task WriteToStream(object o)
+            public Task WriteToStream(object? o)
             {
             {
-                return _channel.Writer.WriteAsync((T)o).AsTask();
+                return _channel.Writer.WriteAsync((T?)o).AsTask();
             }
             }
 
 
-            public void TryComplete(Exception ex)
+            public void TryComplete(Exception? ex)
             {
             {
                 _channel.Writer.TryComplete(ex);
                 _channel.Writer.TryComplete(ex);
             }
             }

+ 2 - 2
src/SignalR/server/SignalR/src/GetHttpContextExtensions.cs

@@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// </summary>
         /// </summary>
         /// <param name="connection">The connection.</param>
         /// <param name="connection">The connection.</param>
         /// <returns>The <see cref="HttpContext"/> for the connection, or <c>null</c> if the connection is not associated with an HTTP request.</returns>
         /// <returns>The <see cref="HttpContext"/> for the connection, or <c>null</c> if the connection is not associated with an HTTP request.</returns>
-        public static HttpContext GetHttpContext(this HubCallerContext connection)
+        public static HttpContext? GetHttpContext(this HubCallerContext connection)
         {
         {
             if (connection == null)
             if (connection == null)
             {
             {
@@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.SignalR
         /// </summary>
         /// </summary>
         /// <param name="connection">The connection.</param>
         /// <param name="connection">The connection.</param>
         /// <returns>The <see cref="HttpContext"/> for the connection, or <c>null</c> if the connection is not associated with an HTTP request.</returns>
         /// <returns>The <see cref="HttpContext"/> for the connection, or <c>null</c> if the connection is not associated with an HTTP request.</returns>
-        public static HttpContext GetHttpContext(this HubConnectionContext connection)
+        public static HttpContext? GetHttpContext(this HubConnectionContext connection)
         {
         {
             if (connection == null)
             if (connection == null)
             {
             {

+ 1 - 1
src/SignalR/server/SignalR/src/HubEndpointRouteBuilderExtensions.cs

@@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Builder
         /// <param name="pattern">The route pattern.</param>
         /// <param name="pattern">The route pattern.</param>
         /// <param name="configureOptions">A callback to configure dispatcher options.</param>
         /// <param name="configureOptions">A callback to configure dispatcher options.</param>
         /// <returns>An <see cref="HubEndpointConventionBuilder"/> for endpoints associated with the connections.</returns>
         /// <returns>An <see cref="HubEndpointConventionBuilder"/> for endpoints associated with the connections.</returns>
-        public static HubEndpointConventionBuilder MapHub<[DynamicallyAccessedMembers(HubAccessibility)]THub>(this IEndpointRouteBuilder endpoints, string pattern, Action<HttpConnectionDispatcherOptions> configureOptions) where THub : Hub
+        public static HubEndpointConventionBuilder MapHub<[DynamicallyAccessedMembers(HubAccessibility)]THub>(this IEndpointRouteBuilder endpoints, string pattern, Action<HttpConnectionDispatcherOptions>? configureOptions) where THub : Hub
         {
         {
             var marker = endpoints.ServiceProvider.GetService<SignalRMarkerService>();
             var marker = endpoints.ServiceProvider.GetService<SignalRMarkerService>();
 
 

+ 1 - 0
src/SignalR/server/SignalR/src/Microsoft.AspNetCore.SignalR.csproj

@@ -4,6 +4,7 @@
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
     <IsPackable>false</IsPackable>
     <IsPackable>false</IsPackable>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 16 - 0
src/SignalR/server/SignalR/src/PublicAPI.Unshipped.txt

@@ -1 +1,17 @@
 #nullable enable
 #nullable enable
+*REMOVED*~static Microsoft.Extensions.DependencyInjection.SignalRDependencyInjectionExtensions.AddHubOptions<THub>(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder signalrBuilder, System.Action<Microsoft.AspNetCore.SignalR.HubOptions<THub>> configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder
+*REMOVED*~static Microsoft.Extensions.DependencyInjection.SignalRDependencyInjectionExtensions.AddSignalR(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder
+*REMOVED*~static Microsoft.Extensions.DependencyInjection.SignalRDependencyInjectionExtensions.AddSignalR(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<Microsoft.AspNetCore.SignalR.HubOptions> configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder
+*REMOVED*~static Microsoft.AspNetCore.SignalR.GetHttpContextExtensions.GetHttpContext(this Microsoft.AspNetCore.SignalR.HubCallerContext connection) -> Microsoft.AspNetCore.Http.HttpContext
+*REMOVED*~static Microsoft.AspNetCore.SignalR.GetHttpContextExtensions.GetHttpContext(this Microsoft.AspNetCore.SignalR.HubConnectionContext connection) -> Microsoft.AspNetCore.Http.HttpContext
+*REMOVED*~static Microsoft.AspNetCore.Builder.HubEndpointRouteBuilderExtensions.MapHub<THub>(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern) -> Microsoft.AspNetCore.Builder.HubEndpointConventionBuilder
+*REMOVED*~static Microsoft.AspNetCore.Builder.HubEndpointRouteBuilderExtensions.MapHub<THub>(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, System.Action<Microsoft.AspNetCore.Http.Connections.HttpConnectionDispatcherOptions> configureOptions) -> Microsoft.AspNetCore.Builder.HubEndpointConventionBuilder
+*REMOVED*~Microsoft.AspNetCore.Builder.HubEndpointConventionBuilder.Add(System.Action<Microsoft.AspNetCore.Builder.EndpointBuilder> convention) -> void
+static Microsoft.Extensions.DependencyInjection.SignalRDependencyInjectionExtensions.AddHubOptions<THub>(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder! signalrBuilder, System.Action<Microsoft.AspNetCore.SignalR.HubOptions<THub!>!>! configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder!
+static Microsoft.Extensions.DependencyInjection.SignalRDependencyInjectionExtensions.AddSignalR(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder!
+static Microsoft.Extensions.DependencyInjection.SignalRDependencyInjectionExtensions.AddSignalR(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<Microsoft.AspNetCore.SignalR.HubOptions!>! configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder!
+static Microsoft.AspNetCore.SignalR.GetHttpContextExtensions.GetHttpContext(this Microsoft.AspNetCore.SignalR.HubCallerContext! connection) -> Microsoft.AspNetCore.Http.HttpContext?
+static Microsoft.AspNetCore.SignalR.GetHttpContextExtensions.GetHttpContext(this Microsoft.AspNetCore.SignalR.HubConnectionContext! connection) -> Microsoft.AspNetCore.Http.HttpContext?
+static Microsoft.AspNetCore.Builder.HubEndpointRouteBuilderExtensions.MapHub<THub>(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! pattern) -> Microsoft.AspNetCore.Builder.HubEndpointConventionBuilder!
+static Microsoft.AspNetCore.Builder.HubEndpointRouteBuilderExtensions.MapHub<THub>(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! pattern, System.Action<Microsoft.AspNetCore.Http.Connections.HttpConnectionDispatcherOptions!>? configureOptions) -> Microsoft.AspNetCore.Builder.HubEndpointConventionBuilder!
+Microsoft.AspNetCore.Builder.HubEndpointConventionBuilder.Add(System.Action<Microsoft.AspNetCore.Builder.EndpointBuilder!>! convention) -> void

+ 1 - 1
src/SignalR/server/StackExchangeRedis/src/Internal/AckHandler.cs

@@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis.Internal
 
 
         public AckHandler()
         public AckHandler()
         {
         {
-            _timer = NonCapturingTimer.Create(state => ((AckHandler)state).CheckAcks(), state: this, dueTime: _ackInterval, period: _ackInterval);
+            _timer = NonCapturingTimer.Create(state => ((AckHandler)state!).CheckAcks(), state: this, dueTime: _ackInterval, period: _ackInterval);
         }
         }
 
 
         public Task CreateAck(int id)
         public Task CreateAck(int id)

+ 1 - 1
src/SignalR/server/StackExchangeRedis/src/Internal/DefaultHubMessageSerializer.cs

@@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
     {
     {
         private readonly List<IHubProtocol> _hubProtocols;
         private readonly List<IHubProtocol> _hubProtocols;
 
 
-        public DefaultHubMessageSerializer(IHubProtocolResolver hubProtocolResolver, IList<string> globalSupportedProtocols, IList<string> hubSupportedProtocols)
+        public DefaultHubMessageSerializer(IHubProtocolResolver hubProtocolResolver, IList<string>? globalSupportedProtocols, IList<string>? hubSupportedProtocols)
         {
         {
             var supportedProtocols = hubSupportedProtocols ?? globalSupportedProtocols ?? Array.Empty<string>();
             var supportedProtocols = hubSupportedProtocols ?? globalSupportedProtocols ?? Array.Empty<string>();
             _hubProtocols = new List<IHubProtocol>(supportedProtocols.Count);
             _hubProtocols = new List<IHubProtocol>(supportedProtocols.Count);

+ 2 - 9
src/SignalR/server/StackExchangeRedis/src/Internal/RedisInvocation.cs

@@ -12,24 +12,17 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis.Internal
         /// Gets a list of connections that should be excluded from this invocation.
         /// Gets a list of connections that should be excluded from this invocation.
         /// May be null to indicate that no connections are to be excluded.
         /// May be null to indicate that no connections are to be excluded.
         /// </summary>
         /// </summary>
-        public IReadOnlyList<string> ExcludedConnectionIds { get; }
+        public IReadOnlyList<string>? ExcludedConnectionIds { get; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the message serialization cache containing serialized payloads for the message.
         /// Gets the message serialization cache containing serialized payloads for the message.
         /// </summary>
         /// </summary>
         public SerializedHubMessage Message { get; }
         public SerializedHubMessage Message { get; }
 
 
-        public RedisInvocation(SerializedHubMessage message, IReadOnlyList<string> excludedConnectionIds)
+        public RedisInvocation(SerializedHubMessage message, IReadOnlyList<string>? excludedConnectionIds)
         {
         {
             Message = message;
             Message = message;
             ExcludedConnectionIds = excludedConnectionIds;
             ExcludedConnectionIds = excludedConnectionIds;
         }
         }
-
-        public static RedisInvocation Create(string target, object[] arguments, IReadOnlyList<string> excludedConnectionIds = null)
-        {
-            return new RedisInvocation(
-                new SerializedHubMessage(new InvocationMessage(target, null, arguments)),
-                excludedConnectionIds);
-        }
     }
     }
 }
 }

+ 9 - 9
src/SignalR/server/StackExchangeRedis/src/Internal/RedisLog.cs

@@ -12,28 +12,28 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis.Internal
     // We'd end up creating separate instances of all the LoggerMessage.Define values for each Hub.
     // We'd end up creating separate instances of all the LoggerMessage.Define values for each Hub.
     internal static class RedisLog
     internal static class RedisLog
     {
     {
-        private static readonly Action<ILogger, string, string, Exception> _connectingToEndpoints =
+        private static readonly Action<ILogger, string, string, Exception?> _connectingToEndpoints =
             LoggerMessage.Define<string, string>(LogLevel.Information, new EventId(1, "ConnectingToEndpoints"), "Connecting to Redis endpoints: {Endpoints}. Using Server Name: {ServerName}");
             LoggerMessage.Define<string, string>(LogLevel.Information, new EventId(1, "ConnectingToEndpoints"), "Connecting to Redis endpoints: {Endpoints}. Using Server Name: {ServerName}");
 
 
-        private static readonly Action<ILogger, Exception> _connected =
+        private static readonly Action<ILogger, Exception?> _connected =
             LoggerMessage.Define(LogLevel.Information, new EventId(2, "Connected"), "Connected to Redis.");
             LoggerMessage.Define(LogLevel.Information, new EventId(2, "Connected"), "Connected to Redis.");
 
 
-        private static readonly Action<ILogger, string, Exception> _subscribing =
+        private static readonly Action<ILogger, string, Exception?> _subscribing =
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(3, "Subscribing"), "Subscribing to channel: {Channel}.");
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(3, "Subscribing"), "Subscribing to channel: {Channel}.");
 
 
-        private static readonly Action<ILogger, string, Exception> _receivedFromChannel =
+        private static readonly Action<ILogger, string, Exception?> _receivedFromChannel =
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(4, "ReceivedFromChannel"), "Received message from Redis channel {Channel}.");
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(4, "ReceivedFromChannel"), "Received message from Redis channel {Channel}.");
 
 
-        private static readonly Action<ILogger, string, Exception> _publishToChannel =
+        private static readonly Action<ILogger, string, Exception?> _publishToChannel =
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(5, "PublishToChannel"), "Publishing message to Redis channel {Channel}.");
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(5, "PublishToChannel"), "Publishing message to Redis channel {Channel}.");
 
 
-        private static readonly Action<ILogger, string, Exception> _unsubscribe =
+        private static readonly Action<ILogger, string, Exception?> _unsubscribe =
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(6, "Unsubscribe"), "Unsubscribing from channel: {Channel}.");
             LoggerMessage.Define<string>(LogLevel.Trace, new EventId(6, "Unsubscribe"), "Unsubscribing from channel: {Channel}.");
 
 
-        private static readonly Action<ILogger, Exception> _notConnected =
+        private static readonly Action<ILogger, Exception?> _notConnected =
             LoggerMessage.Define(LogLevel.Error, new EventId(7, "Connected"), "Not connected to Redis.");
             LoggerMessage.Define(LogLevel.Error, new EventId(7, "Connected"), "Not connected to Redis.");
 
 
-        private static readonly Action<ILogger, Exception> _connectionRestored =
+        private static readonly Action<ILogger, Exception?> _connectionRestored =
             LoggerMessage.Define(LogLevel.Information, new EventId(8, "ConnectionRestored"), "Connection to Redis restored.");
             LoggerMessage.Define(LogLevel.Information, new EventId(8, "ConnectionRestored"), "Connection to Redis restored.");
 
 
         private static readonly Action<ILogger, Exception> _connectionFailed =
         private static readonly Action<ILogger, Exception> _connectionFailed =
@@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis.Internal
         }
         }
 
 
         // This isn't DefineMessage-based because it's just the simple TextWriter logging from ConnectionMultiplexer
         // This isn't DefineMessage-based because it's just the simple TextWriter logging from ConnectionMultiplexer
-        public static void ConnectionMultiplexerMessage(ILogger logger, string message)
+        public static void ConnectionMultiplexerMessage(ILogger logger, string? message)
         {
         {
             if (logger.IsEnabled(LogLevel.Debug))
             if (logger.IsEnabled(LogLevel.Debug))
             {
             {

+ 3 - 3
src/SignalR/server/StackExchangeRedis/src/Internal/RedisProtocol.cs

@@ -34,10 +34,10 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis.Internal
         // * The "Length prefixed string" is the string format used by BinaryReader/BinaryWriter:
         // * The "Length prefixed string" is the string format used by BinaryReader/BinaryWriter:
         //   * A 7-bit variable length integer encodes the length in bytes, followed by the encoded string in UTF-8.
         //   * A 7-bit variable length integer encodes the length in bytes, followed by the encoded string in UTF-8.
 
 
-        public byte[] WriteInvocation(string methodName, object[] args) =>
+        public byte[] WriteInvocation(string methodName, object?[] args) =>
             WriteInvocation(methodName, args, excludedConnectionIds: null);
             WriteInvocation(methodName, args, excludedConnectionIds: null);
 
 
-        public byte[] WriteInvocation(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds)
+        public byte[] WriteInvocation(string methodName, object?[] args, IReadOnlyList<string>? excludedConnectionIds)
         {
         {
             // Written as a MessagePack 'arr' containing at least these items:
             // Written as a MessagePack 'arr' containing at least these items:
             // * A MessagePack 'arr' of 'str's representing the excluded ids
             // * A MessagePack 'arr' of 'str's representing the excluded ids
@@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis.Internal
             ValidateArraySize(ref reader, 2, "Invocation");
             ValidateArraySize(ref reader, 2, "Invocation");
 
 
             // Read excluded Ids
             // Read excluded Ids
-            IReadOnlyList<string> excludedConnectionIds = null;
+            IReadOnlyList<string>? excludedConnectionIds = null;
             var idCount = reader.ReadArrayHeader();
             var idCount = reader.ReadArrayHeader();
             if (idCount > 0)
             if (idCount > 0)
             {
             {

+ 1 - 0
src/SignalR/server/StackExchangeRedis/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj

@@ -3,6 +3,7 @@
   <PropertyGroup>
   <PropertyGroup>
     <Description>Provides scale-out support for ASP.NET Core SignalR using a Redis server and the StackExchange.Redis client.</Description>
     <Description>Provides scale-out support for ASP.NET Core SignalR using a Redis server and the StackExchange.Redis client.</Description>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 46 - 0
src/SignalR/server/StackExchangeRedis/src/PublicAPI.Unshipped.txt

@@ -1 +1,47 @@
 #nullable enable
 #nullable enable
+*REMOVED*~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.RedisHubLifetimeManager(Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>> logger, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions> options, Microsoft.AspNetCore.SignalR.IHubProtocolResolver hubProtocolResolver) -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.RedisHubLifetimeManager(Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>> logger, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions> options, Microsoft.AspNetCore.SignalR.IHubProtocolResolver hubProtocolResolver, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.HubOptions> globalHubOptions, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.HubOptions<THub>> hubOptions) -> void
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.OnConnectedAsync(Microsoft.AspNetCore.SignalR.HubConnectionContext connection) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.OnDisconnectedAsync(Microsoft.AspNetCore.SignalR.HubConnectionContext connection) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendAllAsync(string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendAllExceptAsync(string methodName, object[] args, System.Collections.Generic.IReadOnlyList<string> excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendConnectionAsync(string connectionId, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendConnectionsAsync(System.Collections.Generic.IReadOnlyList<string> connectionIds, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendGroupAsync(string groupName, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendGroupExceptAsync(string groupName, string methodName, object[] args, System.Collections.Generic.IReadOnlyList<string> excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendGroupsAsync(System.Collections.Generic.IReadOnlyList<string> groupNames, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendUserAsync(string userId, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendUsersAsync(System.Collections.Generic.IReadOnlyList<string> userIds, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.AddToGroupAsync(string connectionId, string groupName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.RemoveFromGroupAsync(string connectionId, string groupName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+*REMOVED*~static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder signalrBuilder) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder
+*REMOVED*~static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder signalrBuilder, System.Action<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions> configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder
+*REMOVED*~static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder signalrBuilder, string redisConnectionString) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder
+*REMOVED*~static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder signalrBuilder, string redisConnectionString, System.Action<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions> configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder
+*REMOVED*~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.Configuration.get -> StackExchange.Redis.ConfigurationOptions
+*REMOVED*~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.Configuration.set -> void
+*REMOVED*~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.ConnectionFactory.get -> System.Func<System.IO.TextWriter, System.Threading.Tasks.Task<StackExchange.Redis.IConnectionMultiplexer>>
+*REMOVED*~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.ConnectionFactory.set -> void
+~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.RedisHubLifetimeManager(Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub!>!>! logger, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions!>! options, Microsoft.AspNetCore.SignalR.IHubProtocolResolver! hubProtocolResolver) -> void
+~Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.RedisHubLifetimeManager(Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub!>!>! logger, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions!>! options, Microsoft.AspNetCore.SignalR.IHubProtocolResolver! hubProtocolResolver, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.HubOptions!>? globalHubOptions, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.HubOptions<THub!>!>? hubOptions) -> void
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.OnConnectedAsync(Microsoft.AspNetCore.SignalR.HubConnectionContext! connection) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.OnDisconnectedAsync(Microsoft.AspNetCore.SignalR.HubConnectionContext! connection) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendAllAsync(string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendAllExceptAsync(string! methodName, object?[]! args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendConnectionAsync(string! connectionId, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendConnectionsAsync(System.Collections.Generic.IReadOnlyList<string!>! connectionIds, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendGroupAsync(string! groupName, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendGroupExceptAsync(string! groupName, string! methodName, object?[]! args, System.Collections.Generic.IReadOnlyList<string!>! excludedConnectionIds, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendGroupsAsync(System.Collections.Generic.IReadOnlyList<string!>! groupNames, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendUserAsync(string! userId, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.SendUsersAsync(System.Collections.Generic.IReadOnlyList<string!>! userIds, string! methodName, object?[]! args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.AddToGroupAsync(string! connectionId, string! groupName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+override Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisHubLifetimeManager<THub>.RemoveFromGroupAsync(string! connectionId, string! groupName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder! signalrBuilder) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder!
+static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder! signalrBuilder, System.Action<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions!>! configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder!
+static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder! signalrBuilder, string! redisConnectionString) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder!
+static Microsoft.Extensions.DependencyInjection.StackExchangeRedisDependencyInjectionExtensions.AddStackExchangeRedis(this Microsoft.AspNetCore.SignalR.ISignalRServerBuilder! signalrBuilder, string! redisConnectionString, System.Action<Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions!>! configure) -> Microsoft.AspNetCore.SignalR.ISignalRServerBuilder!
+Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.Configuration.get -> StackExchange.Redis.ConfigurationOptions!
+Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.Configuration.set -> void
+Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.ConnectionFactory.get -> System.Func<System.IO.TextWriter!, System.Threading.Tasks.Task<StackExchange.Redis.IConnectionMultiplexer!>!>?
+Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions.ConnectionFactory.set -> void

Неке датотеке нису приказане због велике количине промена