Browse Source

Target netstandard2.1 for SignalR client (#10540)

Brennan 6 years ago
parent
commit
f989daca4b
28 changed files with 599 additions and 90 deletions
  1. 1 0
      eng/Dependencies.props
  2. 8 0
      eng/SharedFramework.External.props
  3. 4 0
      eng/Version.Details.xml
  4. 1 0
      eng/Versions.props
  5. 8 1
      src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.csproj
  6. 3 5
      src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs
  7. 219 0
      src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.1.cs
  8. 2 1
      src/Servers/Connections.Abstractions/src/ConnectionContext.cs
  9. 0 6
      src/Servers/Connections.Abstractions/src/DefaultConnectionContext.cs
  10. 2 3
      src/Servers/Connections.Abstractions/src/IConnectionListener.cs
  11. 5 1
      src/Servers/Connections.Abstractions/src/Microsoft.AspNetCore.Connections.Abstractions.csproj
  12. 1 1
      src/Servers/Kestrel/build.sh
  13. 4 3
      src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.csproj
  14. 12 0
      src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.0.cs
  15. 184 0
      src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.1.cs
  16. 2 9
      src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs
  17. 0 5
      src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.StreamAsync.cs
  18. 6 2
      src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj
  19. 3 3
      src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.csproj
  20. 93 0
      src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.1.cs
  21. 6 11
      src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
  22. 7 4
      src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
  23. 1 1
      src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj
  24. 1 1
      src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj
  25. 1 12
      src/SignalR/common/Http.Connections/src/Internal/Transports/WebSocketsTransport.cs
  26. 15 2
      src/SignalR/common/Shared/AsyncEnumerableAdapters.cs
  27. 0 4
      src/SignalR/common/Shared/ReflectionHelper.cs
  28. 10 15
      src/SignalR/common/testassets/Tests.Utils/TestHelpers.cs

+ 1 - 0
eng/Dependencies.props

@@ -42,6 +42,7 @@ and are generated based on the last package release.
     <LatestPackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
     <LatestPackageReference Include="Microsoft.Azure.KeyVault" Version="$(MicrosoftAzureKeyVaultPackageVersion)" />
     <LatestPackageReference Include="Microsoft.Azure.Storage.Blob" Version="$(MicrosoftAzureStorageBlobPackageVersion)" />
+    <LatestPackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="$(MicrosoftBclAsyncInterfacesPackageVersion)" />
     <LatestPackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkPackageVersion)" />
     <LatestPackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCorePackageVersion)" />
     <LatestPackageReference Include="Microsoft.CodeAnalysis.Common" Version="$(MicrosoftCodeAnalysisCommonPackageVersion)" />

+ 8 - 0
eng/SharedFramework.External.props

@@ -78,6 +78,14 @@
     <ExternalAspNetCoreAppReference Include="@(_TransitiveExternalAspNetCoreAppReference)" />
   </ItemGroup>
 
+  <!--
+    This compilation reference is necessary to compile netstandard2.0 assemblies that need IAsyncEnumerable and IAsyncDisposable and the assembly is also in the shared framework.
+    This reference is part of Microsoft.NETCore.App, so is listed here as a reference to be used during compilation only.
+  -->
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <_CompilationOnlyReference Include="Microsoft.Bcl.AsyncInterfaces" />
+  </ItemGroup>
+
   <!--
     These compilation references are necessary to compile netstandard2.0 assemblies which are in the shared framework.
     This references are part of Microsoft.NETCore.App, so are listed here as references to be used during compilation only.

+ 4 - 0
eng/Version.Details.xml

@@ -293,6 +293,10 @@
       <Uri>https://github.com/aspnet/Extensions</Uri>
       <Sha>3e7f99fbe3c5e775f5c175238eed87523782fe13</Sha>
     </Dependency>
+    <Dependency Name="Microsoft.Bcl.AsyncInterfaces" Version="1.0.0-preview7.19309.5" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
+      <Uri>https://github.com/dotnet/corefx</Uri>
+      <Sha>7e56d8bd8b224d834b782a98bfd7035f71c3f547</Sha>
+    </Dependency>
     <Dependency Name="Microsoft.CSharp" Version="4.6.0-preview7.19309.5" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
       <Uri>https://github.com/dotnet/corefx</Uri>
       <Sha>7e56d8bd8b224d834b782a98bfd7035f71c3f547</Sha>

+ 1 - 0
eng/Versions.props

@@ -59,6 +59,7 @@
     <MicrosoftNETCoreAppRuntimewinx64PackageVersion>3.0.0-preview7-27810-02</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
     <NETStandardLibraryRefPackageVersion>2.1.0-preview7-27810-02</NETStandardLibraryRefPackageVersion>
     <!-- Packages from dotnet/corefx -->
+    <MicrosoftBclAsyncInterfacesPackageVersion>1.0.0-preview7.19309.5</MicrosoftBclAsyncInterfacesPackageVersion>
     <MicrosoftCSharpPackageVersion>4.6.0-preview7.19309.5</MicrosoftCSharpPackageVersion>
     <MicrosoftWin32RegistryPackageVersion>4.6.0-preview7.19309.5</MicrosoftWin32RegistryPackageVersion>
     <SystemComponentModelAnnotationsPackageVersion>4.6.0-preview7.19309.5</SystemComponentModelAnnotationsPackageVersion>

+ 8 - 1
src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.csproj

@@ -1,12 +1,19 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netstandard2.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
     <Compile Include="Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.Http.Features"  />
     <Reference Include="Microsoft.Extensions.ActivatorUtilities.Sources"  />
     <Reference Include="System.IO.Pipelines"  />
+    <Reference Include="Microsoft.Bcl.AsyncInterfaces"  />
+  </ItemGroup>
+<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
+    <Compile Include="Microsoft.AspNetCore.Connections.Abstractions.netstandard2.1.cs" />
+    <Reference Include="Microsoft.AspNetCore.Http.Features"  />
+    <Reference Include="Microsoft.Extensions.ActivatorUtilities.Sources"  />
+    <Reference Include="System.IO.Pipelines"  />
   </ItemGroup>
 </Project>

