diff --git a/SignalR.sln b/SignalR.sln index 855c160ba6..0a0d5e979a 100644 --- a/SignalR.sln +++ b/SignalR.sln @@ -16,41 +16,37 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{C4BC9889-B49F-41B6-806B-F84941B2549B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocketsSample", "samples\SocketsSample\SocketsSample.csproj", "{C4AEAB04-F341-4539-B6C0-52368FB4BF9E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SocketsSample", "samples\SocketsSample\SocketsSample.csproj", "{C4AEAB04-F341-4539-B6C0-52368FB4BF9E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Sockets", "src\Microsoft.AspNetCore.Sockets\Microsoft.AspNetCore.Sockets.csproj", "{1715EA8D-8E13-4ACF-8BCA-57D048E55ED8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Sockets", "src\Microsoft.AspNetCore.Sockets\Microsoft.AspNetCore.Sockets.csproj", "{1715EA8D-8E13-4ACF-8BCA-57D048E55ED8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6A35B453-52EC-48AF-89CA-D4A69800F131}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Sockets.Tests", "test\Microsoft.AspNetCore.Sockets.Tests\Microsoft.AspNetCore.Sockets.Tests.csproj", "{AAD719D5-5E31-4ED1-A60F-6EB92EFA66D9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Sockets.Tests", "test\Microsoft.AspNetCore.Sockets.Tests\Microsoft.AspNetCore.Sockets.Tests.csproj", "{AAD719D5-5E31-4ED1-A60F-6EB92EFA66D9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR", "src\Microsoft.AspNetCore.SignalR\Microsoft.AspNetCore.SignalR.csproj", "{42E76F87-92B6-45AB-BF07-6B811C0F2CAC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR", "src\Microsoft.AspNetCore.SignalR\Microsoft.AspNetCore.SignalR.csproj", "{42E76F87-92B6-45AB-BF07-6B811C0F2CAC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Redis", "src\Microsoft.AspNetCore.SignalR.Redis\Microsoft.AspNetCore.SignalR.Redis.csproj", "{59319B72-38BE-4041-8E5C-FF6938874CE8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Redis", "src\Microsoft.AspNetCore.SignalR.Redis\Microsoft.AspNetCore.SignalR.Redis.csproj", "{59319B72-38BE-4041-8E5C-FF6938874CE8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatSample", "samples\ChatSample\ChatSample.csproj", "{300979F6-A02E-407A-B8DF-F6200806C18D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatSample", "samples\ChatSample\ChatSample.csproj", "{300979F6-A02E-407A-B8DF-F6200806C18D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocialWeather", "samples\SocialWeather\SocialWeather.csproj", "{8D789F94-CB74-45FD-ACE7-92AF6E55042E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SocialWeather", "samples\SocialWeather\SocialWeather.csproj", "{8D789F94-CB74-45FD-ACE7-92AF6E55042E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Test.Server", "client-ts\Microsoft.AspNetCore.SignalR.Test.Server\Microsoft.AspNetCore.SignalR.Test.Server.csproj", "{A0BF246B-FE7D-4E12-99BF-FFDC131B85D8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Test.Server", "client-ts\Microsoft.AspNetCore.SignalR.Test.Server\Microsoft.AspNetCore.SignalR.Test.Server.csproj", "{A0BF246B-FE7D-4E12-99BF-FFDC131B85D8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Tests", "test\Microsoft.AspNetCore.SignalR.Tests\Microsoft.AspNetCore.SignalR.Tests.csproj", "{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Tests", "test\Microsoft.AspNetCore.SignalR.Tests\Microsoft.AspNetCore.SignalR.Tests.csproj", "{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientSample", "samples\ClientSample\ClientSample.csproj", "{BA99C2A1-48F9-4FA5-B95A-9687A73B7CC9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientSample", "samples\ClientSample\ClientSample.csproj", "{BA99C2A1-48F9-4FA5-B95A-9687A73B7CC9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebSocketSample", "samples\WebSocketSample\WebSocketSample.csproj", "{EE790D50-C632-46B9-A430-06FA2F2FDCD7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSocketSample", "samples\WebSocketSample\WebSocketSample.csproj", "{EE790D50-C632-46B9-A430-06FA2F2FDCD7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Sockets.Client", "src\Microsoft.AspNetCore.Sockets.Client\Microsoft.AspNetCore.Sockets.Client.csproj", "{623FD372-36DE-41A9-A564-F6040D570DBD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Client.Tests", "test\Microsoft.AspNetCore.SignalR.Client.Tests\Microsoft.AspNetCore.SignalR.Client.Tests.csproj", "{B19C15A5-F5EA-4CA7-936B-1166ABEE35C4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Client.Tests", "test\Microsoft.AspNetCore.SignalR.Client.Tests\Microsoft.AspNetCore.SignalR.Client.Tests.csproj", "{B19C15A5-F5EA-4CA7-936B-1166ABEE35C4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Common", "src\Microsoft.AspNetCore.SignalR.Common\Microsoft.AspNetCore.SignalR.Common.csproj", "{E37324FF-6BAF-4243-BA80-7C024CF5F29D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Common", "src\Microsoft.AspNetCore.SignalR.Common\Microsoft.AspNetCore.SignalR.Common.csproj", "{E37324FF-6BAF-4243-BA80-7C024CF5F29D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Client", "src\Microsoft.AspNetCore.SignalR.Client\Microsoft.AspNetCore.SignalR.Client.csproj", "{354335AB-CEE9-4434-A641-78058F6EFE56}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Client", "src\Microsoft.AspNetCore.SignalR.Client\Microsoft.AspNetCore.SignalR.Client.csproj", "{354335AB-CEE9-4434-A641-78058F6EFE56}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Client.FunctionalTests", "test\Microsoft.AspNetCore.SignalR.Client.FunctionalTests\Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj", "{455B68D2-C5B6-4BF4-A685-964B07AFAAF8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Sockets.Common", "src\Microsoft.AspNetCore.Sockets.Common\Microsoft.AspNetCore.Sockets.Common.csproj", "{F3EFFD9F-DD85-48A2-9B11-83A133ECC099}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Client.FunctionalTests", "test\Microsoft.AspNetCore.SignalR.Client.FunctionalTests\Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj", "{455B68D2-C5B6-4BF4-A685-964B07AFAAF8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Client.TS", "client-ts\Microsoft.AspNetCore.SignalR.Client.TS\Microsoft.AspNetCore.SignalR.Client.TS.csproj", "{333526A4-633B-491A-AC45-CC62A0012D1C}" EndProject @@ -67,7 +63,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client-ts", "client-ts", "{ client-ts\package.json = client-ts\package.json EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Microbenchmarks", "test\Microsoft.AspNetCore.SignalR.Microbenchmarks\Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj", "{96771B3F-4D18-41A7-A75B-FF38E76AAC89}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Microbenchmarks", "test\Microsoft.AspNetCore.SignalR.Microbenchmarks\Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj", "{96771B3F-4D18-41A7-A75B-FF38E76AAC89}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Common.Tests", "test\Microsoft.AspNetCore.SignalR.Common.Tests\Microsoft.AspNetCore.SignalR.Common.Tests.csproj", "{75E342F6-5445-4E7E-9143-6D9AE62C2B1E}" EndProject @@ -77,6 +73,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Signal EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Sockets.Http", "src\Microsoft.AspNetCore.Sockets.Http\Microsoft.AspNetCore.Sockets.Http.csproj", "{9E403E93-3284-486F-9A5F-1E15FCE426A5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Sockets.Client.Http", "src\Microsoft.AspNetCore.Sockets.Client.Http\Microsoft.AspNetCore.Sockets.Client.Http.csproj", "{B0243F99-2D3F-4CC6-AD71-E3F891B64724}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Sockets.Common.Http", "src\Microsoft.AspNetCore.Sockets.Common.Http\Microsoft.AspNetCore.Sockets.Common.Http.csproj", "{E081EE41-D95F-4AD2-BC0B-4B562C0A2A47}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -127,10 +127,6 @@ Global {EE790D50-C632-46B9-A430-06FA2F2FDCD7}.Debug|Any CPU.Build.0 = Debug|Any CPU {EE790D50-C632-46B9-A430-06FA2F2FDCD7}.Release|Any CPU.ActiveCfg = Release|Any CPU {EE790D50-C632-46B9-A430-06FA2F2FDCD7}.Release|Any CPU.Build.0 = Release|Any CPU - {623FD372-36DE-41A9-A564-F6040D570DBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {623FD372-36DE-41A9-A564-F6040D570DBD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {623FD372-36DE-41A9-A564-F6040D570DBD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {623FD372-36DE-41A9-A564-F6040D570DBD}.Release|Any CPU.Build.0 = Release|Any CPU {B19C15A5-F5EA-4CA7-936B-1166ABEE35C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B19C15A5-F5EA-4CA7-936B-1166ABEE35C4}.Debug|Any CPU.Build.0 = Debug|Any CPU {B19C15A5-F5EA-4CA7-936B-1166ABEE35C4}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -147,10 +143,6 @@ Global {455B68D2-C5B6-4BF4-A685-964B07AFAAF8}.Debug|Any CPU.Build.0 = Debug|Any CPU {455B68D2-C5B6-4BF4-A685-964B07AFAAF8}.Release|Any CPU.ActiveCfg = Release|Any CPU {455B68D2-C5B6-4BF4-A685-964B07AFAAF8}.Release|Any CPU.Build.0 = Release|Any CPU - {F3EFFD9F-DD85-48A2-9B11-83A133ECC099}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F3EFFD9F-DD85-48A2-9B11-83A133ECC099}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F3EFFD9F-DD85-48A2-9B11-83A133ECC099}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F3EFFD9F-DD85-48A2-9B11-83A133ECC099}.Release|Any CPU.Build.0 = Release|Any CPU {333526A4-633B-491A-AC45-CC62A0012D1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {333526A4-633B-491A-AC45-CC62A0012D1C}.Debug|Any CPU.Build.0 = Debug|Any CPU {333526A4-633B-491A-AC45-CC62A0012D1C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -175,6 +167,14 @@ Global {9E403E93-3284-486F-9A5F-1E15FCE426A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {9E403E93-3284-486F-9A5F-1E15FCE426A5}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E403E93-3284-486F-9A5F-1E15FCE426A5}.Release|Any CPU.Build.0 = Release|Any CPU + {B0243F99-2D3F-4CC6-AD71-E3F891B64724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0243F99-2D3F-4CC6-AD71-E3F891B64724}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0243F99-2D3F-4CC6-AD71-E3F891B64724}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0243F99-2D3F-4CC6-AD71-E3F891B64724}.Release|Any CPU.Build.0 = Release|Any CPU + {E081EE41-D95F-4AD2-BC0B-4B562C0A2A47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E081EE41-D95F-4AD2-BC0B-4B562C0A2A47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E081EE41-D95F-4AD2-BC0B-4B562C0A2A47}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E081EE41-D95F-4AD2-BC0B-4B562C0A2A47}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -191,12 +191,10 @@ Global {1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA} = {6A35B453-52EC-48AF-89CA-D4A69800F131} {BA99C2A1-48F9-4FA5-B95A-9687A73B7CC9} = {C4BC9889-B49F-41B6-806B-F84941B2549B} {EE790D50-C632-46B9-A430-06FA2F2FDCD7} = {C4BC9889-B49F-41B6-806B-F84941B2549B} - {623FD372-36DE-41A9-A564-F6040D570DBD} = {DA69F624-5398-4884-87E4-B816698CDE65} {B19C15A5-F5EA-4CA7-936B-1166ABEE35C4} = {6A35B453-52EC-48AF-89CA-D4A69800F131} {E37324FF-6BAF-4243-BA80-7C024CF5F29D} = {DA69F624-5398-4884-87E4-B816698CDE65} {354335AB-CEE9-4434-A641-78058F6EFE56} = {DA69F624-5398-4884-87E4-B816698CDE65} {455B68D2-C5B6-4BF4-A685-964B07AFAAF8} = {6A35B453-52EC-48AF-89CA-D4A69800F131} - {F3EFFD9F-DD85-48A2-9B11-83A133ECC099} = {DA69F624-5398-4884-87E4-B816698CDE65} {333526A4-633B-491A-AC45-CC62A0012D1C} = {3A76C5A2-79ED-49BC-8BDC-6A3A766FFA1B} {6CEC3DC2-5B01-45A8-8F0D-8531315DA90B} = {6A35B453-52EC-48AF-89CA-D4A69800F131} {96771B3F-4D18-41A7-A75B-FF38E76AAC89} = {6A35B453-52EC-48AF-89CA-D4A69800F131} @@ -204,5 +202,7 @@ Global {F2E4FBD6-9AEA-4A82-BAC9-3FAACA677DF8} = {DA69F624-5398-4884-87E4-B816698CDE65} {FD80BB0F-0876-4F11-8D84-6657C8EF84CA} = {DA69F624-5398-4884-87E4-B816698CDE65} {9E403E93-3284-486F-9A5F-1E15FCE426A5} = {DA69F624-5398-4884-87E4-B816698CDE65} + {B0243F99-2D3F-4CC6-AD71-E3F891B64724} = {DA69F624-5398-4884-87E4-B816698CDE65} + {E081EE41-D95F-4AD2-BC0B-4B562C0A2A47} = {DA69F624-5398-4884-87E4-B816698CDE65} EndGlobalSection EndGlobal diff --git a/samples/ClientSample/ClientSample.csproj b/samples/ClientSample/ClientSample.csproj index 34acd0f87e..c0bfdf5cb8 100644 --- a/samples/ClientSample/ClientSample.csproj +++ b/samples/ClientSample/ClientSample.csproj @@ -15,6 +15,7 @@ + diff --git a/samples/ClientSample/HubSample.cs b/samples/ClientSample/HubSample.cs index 2b9f885a17..aaf3b31002 100644 --- a/samples/ClientSample/HubSample.cs +++ b/samples/ClientSample/HubSample.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR.Client; +using Microsoft.AspNetCore.Sockets.Client; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.Logging; @@ -32,7 +33,8 @@ namespace ClientSample var loggerFactory = new LoggerFactory(); Console.WriteLine("Connecting to {0}", baseUrl); - var connection = new HubConnection(new Uri(baseUrl), loggerFactory); + var httpConnection = new HttpConnection(new Uri(baseUrl)); + var connection = new HubConnection(httpConnection, loggerFactory); try { await connection.StartAsync(); diff --git a/samples/ClientSample/RawSample.cs b/samples/ClientSample/RawSample.cs index 85ce9917d2..2e366cb2d1 100644 --- a/samples/ClientSample/RawSample.cs +++ b/samples/ClientSample/RawSample.cs @@ -8,7 +8,6 @@ using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Sockets; using Microsoft.AspNetCore.Sockets.Client; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.Logging; @@ -37,7 +36,7 @@ namespace ClientSample var logger = loggerFactory.CreateLogger(); Console.WriteLine($"Connecting to {baseUrl}..."); - var connection = new Connection(new Uri(baseUrl), loggerFactory); + var connection = new HttpConnection(new Uri(baseUrl), loggerFactory); try { var cts = new CancellationTokenSource(); diff --git a/src/Microsoft.AspNetCore.SignalR.Client/HubConnection.cs b/src/Microsoft.AspNetCore.SignalR.Client/HubConnection.cs index fb3fdbfb6f..fb6678d1b8 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client/HubConnection.cs +++ b/src/Microsoft.AspNetCore.SignalR.Client/HubConnection.cs @@ -5,13 +5,11 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Channels; using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal.Protocol; -using Microsoft.AspNetCore.Sockets; using Microsoft.AspNetCore.Sockets.Client; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -27,8 +25,6 @@ namespace Microsoft.AspNetCore.SignalR.Client private readonly IHubProtocol _protocol; private readonly HubBinder _binder; - private HttpClient _httpClient; - private readonly object _pendingCallsLock = new object(); private readonly CancellationTokenSource _connectionActive = new CancellationTokenSource(); private readonly Dictionary _pendingCalls = new Dictionary(); @@ -48,12 +44,8 @@ namespace Microsoft.AspNetCore.SignalR.Client remove { _connection.Closed -= value; } } - public HubConnection(Uri url) - : this(new Connection(url), new JsonHubProtocol(new JsonSerializer()), null) - { } - - public HubConnection(Uri url, ILoggerFactory loggerFactory) - : this(new Connection(url), new JsonHubProtocol(new JsonSerializer()), loggerFactory) + public HubConnection(IConnection connection) + : this(connection, new JsonHubProtocol(new JsonSerializer()), null) { } // These are only really needed for tests now... @@ -82,31 +74,14 @@ namespace Microsoft.AspNetCore.SignalR.Client _connection.Closed += Shutdown; } - public Task StartAsync() => StartAsync(TransportType.All, httpClient: null); - public Task StartAsync(HttpClient httpClient) => StartAsync(TransportType.All, httpClient: httpClient); - public Task StartAsync(TransportType transportType) => StartAsync(transportType, httpClient: null); - - public async Task StartAsync(TransportType transportType, HttpClient httpClient) + public async Task StartAsync() { - if (httpClient == null) - { - // We are creating the client so store it to be able to dispose - _httpClient = httpClient = new HttpClient(); - } - - await _connection.StartAsync(new DefaultTransportFactory(transportType, _loggerFactory, httpClient), httpClient); - } - - public async Task StartAsync(ITransportFactory transportFactory, HttpClient httpClient) - { - await _connection.StartAsync(transportFactory, httpClient); + await _connection.StartAsync(); } public async Task DisposeAsync() { await _connection.DisposeAsync(); - - _httpClient?.Dispose(); } // TODO: Client return values/tasks? diff --git a/src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj b/src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj index 009034a7df..b2bd6dbd6e 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj @@ -13,7 +13,8 @@ - + + diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj b/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj index c72fca04e8..e783c7c491 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj @@ -21,8 +21,4 @@ - - - - diff --git a/src/Microsoft.AspNetCore.Sockets.Client/IConnection.cs b/src/Microsoft.AspNetCore.Sockets.Abstractions/IConnection.cs similarity index 83% rename from src/Microsoft.AspNetCore.Sockets.Client/IConnection.cs rename to src/Microsoft.AspNetCore.Sockets.Abstractions/IConnection.cs index e45f406cb8..b2d62197f9 100644 --- a/src/Microsoft.AspNetCore.Sockets.Client/IConnection.cs +++ b/src/Microsoft.AspNetCore.Sockets.Abstractions/IConnection.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -10,7 +9,7 @@ namespace Microsoft.AspNetCore.Sockets.Client { public interface IConnection { - Task StartAsync(ITransportFactory transportFactory, HttpClient httpClient); + Task StartAsync(); Task SendAsync(byte[] data, CancellationToken cancellationToken); Task DisposeAsync(); diff --git a/src/Microsoft.AspNetCore.Sockets.Client/DefaultTransportFactory.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/DefaultTransportFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/DefaultTransportFactory.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/DefaultTransportFactory.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/Connection.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/HttpConnection.cs similarity index 86% rename from src/Microsoft.AspNetCore.Sockets.Client/Connection.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/HttpConnection.cs index 7fb903393b..412ba30f9f 100644 --- a/src/Microsoft.AspNetCore.Sockets.Client/Connection.cs +++ b/src/Microsoft.AspNetCore.Sockets.Client.Http/HttpConnection.cs @@ -15,18 +15,19 @@ using Newtonsoft.Json; namespace Microsoft.AspNetCore.Sockets.Client { - public class Connection : IConnection + public class HttpConnection : IConnection { private readonly ILoggerFactory _loggerFactory; private readonly ILogger _logger; private volatile int _connectionState = ConnectionState.Initial; private volatile IChannelConnection _transportChannel; - private HttpClient _httpClient; + private readonly HttpClient _httpClient; private volatile ITransport _transport; private volatile Task _receiveLoopTask; private TaskCompletionSource _startTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); private TaskQueue _eventQueue = new TaskQueue(); + private readonly ITransportFactory _transportFactory; private ReadableChannel Input => _transportChannel.Input; private WritableChannel Output => _transportChannel.Output; @@ -37,34 +38,45 @@ namespace Microsoft.AspNetCore.Sockets.Client public event Action Received; public event Action Closed; - public Connection(Uri url) - : this(url, null) + public HttpConnection(Uri url) + : this(url, TransportType.WebSockets) { } - public Connection(Uri url, ILoggerFactory loggerFactory) + public HttpConnection(Uri url, TransportType transportType) + : this(url, transportType, loggerFactory: null) + { + } + + public HttpConnection(Uri url, ILoggerFactory loggerFactory) + : this(url, TransportType.WebSockets, loggerFactory, httpMessageHandler: null) + { + } + + public HttpConnection(Uri url, TransportType transportType, ILoggerFactory loggerFactory) + : this(url, transportType, loggerFactory, httpMessageHandler: null) + { + } + + public HttpConnection(Uri url, TransportType transportType, ILoggerFactory loggerFactory, HttpMessageHandler httpMessageHandler) { Url = url ?? throw new ArgumentNullException(nameof(url)); _loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; - _logger = _loggerFactory.CreateLogger(); + _logger = _loggerFactory.CreateLogger(); + _httpClient = httpMessageHandler == null ? new HttpClient() : new HttpClient(httpMessageHandler); + _transportFactory = new DefaultTransportFactory(transportType, _loggerFactory, _httpClient); } - public Task StartAsync() => StartAsync(transportFactory: null, httpClient: null); - public Task StartAsync(HttpClient httpClient) => StartAsync(transportFactory: null, httpClient: httpClient); - public Task StartAsync(ITransportFactory transportFactory) => StartAsync(transportFactory, httpClient: null); - public Task StartAsync(TransportType transportType) => StartAsync(transportType, httpClient: null); - public Task StartAsync(TransportType transportType, HttpClient httpClient) + public HttpConnection(Uri url, ITransportFactory transportFactory, ILoggerFactory loggerFactory, HttpMessageHandler httpMessageHandler) { - if (httpClient == null) - { - // We are creating the client so store it to be able to dispose - _httpClient = httpClient = new HttpClient(); - } - - return StartAsync(new DefaultTransportFactory(transportType, _loggerFactory, httpClient), httpClient); + Url = url ?? throw new ArgumentNullException(nameof(url)); + _loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; + _logger = _loggerFactory.CreateLogger(); + _httpClient = httpMessageHandler == null ? new HttpClient() : new HttpClient(httpMessageHandler); + _transportFactory = transportFactory ?? throw new ArgumentNullException(nameof(transportFactory)); } - public Task StartAsync(ITransportFactory transportFactory, HttpClient httpClient) + public Task StartAsync() { if (Interlocked.CompareExchange(ref _connectionState, ConnectionState.Connecting, ConnectionState.Initial) != ConnectionState.Initial) @@ -73,13 +85,7 @@ namespace Microsoft.AspNetCore.Sockets.Client new InvalidOperationException("Cannot start a connection that is not in the Initial state.")); } - if (httpClient == null) - { - // We are creating the client so store it to be able to dispose - _httpClient = httpClient = new HttpClient(); - } - - StartAsyncInternal(transportFactory ?? new DefaultTransportFactory(TransportType.All, _loggerFactory, httpClient), httpClient) + StartAsyncInternal() .ContinueWith(t => { if (t.IsFaulted) @@ -99,13 +105,13 @@ namespace Microsoft.AspNetCore.Sockets.Client return _startTcs.Task; } - private async Task StartAsyncInternal(ITransportFactory transportFactory, HttpClient httpClient) + private async Task StartAsyncInternal() { _logger.LogDebug("Starting connection."); try { - var negotiationResponse = await Negotiate(Url, httpClient, _logger); + var negotiationResponse = await Negotiate(Url, _httpClient, _logger); // Connection is being stopped while start was in progress if (_connectionState == ConnectionState.Disconnected) @@ -114,7 +120,7 @@ namespace Microsoft.AspNetCore.Sockets.Client return; } - _transport = transportFactory.CreateTransport(GetAvailableServerTransports(negotiationResponse)); + _transport = _transportFactory.CreateTransport(GetAvailableServerTransports(negotiationResponse)); var connectUrl = CreateConnectUrl(Url, negotiationResponse); _logger.LogDebug("Starting transport '{0}' with Url: {1}", _transport.GetType().Name, connectUrl); @@ -161,7 +167,7 @@ namespace Microsoft.AspNetCore.Sockets.Client _logger.LogDebug("Draining event queue"); await _eventQueue.Drain(); - _httpClient?.Dispose(); + _httpClient.Dispose(); _logger.LogDebug("Raising Closed event"); @@ -387,7 +393,7 @@ namespace Microsoft.AspNetCore.Sockets.Client await _receiveLoopTask; } - _httpClient?.Dispose(); + _httpClient.Dispose(); } private class ConnectionState diff --git a/src/Microsoft.AspNetCore.Sockets.Client/ITransport.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/ITransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/ITransport.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/ITransport.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/ITransportFactory.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/ITransportFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/ITransportFactory.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/ITransportFactory.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/Internal/TaskQueue.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/Internal/TaskQueue.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/Internal/TaskQueue.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/Internal/TaskQueue.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/LongPollingTransport.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/LongPollingTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/LongPollingTransport.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/LongPollingTransport.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/Microsoft.AspNetCore.Sockets.Client.csproj b/src/Microsoft.AspNetCore.Sockets.Client.Http/Microsoft.AspNetCore.Sockets.Client.Http.csproj similarity index 95% rename from src/Microsoft.AspNetCore.Sockets.Client/Microsoft.AspNetCore.Sockets.Client.csproj rename to src/Microsoft.AspNetCore.Sockets.Client.Http/Microsoft.AspNetCore.Sockets.Client.Http.csproj index b58e94a281..41dd43997f 100644 --- a/src/Microsoft.AspNetCore.Sockets.Client/Microsoft.AspNetCore.Sockets.Client.csproj +++ b/src/Microsoft.AspNetCore.Sockets.Client.Http/Microsoft.AspNetCore.Sockets.Client.Http.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Microsoft.AspNetCore.Sockets.Client/SendMessage.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/SendMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/SendMessage.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/SendMessage.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/SendUtils.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/SendUtils.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/SendUtils.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/SendUtils.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/ServerSentEventsMessageParser.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/ServerSentEventsMessageParser.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/ServerSentEventsMessageParser.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/ServerSentEventsMessageParser.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/ServerSentEventsTransport.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/ServerSentEventsTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/ServerSentEventsTransport.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/ServerSentEventsTransport.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/Utils.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/Utils.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/Utils.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/Utils.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Client/WebSocketsTransport.cs b/src/Microsoft.AspNetCore.Sockets.Client.Http/WebSocketsTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Client/WebSocketsTransport.cs rename to src/Microsoft.AspNetCore.Sockets.Client.Http/WebSocketsTransport.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Common/Microsoft.AspNetCore.Sockets.Common.csproj b/src/Microsoft.AspNetCore.Sockets.Common.Http/Microsoft.AspNetCore.Sockets.Common.Http.csproj similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Common/Microsoft.AspNetCore.Sockets.Common.csproj rename to src/Microsoft.AspNetCore.Sockets.Common.Http/Microsoft.AspNetCore.Sockets.Common.Http.csproj diff --git a/src/Microsoft.AspNetCore.Sockets.Common/TransportType.cs b/src/Microsoft.AspNetCore.Sockets.Common.Http/TransportType.cs similarity index 100% rename from src/Microsoft.AspNetCore.Sockets.Common/TransportType.cs rename to src/Microsoft.AspNetCore.Sockets.Common.Http/TransportType.cs diff --git a/src/Microsoft.AspNetCore.Sockets.Http/Microsoft.AspNetCore.Sockets.Http.csproj b/src/Microsoft.AspNetCore.Sockets.Http/Microsoft.AspNetCore.Sockets.Http.csproj index f3ad26b1df..971786f6ca 100644 --- a/src/Microsoft.AspNetCore.Sockets.Http/Microsoft.AspNetCore.Sockets.Http.csproj +++ b/src/Microsoft.AspNetCore.Sockets.Http/Microsoft.AspNetCore.Sockets.Http.csproj @@ -17,7 +17,7 @@ - + diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs index 377d5d612b..85323a8829 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.SignalR.Tests.Common; using Microsoft.AspNetCore.Sockets; +using Microsoft.AspNetCore.Sockets.Client; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -51,21 +52,19 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests { var loggerFactory = CreateLogger(); - using (var httpClient = _testServer.CreateClient()) + var httpConnection = new HttpConnection(new Uri("http://test/hubs"), TransportType.LongPolling, loggerFactory, _testServer.CreateHandler()); + var connection = new HubConnection(httpConnection, loggerFactory); + try { - var connection = new HubConnection(new Uri("http://test/hubs"), loggerFactory); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - var result = await connection.Invoke(nameof(TestHub.HelloWorld)); + var result = await connection.Invoke(nameof(TestHub.HelloWorld)); - Assert.Equal("Hello World!", result); - } - finally - { - await connection.DisposeAsync(); - } + Assert.Equal("Hello World!", result); + } + finally + { + await connection.DisposeAsync(); } } @@ -75,21 +74,19 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests var loggerFactory = CreateLogger(); const string originalMessage = "SignalR"; - using (var httpClient = _testServer.CreateClient()) + var httpConnection = new HttpConnection(new Uri("http://test/hubs"), TransportType.LongPolling, loggerFactory, _testServer.CreateHandler()); + var connection = new HubConnection(httpConnection, loggerFactory); + try { - var connection = new HubConnection(new Uri("http://test/hubs"), loggerFactory); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - var result = await connection.Invoke(nameof(TestHub.Echo), originalMessage); + var result = await connection.Invoke(nameof(TestHub.Echo), originalMessage); - Assert.Equal(originalMessage, result); - } - finally - { - await connection.DisposeAsync(); - } + Assert.Equal(originalMessage, result); + } + finally + { + await connection.DisposeAsync(); } } @@ -99,21 +96,19 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests var loggerFactory = CreateLogger(); const string originalMessage = "SignalR"; - using (var httpClient = _testServer.CreateClient()) + var httpConnection = new HttpConnection(new Uri("http://test/hubs"), TransportType.LongPolling, loggerFactory, _testServer.CreateHandler()); + var connection = new HubConnection(httpConnection, loggerFactory); + try { - var connection = new HubConnection(new Uri("http://test/hubs"), loggerFactory); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - var result = await connection.Invoke(nameof(TestHub.Echo).ToLowerInvariant(), originalMessage); + var result = await connection.Invoke(nameof(TestHub.Echo).ToLowerInvariant(), originalMessage); - Assert.Equal(originalMessage, result); - } - finally - { - await connection.DisposeAsync(); - } + Assert.Equal(originalMessage, result); + } + finally + { + await connection.DisposeAsync(); } } @@ -123,24 +118,22 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests var loggerFactory = CreateLogger(); const string originalMessage = "SignalR"; - using (var httpClient = _testServer.CreateClient()) + var httpConnection = new HttpConnection(new Uri("http://test/hubs"), TransportType.LongPolling, loggerFactory, _testServer.CreateHandler()); + var connection = new HubConnection(httpConnection, loggerFactory); + try { - var connection = new HubConnection(new Uri("http://test/hubs"), loggerFactory); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - var tcs = new TaskCompletionSource(); - connection.On("Echo", tcs.SetResult); + var tcs = new TaskCompletionSource(); + connection.On("Echo", tcs.SetResult); - await connection.Invoke(nameof(TestHub.CallEcho), originalMessage).OrTimeout(); + await connection.Invoke(nameof(TestHub.CallEcho), originalMessage).OrTimeout(); - Assert.Equal(originalMessage, await tcs.Task.OrTimeout()); - } - finally - { - await connection.DisposeAsync().OrTimeout(); - } + Assert.Equal(originalMessage, await tcs.Task.OrTimeout()); + } + finally + { + await connection.DisposeAsync().OrTimeout(); } } @@ -149,23 +142,21 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests { var loggerFactory = CreateLogger(); - using (var httpClient = _testServer.CreateClient()) + var httpConnection = new HttpConnection(new Uri("http://test/hubs"), TransportType.LongPolling, loggerFactory, _testServer.CreateHandler()); + var connection = new HubConnection(httpConnection, loggerFactory); + try { - var connection = new HubConnection(new Uri("http://test/hubs"), loggerFactory); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); - var results = await connection.Stream(nameof(TestHub.Stream)).ReadAllAsync().OrTimeout(); + var results = await connection.Stream(nameof(TestHub.Stream)).ReadAllAsync().OrTimeout(); - Assert.Equal(new[] { "a", "b", "c" }, results.ToArray()); - } - finally - { - await connection.DisposeAsync().OrTimeout(); - } + Assert.Equal(new[] { "a", "b", "c" }, results.ToArray()); + } + finally + { + await connection.DisposeAsync().OrTimeout(); } } @@ -174,22 +165,20 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests { var loggerFactory = CreateLogger(); - using (var httpClient = _testServer.CreateClient()) + var httpConnection = new HttpConnection(new Uri("http://test/hubs"), TransportType.LongPolling, loggerFactory, _testServer.CreateHandler()); + var connection = new HubConnection(httpConnection, loggerFactory); + try { - var connection = new HubConnection(new Uri("http://test/hubs"), loggerFactory); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - var ex = await Assert.ThrowsAnyAsync( - async () => await connection.Invoke("!@#$%")); + var ex = await Assert.ThrowsAnyAsync( + async () => await connection.Invoke("!@#$%")); - Assert.Equal("Unknown hub method '!@#$%'", ex.Message); - } - finally - { - await connection.DisposeAsync(); - } + Assert.Equal("Unknown hub method '!@#$%'", ex.Message); + } + finally + { + await connection.DisposeAsync(); } } diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj index 340afe9254..60ca41518a 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj @@ -15,6 +15,7 @@ + diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ConnectionTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/ConnectionTests.cs index 149504ba0e..45cc5e8355 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ConnectionTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/ConnectionTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests [Fact] public void CannotCreateConnectionWithNullUrl() { - var exception = Assert.Throws(() => new Connection(null)); + var exception = Assert.Throws(() => new HttpConnection(null)); Assert.Equal("url", exception.ParamName); } @@ -29,17 +29,16 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests public void ConnectionReturnsUrlUsedToStartTheConnection() { var connectionUrl = new Uri("http://fakeuri.org/"); - Assert.Equal(connectionUrl, new Connection(connectionUrl).Url); + Assert.Equal(connectionUrl, new HttpConnection(connectionUrl).Url); } [Theory] [InlineData((TransportType)0)] [InlineData(TransportType.All + 1)] - public async Task CannotStartConnectionWithInvalidTransportType(TransportType requestedTransportType) + public void CannotStartConnectionWithInvalidTransportType(TransportType requestedTransportType) { - var connection = new Connection(new Uri("http://fakeuri.org/")); - await Assert.ThrowsAsync( - () => connection.StartAsync(requestedTransportType)); + Assert.Throws( + () => new HttpConnection(new Uri("http://fakeuri.org/"), requestedTransportType)); } [Fact] @@ -57,21 +56,18 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + try { - var connection = new Connection(new Uri("http://fakeuri.org/")); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); - var exception = - await Assert.ThrowsAsync( - async () => await connection.StartAsync()); - Assert.Equal("Cannot start a connection that is not in the Initial state.", exception.Message); - } - finally - { - await connection.DisposeAsync(); - } + await connection.StartAsync(); + var exception = + await Assert.ThrowsAsync( + async () => await connection.StartAsync()); + Assert.Equal("Cannot start a connection that is not in the Initial state.", exception.Message); + } + finally + { + await connection.DisposeAsync(); } } @@ -89,18 +85,15 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); - await connection.StartAsync(TransportType.LongPolling, httpClient); - await connection.DisposeAsync(); - var exception = - await Assert.ThrowsAsync( - async () => await connection.StartAsync()); + await connection.StartAsync(); + await connection.DisposeAsync(); + var exception = + await Assert.ThrowsAsync( + async () => await connection.StartAsync()); - Assert.Equal("Cannot start a connection that is not in the Initial state.", exception.Message); - } + Assert.Equal("Cannot start a connection that is not in the Initial state.", exception.Message); } [Fact] @@ -108,7 +101,7 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests { using (var httpClient = new HttpClient()) { - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/")); await connection.DisposeAsync(); var exception = await Assert.ThrowsAsync( @@ -142,31 +135,29 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var transport = new Mock(); - transport.Setup(t => t.StopAsync()).Returns(async () => { await releaseDisposeTcs.Task; }); - var connection = new Connection(new Uri("http://fakeuri.org/")); - var startTask = connection.StartAsync(new TestTransportFactory(transport.Object), httpClient); - await allowDisposeTcs.Task; - var disposeTask = connection.DisposeAsync(); - // allow StartAsync to continue once DisposeAsync has started - releaseNegotiateTcs.SetResult(null); + var transport = new Mock(); + transport.Setup(t => t.StopAsync()).Returns(async () => { await releaseDisposeTcs.Task; }); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), new TestTransportFactory(transport.Object), loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); - // unblock DisposeAsync only after StartAsync completed - await startTask.OrTimeout(); - releaseDisposeTcs.SetResult(null); - await disposeTask.OrTimeout(); + var startTask = connection.StartAsync(); + await allowDisposeTcs.Task; + var disposeTask = connection.DisposeAsync(); + // allow StartAsync to continue once DisposeAsync has started + releaseNegotiateTcs.SetResult(null); - transport.Verify(t => t.StartAsync(It.IsAny(), It.IsAny>()), Times.Never); - } + // unblock DisposeAsync only after StartAsync completed + await startTask.OrTimeout(); + releaseDisposeTcs.SetResult(null); + await disposeTask.OrTimeout(); + + transport.Verify(t => t.StartAsync(It.IsAny(), It.IsAny>()), Times.Never); } [Fact] public async Task SendThrowsIfConnectionIsNotStarted() { - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/")); var exception = await Assert.ThrowsAsync( async () => await connection.SendAsync(new byte[0])); Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); @@ -186,17 +177,15 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - await connection.StartAsync(TransportType.LongPolling, httpClient); - await connection.DisposeAsync(); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); - var exception = await Assert.ThrowsAsync( - async () => await connection.SendAsync(new byte[0])); - Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); - } + await connection.StartAsync(); + await connection.DisposeAsync(); + + var exception = await Assert.ThrowsAsync( + async () => await connection.SendAsync(new byte[0])); + Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); } [Fact] @@ -213,22 +202,20 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) + + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + try { - var connection = new Connection(new Uri("http://fakeuri.org/")); - try - { - var connectedEventRaisedTcs = new TaskCompletionSource(); - connection.Connected += () => connectedEventRaisedTcs.SetResult(null); + var connectedEventRaisedTcs = new TaskCompletionSource(); + connection.Connected += () => connectedEventRaisedTcs.SetResult(null); - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - await connectedEventRaisedTcs.Task.OrTimeout(); - } - finally - { - await connection.DisposeAsync(); - } + await connectedEventRaisedTcs.Task.OrTimeout(); + } + finally + { + await connection.DisposeAsync(); } } @@ -250,25 +237,23 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests mockTransport.Setup(t => t.StartAsync(It.IsAny(), It.IsAny>())) .Returns(Task.FromException(new InvalidOperationException("Transport failed to start"))); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) + + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), new TestTransportFactory(mockTransport.Object), loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + var connectedEventRaised = false; + + try { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var connectedEventRaised = false; + connection.Connected += () => connectedEventRaised = true; - try - { - connection.Connected += () => connectedEventRaised = true; - - await Assert.ThrowsAsync( - async () => await connection.StartAsync(new TestTransportFactory(mockTransport.Object), httpClient)); - } - finally - { - await connection.DisposeAsync(); - } - - Assert.False(connectedEventRaised); + await Assert.ThrowsAsync( + async () => await connection.StartAsync()); } + finally + { + await connection.DisposeAsync(); + } + + Assert.False(connectedEventRaised); } [Fact] @@ -285,19 +270,17 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var closedEventTcs = new TaskCompletionSource(); - connection.Closed += e => closedEventTcs.SetResult(e); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); - await connection.StartAsync(TransportType.LongPolling, httpClient); - await connection.DisposeAsync(); + var closedEventTcs = new TaskCompletionSource(); + connection.Closed += e => closedEventTcs.SetResult(e); - // in case of clean disconnect error should be null - Assert.Null(await closedEventTcs.Task.OrTimeout()); - } + await connection.StartAsync(); + await connection.DisposeAsync(); + + // in case of clean disconnect error should be null + Assert.Null(await closedEventTcs.Task.OrTimeout()); } [Fact] @@ -317,21 +300,18 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var closedEventTcs = new TaskCompletionSource(); - connection.Closed += e => closedEventTcs.TrySetResult(e); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + var closedEventTcs = new TaskCompletionSource(); + connection.Closed += e => closedEventTcs.TrySetResult(e); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); - Assert.IsType(await closedEventTcs.Task.OrTimeout()); - } - finally - { - await connection.DisposeAsync(); - } + try + { + await connection.StartAsync(); + Assert.IsType(await closedEventTcs.Task.OrTimeout()); + } + finally + { + await connection.DisposeAsync(); } } @@ -367,16 +347,14 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests return Task.CompletedTask; }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var receivedInvoked = false; - connection.Received += (m) => receivedInvoked = true; - await connection.StartAsync(new TestTransportFactory(mockTransport.Object), httpClient); - await connection.DisposeAsync(); - Assert.False(receivedInvoked); - } + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), new TestTransportFactory(mockTransport.Object), loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + var receivedInvoked = false; + connection.Received += (m) => receivedInvoked = true; + + await connection.StartAsync(); + await connection.DisposeAsync(); + Assert.False(receivedInvoked); } [Fact] @@ -408,39 +386,37 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests return Task.CompletedTask; }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var closedTcs = new TaskCompletionSource(); - var allowDisposeTcs = new TaskCompletionSource(); - int receivedInvocationCount = 0; - var connection = new Connection(new Uri("http://fakeuri.org/")); - connection.Received += - async (m) => + var closedTcs = new TaskCompletionSource(); + var allowDisposeTcs = new TaskCompletionSource(); + int receivedInvocationCount = 0; + + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), new TestTransportFactory(mockTransport.Object), loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + connection.Received += + async (m) => + { + if (Interlocked.Increment(ref receivedInvocationCount) == 2) { - if (Interlocked.Increment(ref receivedInvocationCount) == 2) - { - allowDisposeTcs.TrySetResult(null); - } - await closedTcs.Task; - }; - connection.Closed += e => closedTcs.SetResult(null); + allowDisposeTcs.TrySetResult(null); + } + await closedTcs.Task; + }; + connection.Closed += e => closedTcs.SetResult(null); - await connection.StartAsync(new TestTransportFactory(mockTransport.Object), httpClient); - channel.Output.TryWrite(Array.Empty()); - channel.Output.TryWrite(Array.Empty()); - await allowDisposeTcs.Task.OrTimeout(); - await connection.DisposeAsync(); - Assert.Equal(2, receivedInvocationCount); - // if the events were running on the main loop they would deadlock - await closedTcs.Task.OrTimeout(); - } + await connection.StartAsync(); + channel.Output.TryWrite(Array.Empty()); + channel.Output.TryWrite(Array.Empty()); + await allowDisposeTcs.Task.OrTimeout(); + await connection.DisposeAsync(); + Assert.Equal(2, receivedInvocationCount); + // if the events were running on the main loop they would deadlock + await closedTcs.Task.OrTimeout(); } [Fact] public async Task ClosedEventNotRaisedWhenTheClientIsStoppedButWasNeverStarted() { - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/")); bool closedEventRaised = false; connection.Closed += e => closedEventRaised = true; @@ -467,11 +443,11 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests using (var httpClient = new HttpClient(mockHttpHandler.Object)) { var longPollingTransport = new LongPollingTransport(httpClient, new LoggerFactory()); - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), new TestTransportFactory(longPollingTransport), loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); try { - await connection.StartAsync(new TestTransportFactory(longPollingTransport), httpClient); + await connection.StartAsync(); Assert.False(longPollingTransport.Running.IsCompleted); } @@ -506,28 +482,25 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + try { - var connection = new Connection(new Uri("http://fakeuri.org/")); - try - { - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - await connection.SendAsync(data); + await connection.SendAsync(data); - Assert.Equal(data, await sendTcs.Task.OrTimeout()); - } - finally - { - await connection.DisposeAsync(); - } + Assert.Equal(data, await sendTcs.Task.OrTimeout()); + } + finally + { + await connection.DisposeAsync(); } } [Fact] public async Task SendAsyncThrowsIfConnectionIsNotStarted() { - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/")); var exception = await Assert.ThrowsAsync( async () => await connection.SendAsync(new byte[0])); @@ -555,18 +528,15 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK, content); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); - await connection.StartAsync(TransportType.LongPolling, httpClient); - await connection.DisposeAsync(); + await connection.StartAsync(); + await connection.DisposeAsync(); - var exception = await Assert.ThrowsAsync( - async () => await connection.SendAsync(new byte[0])); + var exception = await Assert.ThrowsAsync( + async () => await connection.SendAsync(new byte[0])); - Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); - } + Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); } [Fact] @@ -586,17 +556,14 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - var exception = await Assert.ThrowsAsync( - async () => await connection.SendAsync(new byte[0])); + var exception = await Assert.ThrowsAsync( + async () => await connection.SendAsync(new byte[0])); - await connection.DisposeAsync(); - } + await connection.DisposeAsync(); } [Fact] @@ -621,33 +588,30 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK, content); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + try { - var connection = new Connection(new Uri("http://fakeuri.org/")); - try - { - var receiveTcs = new TaskCompletionSource(); - connection.Received += (data) => receiveTcs.TrySetResult(Encoding.UTF8.GetString(data)); - connection.Closed += e => + var receiveTcs = new TaskCompletionSource(); + connection.Received += (data) => receiveTcs.TrySetResult(Encoding.UTF8.GetString(data)); + connection.Closed += e => + { + if (e != null) { - if (e != null) - { - receiveTcs.TrySetException(e); - } - else - { - receiveTcs.TrySetCanceled(); - } - }; + receiveTcs.TrySetException(e); + } + else + { + receiveTcs.TrySetCanceled(); + } + }; - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - Assert.Equal("42", await receiveTcs.Task.OrTimeout()); - } - finally - { - await connection.DisposeAsync(); - } + Assert.Equal("42", await receiveTcs.Task.OrTimeout()); + } + finally + { + await connection.DisposeAsync(); } } @@ -668,28 +632,25 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests : ResponseUtils.CreateResponse(HttpStatusCode.OK); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + try { - var connection = new Connection(new Uri("http://fakeuri.org/")); - try - { - var closeTcs = new TaskCompletionSource(); - connection.Closed += e => closeTcs.TrySetResult(e); + var closeTcs = new TaskCompletionSource(); + connection.Closed += e => closeTcs.TrySetResult(e); - await connection.StartAsync(TransportType.LongPolling, httpClient); + await connection.StartAsync(); - // Exception in send should shutdown the connection - await closeTcs.Task.OrTimeout(); + // Exception in send should shutdown the connection + await closeTcs.Task.OrTimeout(); - var exception = await Assert.ThrowsAsync( - async () => await connection.SendAsync(new byte[0])); + var exception = await Assert.ThrowsAsync( + async () => await connection.SendAsync(new byte[0])); - Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); - } - finally - { - await connection.DisposeAsync(); - } + Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); + } + finally + { + await connection.DisposeAsync(); } } @@ -707,14 +668,11 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests return ResponseUtils.CreateResponse(HttpStatusCode.OK, negotiatePayload); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var exception = await Assert.ThrowsAsync( - () => connection.StartAsync(TransportType.LongPolling, httpClient)); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + var exception = await Assert.ThrowsAsync( + () => connection.StartAsync()); - Assert.Equal("Invalid negotiation response received.", exception.Message); - } + Assert.Equal("Invalid negotiation response received.", exception.Message); } [Fact] @@ -730,14 +688,11 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests ResponseUtils.CreateNegotiationResponse(connectionId: null)); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var exception = await Assert.ThrowsAsync( - () => connection.StartAsync(TransportType.LongPolling, httpClient)); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + var exception = await Assert.ThrowsAsync( + () => connection.StartAsync()); - Assert.Equal("Invalid connection id returned in negotiation response.", exception.Message); - } + Assert.Equal("Invalid connection id returned in negotiation response.", exception.Message); } [Fact] @@ -753,14 +708,11 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests ResponseUtils.CreateNegotiationResponse(transportTypes: null)); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var exception = await Assert.ThrowsAsync( - () => connection.StartAsync(TransportType.LongPolling, httpClient)); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + var exception = await Assert.ThrowsAsync( + () => connection.StartAsync()); - Assert.Equal("No transports returned in negotiation response.", exception.Message); - } + Assert.Equal("No transports returned in negotiation response.", exception.Message); } [Theory] @@ -778,14 +730,11 @@ namespace Microsoft.AspNetCore.Sockets.Client.Tests ResponseUtils.CreateNegotiationResponse(transportTypes: serverTransports)); }); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var connection = new Connection(new Uri("http://fakeuri.org/")); - var exception = await Assert.ThrowsAsync( - () => connection.StartAsync(TransportType.LongPolling, httpClient)); + var connection = new HttpConnection(new Uri("http://fakeuri.org/"), TransportType.LongPolling, loggerFactory: null, httpMessageHandler: mockHttpHandler.Object); + var exception = await Assert.ThrowsAsync( + () => connection.StartAsync()); - Assert.Equal("No requested transports available on the server.", exception.Message); - } + Assert.Equal("No requested transports available on the server.", exception.Message); } } } diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs index 5b7d718872..7b97e55a18 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs @@ -4,19 +4,13 @@ using System; using System.Buffers; using System.Collections.Generic; -using System.Net.Http; -using System.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Client.Tests; using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.SignalR.Tests.Common; -using Microsoft.AspNetCore.Sockets; using Microsoft.AspNetCore.Sockets.Client; -using Microsoft.AspNetCore.Sockets.Client.Tests; using Microsoft.Extensions.Logging; using Moq; -using Moq.Protected; using Xunit; namespace Microsoft.AspNetCore.SignalR.Client.Tests @@ -24,110 +18,34 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests public class HubConnectionTests { [Fact] - public void CannotCreateHubConnectionWithNullUrl() + public async Task StartAsyncCallsConnectionStart() { - var exception = Assert.Throws( - () => new HubConnection((Uri)null, Mock.Of())); - Assert.Equal("url", exception.ParamName); + var connection = new Mock(); + connection.Setup(m => m.StartAsync()).Returns(Task.CompletedTask).Verifiable(); + var hubConnection = new HubConnection(connection.Object); + await hubConnection.StartAsync(); + + connection.Verify(c => c.StartAsync(), Times.Once()); } [Fact] - public async Task CanDisposeNotStartedHubConnection() + public async Task DisposeAsyncCallsConnectionStart() { - await new HubConnection(new Uri("http://fakeuri.org"), new LoggerFactory()) - .DisposeAsync(); - } - - [Fact] - public async Task CannotStartRunningHubConnection() - { - var mockHttpHandler = new Mock(); - mockHttpHandler.Protected() - .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) - .Returns(async (request, cancellationToken) => - { - await Task.Yield(); - return request.Method == HttpMethod.Options - ? ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK, ResponseUtils.CreateNegotiationResponse()) - : ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK); - }); - - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var hubConnection = new HubConnection(new Uri("http://fakeuri.org/"), new LoggerFactory()); - - try - { - await hubConnection.StartAsync(TransportType.LongPolling, httpClient); - var exception = - await Assert.ThrowsAsync( - async () => await hubConnection.StartAsync()); - Assert.Equal("Cannot start a connection that is not in the Initial state.", exception.Message); - } - finally - { - await hubConnection.DisposeAsync(); - } - } - } - - [Fact] - public async Task CannotStartStoppedHubConnection() - { - var mockHttpHandler = new Mock(); - mockHttpHandler.Protected() - .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) - .Returns(async (request, cancellationToken) => - { - await Task.Yield(); - return request.Method == HttpMethod.Options - ? ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK, ResponseUtils.CreateNegotiationResponse()) - : ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK); - }); - - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var hubConnection = new HubConnection(new Uri("http://fakeuri.org/"), new LoggerFactory()); - - await hubConnection.StartAsync(TransportType.LongPolling, httpClient); - await hubConnection.DisposeAsync(); - var exception = - await Assert.ThrowsAsync( - async () => await hubConnection.StartAsync()); - - Assert.Equal("Cannot start a connection that is not in the Initial state.", exception.Message); - } - } - - [Fact] - public async Task InvokeThrowsIfHubConnectionNotStarted() - { - var hubConnection = new HubConnection(new Uri("http://fakeuri.org")); - var exception = - await Assert.ThrowsAsync(async () => await hubConnection.Invoke("test")); - Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); - } - - [Fact] - public async Task InvokeThrowsIfHubConnectionDisposed() - { - var hubConnection = new HubConnection(new Uri("http://fakeuri.org")); + var connection = new Mock(); + connection.Setup(m => m.StartAsync()).Verifiable(); + var hubConnection = new HubConnection(connection.Object); await hubConnection.DisposeAsync(); - var exception = - await Assert.ThrowsAsync(async () => await hubConnection.Invoke("test")); - Assert.Equal("Cannot send messages when the connection is not in the Connected state.", exception.Message); + connection.Verify(c => c.DisposeAsync(), Times.Once()); } [Fact] public async Task InvokeThrowsIfSerializingMessageFails() { - var mockConnection = new Mock(); - var exception = new InvalidOperationException(); var mockProtocol = MockHubProtocol.Throw(exception); - var hubConnection = new HubConnection(mockConnection.Object, mockProtocol, null); - await hubConnection.StartAsync(TransportType.All, httpClient: null); + var hubConnection = new HubConnection(new TestConnection(), mockProtocol, null); + await hubConnection.StartAsync(); var actualException = await Assert.ThrowsAsync(async () => await hubConnection.Invoke("test")); @@ -137,75 +55,43 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests [Fact] public async Task HubConnectionConnectedEventRaisedWhenTheClientIsConnected() { - var mockHttpHandler = new Mock(); - mockHttpHandler.Protected() - .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) - .Returns(async (request, cancellationToken) => - { - await Task.Yield(); - return request.Method == HttpMethod.Options - ? ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK, ResponseUtils.CreateNegotiationResponse()) - : ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK); - }); - - using (var httpClient = new HttpClient(mockHttpHandler.Object)) + var connection = new TestConnection(); + var hubConnection = new HubConnection(connection); + try { - var hubConnection = new HubConnection(new Uri("http://fakeuri.org"), new LoggerFactory()); - try - { - var connectedEventRaisedTcs = new TaskCompletionSource(); - hubConnection.Connected += () => connectedEventRaisedTcs.SetResult(null); + var connectedEventRaisedTcs = new TaskCompletionSource(); + hubConnection.Connected += () => connectedEventRaisedTcs.SetResult(null); - await hubConnection.StartAsync(TransportType.LongPolling, httpClient); + await hubConnection.StartAsync(); - await connectedEventRaisedTcs.Task.OrTimeout(); - } - finally - { - await hubConnection.DisposeAsync(); - } + await connectedEventRaisedTcs.Task.OrTimeout(); + } + finally + { + await hubConnection.DisposeAsync(); } } [Fact] public async Task ClosedEventRaisedWhenTheClientIsStopped() { - var mockHttpHandler = new Mock(); - mockHttpHandler.Protected() - .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) - .Returns(async (request, cancellationToken) => - { - await Task.Yield(); - return request.Method == HttpMethod.Options - ? ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK, ResponseUtils.CreateNegotiationResponse()) - : ResponseUtils.CreateResponse(System.Net.HttpStatusCode.OK); - }); + var hubConnection = new HubConnection(new TestConnection()); + var closedEventTcs = new TaskCompletionSource(); + hubConnection.Closed += e => closedEventTcs.SetResult(e); - using (var httpClient = new HttpClient(mockHttpHandler.Object)) - { - var hubConnection = new HubConnection(new Uri("http://fakeuri.org"), new LoggerFactory()); - var closedEventTcs = new TaskCompletionSource(); - hubConnection.Closed += e => closedEventTcs.SetResult(e); + await hubConnection.StartAsync(); + await hubConnection.DisposeAsync(); - await hubConnection.StartAsync(TransportType.LongPolling, httpClient); - await hubConnection.DisposeAsync(); - - Assert.Null(await closedEventTcs.Task.OrTimeout()); - } + Assert.Null(await closedEventTcs.Task.OrTimeout()); } [Fact] public async Task CannotCallInvokeOnClosedHubConnection() { - var mockConnection = new Mock(); - mockConnection - .Setup(m => m.DisposeAsync()) - .Callback(() => mockConnection.Raise(c => c.Closed += null, (Exception)null)) - .Returns(Task.FromResult(null)); + var connection = new TestConnection(); + var hubConnection = new HubConnection(connection, new LoggerFactory()); - var hubConnection = new HubConnection(mockConnection.Object, new LoggerFactory()); - - await hubConnection.StartAsync(new TestTransportFactory(Mock.Of()), httpClient: null); + await hubConnection.StartAsync(); await hubConnection.DisposeAsync(); var exception = await Assert.ThrowsAsync( async () => await hubConnection.Invoke("test")); @@ -216,15 +102,10 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests [Fact] public async Task PendingInvocationsAreCancelledWhenConnectionClosesCleanly() { - var mockConnection = new Mock(); - mockConnection - .Setup(m => m.DisposeAsync()) - .Callback(() => mockConnection.Raise(c => c.Closed += null, (Exception)null)) - .Returns(Task.FromResult(null)); + var connection = new TestConnection(); + var hubConnection = new HubConnection(connection, new LoggerFactory()); - var hubConnection = new HubConnection(mockConnection.Object, new LoggerFactory()); - - await hubConnection.StartAsync(new TestTransportFactory(Mock.Of()), httpClient: null); + await hubConnection.StartAsync(); var invokeTask = hubConnection.Invoke("testMethod"); await hubConnection.DisposeAsync(); @@ -243,7 +124,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests var hubConnection = new HubConnection(mockConnection.Object, new LoggerFactory()); - await hubConnection.StartAsync(new TestTransportFactory(Mock.Of()), httpClient: null); + await hubConnection.StartAsync(); var invokeTask = hubConnection.Invoke("testMethod"); await hubConnection.DisposeAsync(); @@ -261,7 +142,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests var mockProtocol = MockHubProtocol.ReturnOnParse(invocation); var hubConnection = new HubConnection(mockConnection.Object, mockProtocol, null); - await hubConnection.StartAsync(new TestTransportFactory(Mock.Of()), httpClient: null); + await hubConnection.StartAsync(); mockConnection.Raise(c => c.Received += null, new object[] { new byte[] { } }); Assert.Equal(1, mockProtocol.ParseCalls); diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj index 4edd643532..c564fcbb8a 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs index c85961c968..5e5104ced9 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs @@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests throw new ObjectDisposedException("Unable to send message, underlying channel was closed"); } - public Task StartAsync(ITransportFactory transportFactory, HttpClient httpClient) + public Task StartAsync() { _started.TrySetResult(null); Connected?.Invoke(); diff --git a/test/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj b/test/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj index f17d379af5..af3aa9a7b2 100644 --- a/test/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj @@ -14,7 +14,6 @@ - diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs index f537bbb6e2..65f6faebc5 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs @@ -17,7 +17,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; using Xunit; using Xunit.Abstractions; -using ClientConnection = Microsoft.AspNetCore.Sockets.Client.Connection; namespace Microsoft.AspNetCore.SignalR.Tests { @@ -88,7 +87,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests const string message = "Major Key"; var url = _serverFixture.BaseUrl + "/echo"; - var connection = new ClientConnection(new Uri(url), loggerFactory); + var connection = new HttpConnection(new Uri(url), transportType, loggerFactory); try { var receiveTcs = new TaskCompletionSource(); @@ -114,7 +113,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests }; logger.LogInformation("Starting connection to {url}", url); - await connection.StartAsync(transportType).OrTimeout(); + await connection.StartAsync().OrTimeout(); logger.LogInformation("Started connection to {url}", url); var bytes = Encoding.UTF8.GetBytes(message); @@ -156,7 +155,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests var logger = loggerFactory.CreateLogger(); var url = _serverFixture.BaseUrl + "/echo"; - var connection = new ClientConnection(new Uri(url), loggerFactory); + var connection = new HttpConnection(new Uri(url), loggerFactory); try { var receiveTcs = new TaskCompletionSource(); @@ -167,7 +166,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests }; logger.LogInformation("Starting connection to {url}", url); - await connection.StartAsync(TransportType.WebSockets).OrTimeout(); + await connection.StartAsync().OrTimeout(); logger.LogInformation("Started connection to {url}", url); var bytes = Encoding.UTF8.GetBytes(message); @@ -213,7 +212,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests var logger = loggerFactory.CreateLogger(); var url = _serverFixture.BaseUrl + "/uncreatable"; - var connection = new HubConnection(new Uri(url), loggerFactory); + + var connection = new HubConnection(new HttpConnection(new Uri(url), transportType, loggerFactory), loggerFactory); try { var closeTcs = new TaskCompletionSource(); @@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests }; logger.LogInformation("Starting connection to {url}", url); - await connection.StartAsync(transportType).OrTimeout(); + await connection.StartAsync().OrTimeout(); await closeTcs.Task.OrTimeout(); } diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj index 3c77ea562f..25d5d021c4 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj @@ -21,6 +21,7 @@ +