+ 3 - 5
src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs

@@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Connections
         public static Microsoft.AspNetCore.Connections.IConnectionBuilder Use(this Microsoft.AspNetCore.Connections.IConnectionBuilder connectionBuilder, System.Func<Microsoft.AspNetCore.Connections.ConnectionContext, System.Func<System.Threading.Tasks.Task>, System.Threading.Tasks.Task> middleware) { throw null; }
         public static Microsoft.AspNetCore.Connections.IConnectionBuilder UseConnectionHandler<TConnectionHandler>(this Microsoft.AspNetCore.Connections.IConnectionBuilder connectionBuilder) where TConnectionHandler : Microsoft.AspNetCore.Connections.ConnectionHandler { throw null; }
     }
-    public abstract partial class ConnectionContext
+    public abstract partial class ConnectionContext : System.IAsyncDisposable
     {
         protected ConnectionContext() { }
         public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
@@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Connections
         public ConnectionResetException(string message) { }
         public ConnectionResetException(string message, System.Exception inner) { }
     }
-    public partial class DefaultConnectionContext : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionEndPointFeature, Microsoft.AspNetCore.Connections.Features.IConnectionIdFeature, Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature, Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature, Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature, Microsoft.AspNetCore.Connections.Features.IConnectionUserFeature, System.IDisposable
+    public partial class DefaultConnectionContext : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionEndPointFeature, Microsoft.AspNetCore.Connections.Features.IConnectionIdFeature, Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature, Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature, Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature, Microsoft.AspNetCore.Connections.Features.IConnectionUserFeature
     {
         public DefaultConnectionContext() { }
         public DefaultConnectionContext(string id) { }
@@ -89,7 +89,6 @@ namespace Microsoft.AspNetCore.Connections
         public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
         public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
         public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { }
-        public void Dispose() { }
         public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
     }
     public partial class FileHandleEndPoint : System.Net.EndPoint
@@ -110,11 +109,10 @@ namespace Microsoft.AspNetCore.Connections
         Microsoft.AspNetCore.Connections.ConnectionDelegate Build();
         Microsoft.AspNetCore.Connections.IConnectionBuilder Use(System.Func<Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Connections.ConnectionDelegate> middleware);
     }
-    public partial interface IConnectionListener
+    public partial interface IConnectionListener : System.IAsyncDisposable
     {
         System.Net.EndPoint EndPoint { get; }
         System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> AcceptAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
-        System.Threading.Tasks.ValueTask DisposeAsync();
         System.Threading.Tasks.ValueTask UnbindAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
     }
     public partial interface IConnectionListenerFactory

+ 219 - 0
src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.1.cs

@@ -0,0 +1,219 @@
+// 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.
+
+namespace Microsoft.AspNetCore.Connections
+{
+    public partial class AddressInUseException : System.InvalidOperationException
+    {
+        public AddressInUseException(string message) { }
+        public AddressInUseException(string message, System.Exception inner) { }
+    }
+    public partial class ConnectionAbortedException : System.OperationCanceledException
+    {
+        public ConnectionAbortedException() { }
+        public ConnectionAbortedException(string message) { }
+        public ConnectionAbortedException(string message, System.Exception inner) { }
+    }
+    public partial class ConnectionBuilder : Microsoft.AspNetCore.Connections.IConnectionBuilder
+    {
+        public ConnectionBuilder(System.IServiceProvider applicationServices) { }
+        public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public Microsoft.AspNetCore.Connections.ConnectionDelegate Build() { throw null; }
+        public Microsoft.AspNetCore.Connections.IConnectionBuilder Use(System.Func<Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Connections.ConnectionDelegate> middleware) { throw null; }
+    }
+    public static partial class ConnectionBuilderExtensions
+    {
+        public static Microsoft.AspNetCore.Connections.IConnectionBuilder Run(this Microsoft.AspNetCore.Connections.IConnectionBuilder connectionBuilder, System.Func<Microsoft.AspNetCore.Connections.ConnectionContext, System.Threading.Tasks.Task> middleware) { throw null; }
+        public static Microsoft.AspNetCore.Connections.IConnectionBuilder Use(this Microsoft.AspNetCore.Connections.IConnectionBuilder connectionBuilder, System.Func<Microsoft.AspNetCore.Connections.ConnectionContext, System.Func<System.Threading.Tasks.Task>, System.Threading.Tasks.Task> middleware) { throw null; }
+        public static Microsoft.AspNetCore.Connections.IConnectionBuilder UseConnectionHandler<TConnectionHandler>(this Microsoft.AspNetCore.Connections.IConnectionBuilder connectionBuilder) where TConnectionHandler : Microsoft.AspNetCore.Connections.ConnectionHandler { throw null; }
+    }
+    public abstract partial class ConnectionContext : System.IAsyncDisposable
+    {
+        protected ConnectionContext() { }
+        public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public abstract string ConnectionId { get; set; }
+        public abstract Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get; }
+        public abstract System.Collections.Generic.IDictionary<object, object> Items { get; set; }
+        public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public abstract System.IO.Pipelines.IDuplexPipe Transport { get; set; }
+        public virtual void Abort() { }
+        public virtual void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { }
+        public virtual System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
+    }
+    public delegate System.Threading.Tasks.Task ConnectionDelegate(Microsoft.AspNetCore.Connections.ConnectionContext connection);
+    public abstract partial class ConnectionHandler
+    {
+        protected ConnectionHandler() { }
+        public abstract System.Threading.Tasks.Task OnConnectedAsync(Microsoft.AspNetCore.Connections.ConnectionContext connection);
+    }
+    public partial class ConnectionItems : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<object, object>>, System.Collections.Generic.IDictionary<object, object>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<object, object>>, System.Collections.IEnumerable
+    {
+        public ConnectionItems() { }
+        public ConnectionItems(System.Collections.Generic.IDictionary<object, object> items) { }
+        public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        int System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Count { get { throw null; } }
+        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.IsReadOnly { get { throw null; } }
+        object System.Collections.Generic.IDictionary<System.Object,System.Object>.this[object key] { get { throw null; } set { } }
+        System.Collections.Generic.ICollection<object> System.Collections.Generic.IDictionary<System.Object,System.Object>.Keys { get { throw null; } }
+        System.Collections.Generic.ICollection<object> System.Collections.Generic.IDictionary<System.Object,System.Object>.Values { get { throw null; } }
+        void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Add(System.Collections.Generic.KeyValuePair<object, object> item) { }
+        void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Clear() { }
+        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Contains(System.Collections.Generic.KeyValuePair<object, object> item) { throw null; }
+        void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.CopyTo(System.Collections.Generic.KeyValuePair<object, object>[] array, int arrayIndex) { }
+        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Remove(System.Collections.Generic.KeyValuePair<object, object> item) { throw null; }
+        void System.Collections.Generic.IDictionary<System.Object,System.Object>.Add(object key, object value) { }
+        bool System.Collections.Generic.IDictionary<System.Object,System.Object>.ContainsKey(object key) { throw null; }
+        bool System.Collections.Generic.IDictionary<System.Object,System.Object>.Remove(object key) { throw null; }
+        bool System.Collections.Generic.IDictionary<System.Object,System.Object>.TryGetValue(object key, out object value) { throw null; }
+        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<object, object>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.GetEnumerator() { throw null; }
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
+    }
+    public partial class ConnectionResetException : System.IO.IOException
+    {
+        public ConnectionResetException(string message) { }
+        public ConnectionResetException(string message, System.Exception inner) { }
+    }
+    public partial class DefaultConnectionContext : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionEndPointFeature, Microsoft.AspNetCore.Connections.Features.IConnectionIdFeature, Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature, Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature, Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature, Microsoft.AspNetCore.Connections.Features.IConnectionUserFeature
+    {
+        public DefaultConnectionContext() { }
+        public DefaultConnectionContext(string id) { }
+        public DefaultConnectionContext(string id, System.IO.Pipelines.IDuplexPipe transport, System.IO.Pipelines.IDuplexPipe application) { }
+        public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { }
+        public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
+    }
+    public partial class FileHandleEndPoint : System.Net.EndPoint
+    {
+        public FileHandleEndPoint(ulong fileHandle, Microsoft.AspNetCore.Connections.FileHandleType fileHandleType) { }
+        public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+    }
+    public enum FileHandleType
+    {
+        Auto = 0,
+        Tcp = 1,
+        Pipe = 2,
+    }
+    public partial interface IConnectionBuilder
+    {
+        System.IServiceProvider ApplicationServices { get; }
+        Microsoft.AspNetCore.Connections.ConnectionDelegate Build();
+        Microsoft.AspNetCore.Connections.IConnectionBuilder Use(System.Func<Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Connections.ConnectionDelegate> middleware);
+    }
+    public partial interface IConnectionListener : System.IAsyncDisposable
+    {
+        System.Net.EndPoint EndPoint { get; }
+        System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> AcceptAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+        System.Threading.Tasks.ValueTask UnbindAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+    }
+    public partial interface IConnectionListenerFactory
+    {
+        System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.IConnectionListener> BindAsync(System.Net.EndPoint endpoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+    }
+    [System.FlagsAttribute]
+    public enum TransferFormat
+    {
+        Binary = 1,
+        Text = 2,
+    }
+    public abstract partial class TransportConnection : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionIdFeature, Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature, Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature, Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature, Microsoft.AspNetCore.Connections.Features.IMemoryPoolFeature, Microsoft.AspNetCore.Http.Features.IFeatureCollection, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.Type, object>>, System.Collections.IEnumerable
+    {
+        public TransportConnection() { }
+        public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get { throw null; } }
+        public override System.Collections.Generic.IDictionary<object, object> Items { get { throw null; } set { } }
+        public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public virtual System.Buffers.MemoryPool<byte> MemoryPool { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        System.Collections.Generic.IDictionary<object, object> Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature.Items { get { throw null; } set { } }
+        System.Threading.CancellationToken Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature.ConnectionClosed { get { throw null; } set { } }
+        System.IO.Pipelines.IDuplexPipe Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature.Transport { get { throw null; } set { } }
+        System.Buffers.MemoryPool<byte> Microsoft.AspNetCore.Connections.Features.IMemoryPoolFeature.MemoryPool { get { throw null; } }
+        bool Microsoft.AspNetCore.Http.Features.IFeatureCollection.IsReadOnly { get { throw null; } }
+        object Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type key] { get { throw null; } set { } }
+        int Microsoft.AspNetCore.Http.Features.IFeatureCollection.Revision { get { throw null; } }
+        public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { }
+        void Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature.Abort() { }
+        TFeature Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get<TFeature>() { throw null; }
+        void Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set<TFeature>(TFeature feature) { }
+        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<System.Type, object>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.Type,System.Object>>.GetEnumerator() { throw null; }
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
+    }
+}
+namespace Microsoft.AspNetCore.Connections.Features
+{
+    public partial interface IConnectionCompleteFeature
+    {
+        void OnCompleted(System.Func<object, System.Threading.Tasks.Task> callback, object state);
+    }
+    public partial interface IConnectionEndPointFeature
+    {
+        System.Net.EndPoint LocalEndPoint { get; set; }
+        System.Net.EndPoint RemoteEndPoint { get; set; }
+    }
+    public partial interface IConnectionHeartbeatFeature
+    {
+        void OnHeartbeat(System.Action<object> action, object state);
+    }
+    public partial interface IConnectionIdFeature
+    {
+        string ConnectionId { get; set; }
+    }
+    public partial interface IConnectionInherentKeepAliveFeature
+    {
+        bool HasInherentKeepAlive { get; }
+    }
+    public partial interface IConnectionItemsFeature
+    {
+        System.Collections.Generic.IDictionary<object, object> Items { get; set; }
+    }
+    public partial interface IConnectionLifetimeFeature
+    {
+        System.Threading.CancellationToken ConnectionClosed { get; set; }
+        void Abort();
+    }
+    public partial interface IConnectionLifetimeNotificationFeature
+    {
+        System.Threading.CancellationToken ConnectionClosedRequested { get; set; }
+        void RequestClose();
+    }
+    public partial interface IConnectionTransportFeature
+    {
+        System.IO.Pipelines.IDuplexPipe Transport { get; set; }
+    }
+    public partial interface IConnectionUserFeature
+    {
+        System.Security.Claims.ClaimsPrincipal User { get; set; }
+    }
+    public partial interface IMemoryPoolFeature
+    {
+        System.Buffers.MemoryPool<byte> MemoryPool { get; }
+    }
+    public partial interface ITlsHandshakeFeature
+    {
+        System.Security.Authentication.CipherAlgorithmType CipherAlgorithm { get; }
+        int CipherStrength { get; }
+        System.Security.Authentication.HashAlgorithmType HashAlgorithm { get; }
+        int HashStrength { get; }
+        System.Security.Authentication.ExchangeAlgorithmType KeyExchangeAlgorithm { get; }
+        int KeyExchangeStrength { get; }
+        System.Security.Authentication.SslProtocols Protocol { get; }
+    }
+    public partial interface ITransferFormatFeature
+    {
+        Microsoft.AspNetCore.Connections.TransferFormat ActiveFormat { get; set; }
+        Microsoft.AspNetCore.Connections.TransferFormat SupportedFormats { get; }
+    }
+}

+ 2 - 1
src/Servers/Connections.Abstractions/src/ConnectionContext.cs

@@ -1,6 +1,7 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+using System;
 using System.Collections.Generic;
 using System.IO.Pipelines;
 using System.Net;
@@ -11,7 +12,7 @@ using Microsoft.AspNetCore.Http.Features;
 
 namespace Microsoft.AspNetCore.Connections
 {
-    public abstract class ConnectionContext
+    public abstract class ConnectionContext : IAsyncDisposable
     {
         public abstract string ConnectionId { get; set; }
 

+ 0 - 6
src/Servers/Connections.Abstractions/src/DefaultConnectionContext.cs

@@ -14,7 +14,6 @@ using Microsoft.AspNetCore.Http.Features;
 namespace Microsoft.AspNetCore.Connections
 {
     public class DefaultConnectionContext : ConnectionContext,
-                                            IDisposable,
                                             IConnectionIdFeature,
                                             IConnectionItemsFeature,
                                             IConnectionTransportFeature,
@@ -76,11 +75,6 @@ namespace Microsoft.AspNetCore.Connections
             ThreadPool.UnsafeQueueUserWorkItem(cts => ((CancellationTokenSource)cts).Cancel(), _connectionClosedTokenSource);
         }
 
-        public void Dispose()
-        {
-            _connectionClosedTokenSource.Dispose();
-        }
-
         public override ValueTask DisposeAsync()
         {
             _connectionClosedTokenSource.Dispose();

+ 2 - 3
src/Servers/Connections.Abstractions/src/IConnectionListener.cs

@@ -1,20 +1,19 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+using System;
 using System.Net;
 using System.Threading;
 using System.Threading.Tasks;
 
 namespace Microsoft.AspNetCore.Connections
 {
-    public interface IConnectionListener
+    public interface IConnectionListener : IAsyncDisposable
     {
         EndPoint EndPoint { get; }
 
         ValueTask<ConnectionContext> AcceptAsync(CancellationToken cancellationToken = default);
 
         ValueTask UnbindAsync(CancellationToken cancellationToken = default);
-
-        ValueTask DisposeAsync();
     }
 }

+ 5 - 1
src/Servers/Connections.Abstractions/src/Microsoft.AspNetCore.Connections.Abstractions.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <Description>Core components of ASP.NET Core networking protocol stack.</Description>
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore</PackageTags>
@@ -16,4 +16,8 @@
     <Reference Include="System.IO.Pipelines" />
   </ItemGroup>
 
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Reference Include="Microsoft.Bcl.AsyncInterfaces" />
+  </ItemGroup>
+
 </Project>

+ 1 - 1
src/Servers/Kestrel/build.sh

@@ -3,5 +3,5 @@
 set -euo pipefail
 
 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-repo_root="$DIR/../.."
+repo_root="$DIR/../../.."
 "$repo_root/build.sh" --all --projects "$DIR/**/*.*proj" "$@"

+ 4 - 3
src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.csproj

@@ -1,7 +1,7 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
     <Compile Include="Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.0.cs" />
@@ -10,9 +10,10 @@
     <Reference Include="Microsoft.Extensions.DependencyInjection"  />
     <Reference Include="Microsoft.Extensions.Logging"  />
     <Reference Include="System.Threading.Channels"  />
+    <Reference Include="Microsoft.Bcl.AsyncInterfaces"  />
   </ItemGroup>
-<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.SignalR.Client.Core.netcoreapp3.0.cs" />
+<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
+    <Compile Include="Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.1.cs" />
     <Reference Include="Microsoft.AspNetCore.SignalR.Common"  />
     <Reference Include="Microsoft.AspNetCore.SignalR.Protocols.Json"  />
     <Reference Include="Microsoft.Extensions.DependencyInjection"  />

+ 12 - 0
src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.0.cs

@@ -49,6 +49,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
         public System.Threading.Tasks.Task StopAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
         [System.Diagnostics.DebuggerStepThroughAttribute]
         public System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<object>> StreamAsChannelCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsyncCore<TResult>(string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
     }
     public partial class HubConnectionBuilder : Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder, Microsoft.AspNetCore.SignalR.ISignalRBuilder
     {
@@ -141,6 +142,17 @@ namespace Microsoft.AspNetCore.SignalR.Client
         public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
         [System.Diagnostics.DebuggerStepThroughAttribute]
         public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> StreamAsChannelCoreAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
     }
     public enum HubConnectionState
     {

+ 184 - 0
src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.1.cs

@@ -0,0 +1,184 @@
+// 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.
+
+namespace Microsoft.AspNetCore.Internal
+{
+    public static partial class AwaitableThreadPool
+    {
+        public static Microsoft.AspNetCore.Internal.AwaitableThreadPool.Awaitable Yield() { throw null; }
+        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Size=1)]
+        public readonly partial struct Awaitable : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion
+        {
+            public bool IsCompleted { get { throw null; } }
+            public Microsoft.AspNetCore.Internal.AwaitableThreadPool.Awaitable GetAwaiter() { throw null; }
+            public void GetResult() { }
+            public void OnCompleted(System.Action continuation) { }
+            public void UnsafeOnCompleted(System.Action continuation) { }
+        }
+    }
+}
+namespace Microsoft.AspNetCore.SignalR.Client
+{
+    public partial class HubConnection
+    {
+        public static readonly System.TimeSpan DefaultHandshakeTimeout;
+        public static readonly System.TimeSpan DefaultKeepAliveInterval;
+        public static readonly System.TimeSpan DefaultServerTimeout;
+        public HubConnection(Microsoft.AspNetCore.SignalR.Client.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
+        public HubConnection(Microsoft.AspNetCore.SignalR.Client.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
+        public HubConnection(Microsoft.AspNetCore.SignalR.Client.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy reconnectPolicy) { }
+        public string ConnectionId { get { throw null; } }
+        public System.TimeSpan HandshakeTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.TimeSpan ServerTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.SignalR.Client.HubConnectionState State { get { throw null; } }
+        public event System.Func<System.Exception, System.Threading.Tasks.Task> Closed { add { } remove { } }
+        public event System.Func<string, System.Threading.Tasks.Task> Reconnected { add { } remove { } }
+        public event System.Func<System.Exception, System.Threading.Tasks.Task> Reconnecting { add { } remove { } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task DisposeAsync() { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task<object> InvokeCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public System.IDisposable On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) { throw null; }
+        public void Remove(string methodName) { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task SendCoreAsync(string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StopAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<object>> StreamAsChannelCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsyncCore<TResult>(string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+    }
+    public partial class HubConnectionBuilder : Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder, Microsoft.AspNetCore.SignalR.ISignalRBuilder
+    {
+        public HubConnectionBuilder() { }
+        public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public Microsoft.AspNetCore.SignalR.Client.HubConnection Build() { throw null; }
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+        public override bool Equals(object obj) { throw null; }
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+        public override int GetHashCode() { throw null; }
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+        public new System.Type GetType() { throw null; }
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+        public override string ToString() { throw null; }
+    }
+    public static partial class HubConnectionBuilderExtensions
+    {
+        public static Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder ConfigureLogging(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.Action<Microsoft.Extensions.Logging.ILoggingBuilder> configureLogging) { throw null; }
+        public static Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder) { throw null; }
+        public static Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy retryPolicy) { throw null; }
+        public static Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder WithAutomaticReconnect(this Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder hubConnectionBuilder, System.TimeSpan[] reconnectDelays) { throw null; }
+    }
+    public static partial class HubConnectionExtensions
+    {
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task InvokeAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task<TResult> InvokeAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task InvokeCoreAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public static System.Threading.Tasks.Task<TResult> InvokeCoreAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.IDisposable On(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action handler) { throw null; }
+        public static System.IDisposable On(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<System.Threading.Tasks.Task> handler) { throw null; }
+        public static System.IDisposable On(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Type[] parameterTypes, System.Func<object[], System.Threading.Tasks.Task> handler) { throw null; }
+        public static System.IDisposable On<T1>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1> handler) { throw null; }
+        public static System.IDisposable On<T1>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, System.Threading.Tasks.Task> handler) { throw null; }
+        public static System.IDisposable On<T1, T2>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2> handler) { throw null; }
+        public static System.IDisposable On<T1, T2>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, System.Threading.Tasks.Task> handler) { throw null; }
+        public static System.IDisposable On<T1, T2, T3>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3> handler) { throw null; }
+        public static System.IDisposable On<T1, T2, T3>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Func<T1, T2, T3, System.Threading.Tasks.Task> handler) { throw null; }
+        public static System.IDisposable On<T1, T2, T3, T4>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3, T4> handler) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.IDisposable On<T1, T2, T3, T4, T5>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Action<T1, T2, T3, T4, T5> handler) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.IDisposable 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) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task 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)) { throw null; }
+        public static System.Threading.Tasks.Task SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, object arg3, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task SendAsync(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> 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)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> StreamAsChannelAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public static System.Threading.Tasks.Task<System.Threading.Channels.ChannelReader<TResult>> StreamAsChannelCoreAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> 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)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, object arg2, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, object arg1, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public static System.Collections.Generic.IAsyncEnumerable<TResult> StreamAsync<TResult>(this Microsoft.AspNetCore.SignalR.Client.HubConnection hubConnection, string methodName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+    }
+    public enum HubConnectionState
+    {
+        Disconnected = 0,
+        Connected = 1,
+        Connecting = 2,
+        Reconnecting = 3,
+    }
+    public partial interface IConnectionFactory
+    {
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Connections.ConnectionContext> ConnectAsync(Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+        System.Threading.Tasks.Task DisposeAsync(Microsoft.AspNetCore.Connections.ConnectionContext connection);
+    }
+    public partial interface IHubConnectionBuilder : Microsoft.AspNetCore.SignalR.ISignalRBuilder
+    {
+        Microsoft.AspNetCore.SignalR.Client.HubConnection Build();
+    }
+    public partial interface IRetryPolicy
+    {
+        System.TimeSpan? NextRetryDelay(Microsoft.AspNetCore.SignalR.Client.RetryContext retryContext);
+    }
+    public sealed partial class RetryContext
+    {
+        public RetryContext() { }
+        public System.TimeSpan ElapsedTime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public long PreviousRetryCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Exception RetryReason { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+}

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

@@ -49,9 +49,8 @@ namespace Microsoft.AspNetCore.SignalR.Client
         };
 
         private static readonly MethodInfo _sendStreamItemsMethod = typeof(HubConnection).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Single(m => m.Name.Equals(nameof(SendStreamItems)));
-#if NETCOREAPP3_0
         private static readonly MethodInfo _sendIAsyncStreamItemsMethod = typeof(HubConnection).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Single(m => m.Name.Equals(nameof(SendIAsyncEnumerableStreamItems)));
-#endif
+
         // Persistent across all connections
         private readonly ILoggerFactory _loggerFactory;
         private readonly ILogger _logger;
@@ -522,7 +521,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
             }
         }
 
-#if NETCOREAPP3_0
         /// <summary>
         /// Invokes a streaming hub method on the server using the specified method name, return type and arguments.
         /// </summary>
@@ -559,7 +557,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 cts.Dispose();
             }
         }
-#endif
 
         private async Task<ChannelReader<object>> StreamAsChannelCoreAsyncCore(string methodName, Type returnType, object[] args, CancellationToken cancellationToken)
         {
@@ -674,7 +671,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
                 // For each stream that needs to be sent, run a "send items" task in the background.
                 // This reads from the channel, attaches streamId, and sends to server.
                 // A single background thread here quickly gets messy.
-#if NETCOREAPP3_0
                 if (ReflectionHelper.IsIAsyncEnumerable(reader.GetType()))
                 {
                     _ = _sendIAsyncStreamItemsMethod
@@ -682,7 +678,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
                         .Invoke(this, new object[] { connectionState, kvp.Key.ToString(), reader, cancellationToken });
                     continue;
                 }
-#endif
                 _ = _sendStreamItemsMethod
                     .MakeGenericMethod(reader.GetType().GetGenericArguments())
                     .Invoke(this, new object[] { connectionState, kvp.Key.ToString(), reader, cancellationToken });
@@ -707,7 +702,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
             return CommonStreaming(connectionState, streamId, token, ReadChannelStream);
         }
 
-#if NETCOREAPP3_0
         // this is called via reflection using the `_sendIAsyncStreamItemsMethod` field
         private Task SendIAsyncEnumerableStreamItems<T>(ConnectionState connectionState, string streamId, IAsyncEnumerable<T> stream, CancellationToken token)
         {
@@ -724,7 +718,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
             return CommonStreaming(connectionState, streamId, token, ReadAsyncEnumerableStream);
         }
-#endif
 
         private async Task CommonStreaming(ConnectionState connectionState, string streamId, CancellationToken token, Func<CancellationTokenSource, Task> createAndConsumeStream)
         {
@@ -1445,7 +1438,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
 
         private OperationCanceledException GetOperationCanceledException(string message, Exception innerException, CancellationToken cancellationToken)
         {
-#if NETCOREAPP3_0
+#if NETSTANDARD2_1
             return new OperationCanceledException(message, innerException, _state.StopCts.Token);
 #else
             return new OperationCanceledException(message, innerException);

+ 0 - 5
src/SignalR/clients/csharp/Client.Core/src/HubConnectionExtensions.StreamAsync.cs

@@ -14,9 +14,6 @@ namespace Microsoft.AspNetCore.SignalR.Client
     /// </summary>
     public static partial class HubConnectionExtensions
     {
-
-#if NETCOREAPP3_0
-
         /// <summary>
         /// Invokes a streaming hub method on the server using the specified method name and return type.
         /// </summary>
@@ -236,7 +233,5 @@ namespace Microsoft.AspNetCore.SignalR.Client
         {
             return hubConnection.StreamAsyncCore<TResult>(methodName, new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }, cancellationToken);
         }
-#endif
-
     }
 }

+ 6 - 2
src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj

@@ -1,8 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <Description>Client for ASP.NET Core SignalR</Description>
-    <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
     <RootNamespace>Microsoft.AspNetCore.SignalR.Client</RootNamespace>
     <IsShippingPackage>true</IsShippingPackage>
   </PropertyGroup>
@@ -28,6 +28,10 @@
     <Reference Include="System.Threading.Channels" />
   </ItemGroup>
 
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Reference Include="Microsoft.Bcl.AsyncInterfaces" />
+  </ItemGroup>
+
   <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '3.0'">
     <!-- This dependency was replaced by Protocols.NewtonsoftJson between 3.0 and 2.2. This suppression can be removed after 3.0 is complete. -->
     <SuppressBaselineReference Include="Microsoft.AspNetCore.SignalR.Protocols.Json" />

+ 3 - 3
src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.csproj

@@ -1,15 +1,15 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
     <Compile Include="Microsoft.AspNetCore.Http.Connections.Client.netstandard2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.Http.Connections.Common"  />
     <Reference Include="Microsoft.Extensions.Logging.Abstractions"  />
   </ItemGroup>
-<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.Http.Connections.Client.netcoreapp3.0.cs" />
+<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
+    <Compile Include="Microsoft.AspNetCore.Http.Connections.Client.netstandard2.1.cs" />
     <Reference Include="Microsoft.AspNetCore.Http.Connections.Common"  />
     <Reference Include="Microsoft.Extensions.Logging.Abstractions"  />
   </ItemGroup>

+ 93 - 0
src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.1.cs

@@ -0,0 +1,93 @@
+// 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.
+
+namespace Microsoft.AspNetCore.Http.Connections.Client
+{
+    public partial class HttpConnection : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionInherentKeepAliveFeature
+    {
+        public HttpConnection(Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions httpConnectionOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
+        public HttpConnection(System.Uri url) { }
+        public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) { }
+        public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
+        public override string ConnectionId { get { throw null; } set { } }
+        public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        bool Microsoft.AspNetCore.Connections.Features.IConnectionInherentKeepAliveFeature.HasInherentKeepAlive { get { throw null; } }
+        public override System.IO.Pipelines.IDuplexPipe Transport { get { throw null; } set { } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StartAsync(Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        public System.Threading.Tasks.Task StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+    }
+    public partial class HttpConnectionOptions
+    {
+        public HttpConnectionOptions() { }
+        public System.Func<System.Threading.Tasks.Task<string>> AccessTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw null; } set { } }
+        public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Net.CookieContainer Cookies { get { throw null; } set { } }
+        public System.Net.ICredentials Credentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Collections.Generic.IDictionary<string, string> Headers { get { throw null; } set { } }
+        public System.Func<System.Net.Http.HttpMessageHandler, System.Net.Http.HttpMessageHandler> HttpMessageHandlerFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Net.IWebProxy Proxy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool SkipNegotiation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Uri Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool? UseDefaultCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Action<System.Net.WebSockets.ClientWebSocketOptions> WebSocketConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class NoTransportSupportedException : System.Exception
+    {
+        public NoTransportSupportedException(string message) { }
+    }
+    public partial class TransportFailedException : System.Exception
+    {
+        public TransportFailedException(string transportType, string message, System.Exception innerException = null) { }
+        public string TransportType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+    }
+}
+namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
+{
+    public partial interface ITransport : System.IO.Pipelines.IDuplexPipe
+    {
+        System.Threading.Tasks.Task StartAsync(System.Uri url, Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+        System.Threading.Tasks.Task StopAsync();
+    }
+    public partial interface ITransportFactory
+    {
+        Microsoft.AspNetCore.Http.Connections.Client.Internal.ITransport CreateTransport(Microsoft.AspNetCore.Http.Connections.HttpTransportType availableServerTransports);
+    }
+    public partial class LongPollingTransport : Microsoft.AspNetCore.Http.Connections.Client.Internal.ITransport, System.IO.Pipelines.IDuplexPipe
+    {
+        public LongPollingTransport(System.Net.Http.HttpClient httpClient) { }
+        public LongPollingTransport(System.Net.Http.HttpClient httpClient, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
+        public System.IO.Pipelines.PipeReader Input { get { throw null; } }
+        public System.IO.Pipelines.PipeWriter Output { get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StartAsync(System.Uri url, Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StopAsync() { throw null; }
+    }
+    public partial class ServerSentEventsTransport : Microsoft.AspNetCore.Http.Connections.Client.Internal.ITransport, System.IO.Pipelines.IDuplexPipe
+    {
+        public ServerSentEventsTransport(System.Net.Http.HttpClient httpClient) { }
+        public ServerSentEventsTransport(System.Net.Http.HttpClient httpClient, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
+        public System.IO.Pipelines.PipeReader Input { get { throw null; } }
+        public System.IO.Pipelines.PipeWriter Output { get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StartAsync(System.Uri url, Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StopAsync() { throw null; }
+    }
+    public partial class WebSocketsTransport : Microsoft.AspNetCore.Http.Connections.Client.Internal.ITransport, System.IO.Pipelines.IDuplexPipe
+    {
+        public WebSocketsTransport(Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions httpConnectionOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, System.Func<System.Threading.Tasks.Task<string>> accessTokenProvider) { }
+        public System.IO.Pipelines.PipeReader Input { get { throw null; } }
+        public System.IO.Pipelines.PipeWriter Output { get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StartAsync(System.Uri url, Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public System.Threading.Tasks.Task StopAsync() { throw null; }
+    }
+}

+ 6 - 11
src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 using System.IO.Pipelines;
 using System.Linq;
 using System.Net.Http;
-using System.Runtime.InteropServices;
+using System.Net.WebSockets;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Connections;
@@ -29,9 +29,6 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
         private static readonly Task<string> _noAccessToken = Task.FromResult<string>(null);
 
         private static readonly TimeSpan HttpClientTimeout = TimeSpan.FromSeconds(120);
-#if !NETCOREAPP3_0
-        private static readonly Version Windows8Version = new Version(6, 2);
-#endif
 
         private readonly ILogger _logger;
 
@@ -586,20 +583,18 @@ namespace Microsoft.AspNetCore.Http.Connections.Client
 
         private static bool IsWebSocketsSupported()
         {
-#if NETCOREAPP3_0
+#if NETSTANDARD2_1
             // .NET Core 2.1 and above has a managed implementation
             return true;
 #else
-            var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-            if (!isWindows)
+            try
             {
-                // Assume other OSes have websockets
+                new ClientWebSocket().Dispose();
                 return true;
             }
-            else
+            catch
             {
-                // Windows 8 and above has websockets
-                return Environment.OSVersion.Version >= Windows8Version;
+                return false;
             }
 #endif
         }

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

@@ -204,7 +204,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
             {
                 while (true)
                 {
-#if NETCOREAPP3_0
+#if NETSTANDARD2_1
+                    // Do a 0 byte read so that idle connections don't allocate a buffer when waiting for a read
                     var result = await socket.ReceiveAsync(Memory<byte>.Empty, CancellationToken.None);
 
                     if (result.MessageType == WebSocketMessageType.Close)
@@ -220,17 +221,19 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
                     }
 #endif
                     var memory = _application.Output.GetMemory();
-#if NETCOREAPP3_0
+#if NETSTANDARD2_1
                     // Because we checked the CloseStatus from the 0 byte read above, we don't need to check again after reading
                     var receiveResult = await socket.ReceiveAsync(memory, CancellationToken.None);
-#else
+#elif NETSTANDARD2_0
                     var isArray = MemoryMarshal.TryGetArray<byte>(memory, out var arraySegment);
                     Debug.Assert(isArray);
 
                     // Exceptions are handled above where the send and receive tasks are being run.
                     var receiveResult = await socket.ReceiveAsync(arraySegment, CancellationToken.None);
+#else
+#error TFMs need to be updated
 #endif
-                    // Need to check again for netcoreapp3.0 because a close can happen between a 0-byte read and the actual read
+                    // Need to check again for netstandard2.1 because a close can happen between a 0-byte read and the actual read
                     if (receiveResult.MessageType == WebSocketMessageType.Close)
                     {
                         Log.WebSocketClosed(_logger, _webSocket.CloseStatus);

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

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <Description>Client for ASP.NET Core Connection Handlers</Description>
-    <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
     <IsShippingPackage>true</IsShippingPackage>
   </PropertyGroup>
 

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

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <Description>Common primitives for ASP.NET Connection Handlers and clients</Description>

+ 1 - 12
src/SignalR/common/Http.Connections/src/Internal/Transports/WebSocketsTransport.cs

@@ -5,10 +5,8 @@ using System;
 using System.Diagnostics;
 using System.IO.Pipelines;
 using System.Net.WebSockets;
-using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Connections;
 using Microsoft.Extensions.Logging;
 
@@ -144,7 +142,6 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal.Transports
             {
                 while (!token.IsCancellationRequested)
                 {
-#if NETCOREAPP3_0
                     // Do a 0 byte read so that idle connections don't allocate a buffer when waiting for a read
                     var result = await socket.ReceiveAsync(Memory<byte>.Empty, token);
 
@@ -152,18 +149,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal.Transports
                     {
                         return;
                     }
-#endif
+
                     var memory = _application.Output.GetMemory();
 
-#if NETCOREAPP3_0
                     var receiveResult = await socket.ReceiveAsync(memory, token);
-#else
-                    var isArray = MemoryMarshal.TryGetArray<byte>(memory, out var arraySegment);
-                    Debug.Assert(isArray);
-
-                    // Exceptions are handled above where the send and receive tasks are being run.
-                    var receiveResult = await socket.ReceiveAsync(arraySegment, token);
-#endif
                     // Need to check again for netcoreapp3.0 because a close can happen between a 0-byte read and the actual read
                     if (receiveResult.MessageType == WebSocketMessageType.Close)
                     {

+ 15 - 2
src/SignalR/common/Shared/AsyncEnumerableAdapters.cs

@@ -13,7 +13,6 @@ namespace Microsoft.AspNetCore.SignalR.Internal
     // True-internal because this is a weird and tricky class to use :)
     internal static class AsyncEnumerableAdapters
     {
-#if NETCOREAPP3_0
         public static IAsyncEnumerable<object> MakeCancelableAsyncEnumerable<T>(IAsyncEnumerable<T> asyncEnumerable, CancellationToken cancellationToken = default)
         {
             return new CancelableAsyncEnumerable<T>(asyncEnumerable, cancellationToken);
@@ -24,6 +23,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
             return new CancelableTypedAsyncEnumerable<T>(asyncEnumerable, cts);
         }
 
+#if NETCOREAPP3_0
         public static async IAsyncEnumerable<object> MakeAsyncEnumerableFromChannel<T>(ChannelReader<T> channel, [EnumeratorCancellation] CancellationToken cancellationToken = default)
         {
             await foreach (var item in channel.ReadAllAsync(cancellationToken))
@@ -31,6 +31,20 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                 yield return item;
             }
         }
+#else
+        // System.Threading.Channels.ReadAllAsync() is not available on netstandard2.0 and netstandard2.1
+        // But this is the exact same code that it uses
+        public static async IAsyncEnumerable<object> MakeAsyncEnumerableFromChannel<T>(ChannelReader<T> channel, [EnumeratorCancellation] CancellationToken cancellationToken = default)
+        {
+            while (await channel.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
+            {
+                while (channel.TryRead(out var item))
+                {
+                    yield return item;
+                }
+            }
+        }
+#endif
 
         private class CancelableTypedAsyncEnumerable<TResult> : IAsyncEnumerable<TResult>
         {
@@ -129,6 +143,5 @@ namespace Microsoft.AspNetCore.SignalR.Internal
                 }
             }
         }
-#endif
     }
 }

+ 0 - 4
src/SignalR/common/Shared/ReflectionHelper.cs

@@ -16,12 +16,10 @@ namespace Microsoft.AspNetCore.SignalR
         {
             // TODO #2594 - add Streams here, to make sending files easy
 
-#if NETCOREAPP3_0
             if (IsIAsyncEnumerable(type))
             {
                 return true;
             }
-#endif
             do
             {
                 if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ChannelReader<>))
@@ -35,7 +33,6 @@ namespace Microsoft.AspNetCore.SignalR
             return false;
         }
 
-#if NETCOREAPP3_0
         public static bool IsIAsyncEnumerable(Type type)
         {
             if (type.IsGenericType)
@@ -55,6 +52,5 @@ namespace Microsoft.AspNetCore.SignalR
                 }
             });
         }
-#endif
     }
 }

+ 10 - 15
src/SignalR/common/testassets/Tests.Utils/TestHelpers.cs

@@ -1,8 +1,7 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
-using System;
-using System.Runtime.InteropServices;
+using System.Net.WebSockets;
 
 namespace Microsoft.AspNetCore.SignalR.Tests
 {
@@ -10,19 +9,15 @@ namespace Microsoft.AspNetCore.SignalR.Tests
     {
         public static bool IsWebSocketsSupported()
         {
-#if NETCOREAPP3_0
-            // .NET Core 2.1 and greater has sockets
-            return true;
-#else
-                // Non-Windows platforms have sockets
-                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-                {
-                    return true;
-                }
-
-                // Windows 8 and greater has sockets
-                return Environment.OSVersion.Version >= new Version(6, 2);
-#endif
+            try
+            {
+                new ClientWebSocket().Dispose();
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
         }
     }
 }