From 144984e599fe4af857b88294a42abba342d7baf3 Mon Sep 17 00:00:00 2001 From: Andrew Stanton-Nurse Date: Wed, 10 Jan 2018 14:20:57 -0800 Subject: [PATCH] Split MsgPack into separate assembly (#1274) --- SignalR.sln | 21 ++++++++ .../HubProtocolBenchmark.cs | 3 ++ ....AspNetCore.SignalR.Microbenchmarks.csproj | 1 + .../Startup.cs | 12 +++-- samples/SocketsSample/Hubs/Person.cs | 16 ------ samples/SocketsSample/Startup.cs | 1 + .../HubConnectionBuilderExtensions.cs | 29 ++-------- ...kProtocolHubConnectionBuilderExtensions.cs | 19 +++++++ ...t.AspNetCore.SignalR.Client.MsgPack.csproj | 13 +++++ .../Internal/Protocol/JsonHubProtocol.cs | 49 +++++++---------- .../JsonHubProtocolOptions.cs | 13 +++++ ...Microsoft.AspNetCore.SignalR.Common.csproj | 2 +- .../HubConnectionContext.cs | 1 - .../HubEndPoint.cs | 1 - .../HubOptions.cs | 5 -- .../Internal/DefaultHubProtocolResolver.cs | 38 +++++++++---- .../Internal/SignalRCoreLoggerExtensions.cs | 19 ++++++- ...onProtocolDependencyInjectionExtensions.cs | 37 +++++++++++++ .../SignalRDependencyInjectionExtensions.cs | 2 +- ...icrosoft.AspNetCore.SignalR.MsgPack.csproj | 14 +++++ ...ckProtocolDependencyInjectionExtensions.cs | 37 +++++++++++++ .../Protocol/MessagePackHubProtocol.cs | 23 ++++---- .../MessagePackHubProtocolOptions.cs | 13 +++++ ...spNetCore.SignalR.Protocols.MsgPack.csproj | 22 ++++++++ .../SignalRDependencyInjectionExtensions.cs | 5 +- ...Core.SignalR.Client.FunctionalTests.csproj | 2 + .../Startup.cs | 5 +- .../HubConnectionBuilderExtensionsTests.cs | 2 +- .../HubConnectionBuilderTests.cs | 54 ++++++++++++++++++- .../HubConnectionExtensionsTests.cs | 2 +- .../HubConnectionProtocolTests.cs | 2 +- ...oft.AspNetCore.SignalR.Client.Tests.csproj | 1 + .../Internal/Protocol/JsonHubProtocolTests.cs | 23 +++++--- ...oft.AspNetCore.SignalR.Common.Tests.csproj | 1 + .../Docker.cs | 49 +++++++++++++---- ...soft.AspNetCore.SignalR.Redis.Tests.csproj | 2 + .../SkipIfDockerNotPresentAttribute.cs | 28 +++++++++- .../Startup.cs | 1 + .../TaskExtensions.cs | 24 +++++++++ .../HubEndpointTestUtils/Utils.cs | 8 +-- .../HubEndpointTests.cs | 37 +++++++------ .../DefaultHubProtocolResolverTests.cs | 47 ++++++++++++---- .../Microsoft.AspNetCore.SignalR.Tests.csproj | 1 + ...gnalRDependencyInjectionExtensionsTests.cs | 38 ------------- test/xunit.runner.json | 2 +- 45 files changed, 522 insertions(+), 203 deletions(-) delete mode 100644 samples/SocketsSample/Hubs/Person.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Client.MsgPack/MessagePackProtocolHubConnectionBuilderExtensions.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Client.MsgPack/Microsoft.AspNetCore.SignalR.Client.MsgPack.csproj create mode 100644 src/Microsoft.AspNetCore.SignalR.Common/JsonHubProtocolOptions.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Core/JsonProtocolDependencyInjectionExtensions.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.MsgPack/Microsoft.AspNetCore.SignalR.MsgPack.csproj create mode 100644 src/Microsoft.AspNetCore.SignalR.MsgPack/MsgPackProtocolDependencyInjectionExtensions.cs rename src/{Microsoft.AspNetCore.SignalR.Common => Microsoft.AspNetCore.SignalR.Protocols.MsgPack}/Internal/Protocol/MessagePackHubProtocol.cs (95%) create mode 100644 src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/MessagePackHubProtocolOptions.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Microsoft.AspNetCore.SignalR.Protocols.MsgPack.csproj delete mode 100644 test/Microsoft.AspNetCore.SignalR.Tests/SignalRDependencyInjectionExtensionsTests.cs diff --git a/SignalR.sln b/SignalR.sln index 834b4998d3..1adb8bf698 100644 --- a/SignalR.sln +++ b/SignalR.sln @@ -88,6 +88,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JwtClientSample", "samples\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Tests.Utils", "test\Microsoft.AspNetCore.SignalR.Tests.Utils\Microsoft.AspNetCore.SignalR.Tests.Utils.csproj", "{0A0A6135-EA24-4307-95C2-CE1B7E164A5E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Protocols.MsgPack", "src\Microsoft.AspNetCore.SignalR.Protocols.MsgPack\Microsoft.AspNetCore.SignalR.Protocols.MsgPack.csproj", "{55DB4B6F-12E5-4A27-97F4-E97E135470FF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.MsgPack", "src\Microsoft.AspNetCore.SignalR.MsgPack\Microsoft.AspNetCore.SignalR.MsgPack.csproj", "{FDDB4E1F-2FD2-49E8-B0FF-874B0931369A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Client.MsgPack", "src\Microsoft.AspNetCore.SignalR.Client.MsgPack\Microsoft.AspNetCore.SignalR.Client.MsgPack.csproj", "{4DBF918E-BD37-4309-B448-BA68C935944D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -206,6 +212,18 @@ Global {0A0A6135-EA24-4307-95C2-CE1B7E164A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A0A6135-EA24-4307-95C2-CE1B7E164A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A0A6135-EA24-4307-95C2-CE1B7E164A5E}.Release|Any CPU.Build.0 = Release|Any CPU + {55DB4B6F-12E5-4A27-97F4-E97E135470FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55DB4B6F-12E5-4A27-97F4-E97E135470FF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55DB4B6F-12E5-4A27-97F4-E97E135470FF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55DB4B6F-12E5-4A27-97F4-E97E135470FF}.Release|Any CPU.Build.0 = Release|Any CPU + {FDDB4E1F-2FD2-49E8-B0FF-874B0931369A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FDDB4E1F-2FD2-49E8-B0FF-874B0931369A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FDDB4E1F-2FD2-49E8-B0FF-874B0931369A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FDDB4E1F-2FD2-49E8-B0FF-874B0931369A}.Release|Any CPU.Build.0 = Release|Any CPU + {4DBF918E-BD37-4309-B448-BA68C935944D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4DBF918E-BD37-4309-B448-BA68C935944D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4DBF918E-BD37-4309-B448-BA68C935944D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4DBF918E-BD37-4309-B448-BA68C935944D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -239,6 +257,9 @@ Global {6A7491D3-3C97-49BD-A71C-433AED657F30} = {C4BC9889-B49F-41B6-806B-F84941B2549B} {1A953296-E869-4DE2-A693-FD5FCDE27057} = {C4BC9889-B49F-41B6-806B-F84941B2549B} {0A0A6135-EA24-4307-95C2-CE1B7E164A5E} = {6A35B453-52EC-48AF-89CA-D4A69800F131} + {55DB4B6F-12E5-4A27-97F4-E97E135470FF} = {DA69F624-5398-4884-87E4-B816698CDE65} + {FDDB4E1F-2FD2-49E8-B0FF-874B0931369A} = {DA69F624-5398-4884-87E4-B816698CDE65} + {4DBF918E-BD37-4309-B448-BA68C935944D} = {DA69F624-5398-4884-87E4-B816698CDE65} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7945A4E4-ACDB-4F6E-95CA-6AC6E7C2CD59} diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs index d0926148c6..8ee96f8d9c 100644 --- a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs +++ b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs @@ -1,3 +1,6 @@ +// 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 BenchmarkDotNet.Attributes; using Microsoft.AspNetCore.SignalR.Internal; diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj index 7a54cdd885..e24944e5f0 100644 --- a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj +++ b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj @@ -8,6 +8,7 @@ + diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/Startup.cs b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/Startup.cs index e9e3efeb4e..16f801e101 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/Startup.cs +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/Startup.cs @@ -23,11 +23,13 @@ namespace Microsoft.AspNetCore.SignalR.Test.Server public void ConfigureServices(IServiceCollection services) { services.AddSockets(); - services.AddSignalR(options => { - // we are running the same tests with JSON and MsgPack protocols and having - // consistent casing makes it cleaner to verify results - options.JsonSerializerSettings.ContractResolver = new DefaultContractResolver(); - }); + services.AddSignalR() + .AddJsonProtocol(options => + { + // we are running the same tests with JSON and MsgPack protocols and having + // consistent casing makes it cleaner to verify results + options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver(); + }); services.AddAuthorization(options => { diff --git a/samples/SocketsSample/Hubs/Person.cs b/samples/SocketsSample/Hubs/Person.cs deleted file mode 100644 index 7a1699355b..0000000000 --- a/samples/SocketsSample/Hubs/Person.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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.Linq; -using System.Threading.Tasks; - -namespace SocketsSample.Hubs -{ - public class Person - { - public string Name { get; set; } - public long Age { get; set; } - } -} diff --git a/samples/SocketsSample/Startup.cs b/samples/SocketsSample/Startup.cs index d4ce58a59a..9c3af3050f 100644 --- a/samples/SocketsSample/Startup.cs +++ b/samples/SocketsSample/Startup.cs @@ -5,6 +5,7 @@ using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json.Serialization; using SocketsSample.EndPoints; using SocketsSample.Hubs; diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs index e678c97349..69ed4535fc 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs @@ -1,11 +1,10 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.Extensions.Logging; -using MsgPack.Serialization; -using Newtonsoft.Json; +using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.SignalR.Client { @@ -22,29 +21,9 @@ namespace Microsoft.AspNetCore.SignalR.Client return hubConnectionBuilder.WithHubProtocol(new JsonHubProtocol()); } - public static IHubConnectionBuilder WithJsonProtocol(this IHubConnectionBuilder hubConnectionBuilder, JsonSerializerSettings serializerSettings) + public static IHubConnectionBuilder WithJsonProtocol(this IHubConnectionBuilder hubConnectionBuilder, JsonHubProtocolOptions options) { - return hubConnectionBuilder.WithHubProtocol(new JsonHubProtocol(JsonSerializer.Create(serializerSettings))); - } - - public static IHubConnectionBuilder WithJsonProtocol(this IHubConnectionBuilder hubConnectionBuilder, JsonSerializer jsonSerializer) - { - return hubConnectionBuilder.WithHubProtocol(new JsonHubProtocol(jsonSerializer)); - } - - public static IHubConnectionBuilder WithMessagePackProtocol(this IHubConnectionBuilder hubConnectionBuilder) - { - return hubConnectionBuilder.WithHubProtocol(new MessagePackHubProtocol()); - } - - public static IHubConnectionBuilder WithMessagePackProtocol(this IHubConnectionBuilder hubConnectionBuilder, SerializationContext serializationContext) - { - if (serializationContext == null) - { - throw new ArgumentNullException(nameof(serializationContext)); - } - - return hubConnectionBuilder.WithHubProtocol(new MessagePackHubProtocol(serializationContext)); + return hubConnectionBuilder.WithHubProtocol(new JsonHubProtocol(Options.Create(options))); } public static IHubConnectionBuilder WithLoggerFactory(this IHubConnectionBuilder hubConnectionBuilder, ILoggerFactory loggerFactory) diff --git a/src/Microsoft.AspNetCore.SignalR.Client.MsgPack/MessagePackProtocolHubConnectionBuilderExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Client.MsgPack/MessagePackProtocolHubConnectionBuilderExtensions.cs new file mode 100644 index 0000000000..c92e5da68f --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Client.MsgPack/MessagePackProtocolHubConnectionBuilderExtensions.cs @@ -0,0 +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 Microsoft.AspNetCore.SignalR.Internal.Protocol; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.SignalR.Client +{ + public static class MessagePackProtocolHubConnectionBuilderExtensions + { + public static IHubConnectionBuilder WithMessagePackProtocol(this IHubConnectionBuilder builder) => + WithMessagePackProtocol(builder, new MessagePackHubProtocolOptions()); + + public static IHubConnectionBuilder WithMessagePackProtocol(this IHubConnectionBuilder builder, MessagePackHubProtocolOptions options) + { + return builder.WithHubProtocol(new MessagePackHubProtocol(Options.Create(options))); + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Client.MsgPack/Microsoft.AspNetCore.SignalR.Client.MsgPack.csproj b/src/Microsoft.AspNetCore.SignalR.Client.MsgPack/Microsoft.AspNetCore.SignalR.Client.MsgPack.csproj new file mode 100644 index 0000000000..bf971bf27e --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Client.MsgPack/Microsoft.AspNetCore.SignalR.Client.MsgPack.csproj @@ -0,0 +1,13 @@ + + + + Provides client-side support for the MsgPack protocol in ASP.NET Core SignalR + netstandard2.0 + + + + + + + + diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs index c1a7605ff2..63f02fc235 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Runtime.ExceptionServices; using Microsoft.AspNetCore.SignalR.Internal.Formatters; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; @@ -23,35 +24,21 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol private const string ArgumentsPropertyName = "arguments"; private const string PayloadPropertyName = "payload"; + public static readonly string ProtocolName = "json"; + // ONLY to be used for application payloads (args, return values, etc.) - private JsonSerializer _payloadSerializer; + public JsonSerializer PayloadSerializer { get; } - /// - /// Creates an instance of the using the default - /// to serialize application payloads (arguments, results, etc.). The serialization of the outer protocol can - /// NOT be changed using this serializer. - /// - public JsonHubProtocol() - : this(JsonSerializer.Create(CreateDefaultSerializerSettings())) - { } - - /// - /// Creates an instance of the using the specified - /// to serialize application payloads (arguments, results, etc.). The serialization of the outer protocol can - /// NOT be changed using this serializer. - /// - /// The to use to serialize application payloads (arguments, results, etc.). - public JsonHubProtocol(JsonSerializer payloadSerializer) + public JsonHubProtocol() : this(Options.Create(new JsonHubProtocolOptions())) { - if (payloadSerializer == null) - { - throw new ArgumentNullException(nameof(payloadSerializer)); - } - - _payloadSerializer = payloadSerializer; } - public string Name => "json"; + public JsonHubProtocol(IOptions options) + { + PayloadSerializer = JsonSerializer.Create(options.Value.PayloadSerializerSettings); + } + + public string Name => ProtocolName; public ProtocolType Type => ProtocolType.Text; @@ -167,7 +154,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol else if (message.HasResult) { writer.WritePropertyName(ResultPropertyName); - _payloadSerializer.Serialize(writer, message.Result); + PayloadSerializer.Serialize(writer, message.Result); } writer.WriteEndObject(); } @@ -184,7 +171,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol writer.WriteStartObject(); WriteHubInvocationMessageCommon(message, writer, HubProtocolConstants.StreamItemMessageType); writer.WritePropertyName(ItemPropertyName); - _payloadSerializer.Serialize(writer, message.Item); + PayloadSerializer.Serialize(writer, message.Item); writer.WriteEndObject(); } @@ -218,7 +205,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol writer.WriteStartArray(); foreach (var argument in arguments) { - _payloadSerializer.Serialize(writer, argument); + PayloadSerializer.Serialize(writer, argument); } writer.WriteEndArray(); } @@ -299,7 +286,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol for (var i = 0; i < paramTypes.Length; i++) { var paramType = paramTypes[i]; - arguments[i] = args[i].ToObject(paramType, _payloadSerializer); + arguments[i] = args[i].ToObject(paramType, PayloadSerializer); } return arguments; @@ -316,7 +303,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol var result = JsonUtils.GetRequiredProperty(json, ItemPropertyName); var returnType = binder.GetReturnType(invocationId); - return new StreamItemMessage(invocationId, result?.ToObject(returnType, _payloadSerializer)); + return new StreamItemMessage(invocationId, result?.ToObject(returnType, PayloadSerializer)); } private CompletionMessage BindCompletionMessage(JObject json, IInvocationBinder binder) @@ -336,7 +323,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol } var returnType = binder.GetReturnType(invocationId); - var payload = resultProp.Value?.ToObject(returnType, _payloadSerializer); + var payload = resultProp.Value?.ToObject(returnType, PayloadSerializer); return new CompletionMessage(invocationId, error, result: payload, hasResult: true); } @@ -346,7 +333,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol return new CancelInvocationMessage(invocationId); } - public static JsonSerializerSettings CreateDefaultSerializerSettings() + internal static JsonSerializerSettings CreateDefaultSerializerSettings() { return new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/JsonHubProtocolOptions.cs b/src/Microsoft.AspNetCore.SignalR.Common/JsonHubProtocolOptions.cs new file mode 100644 index 0000000000..4ff4d010df --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Common/JsonHubProtocolOptions.cs @@ -0,0 +1,13 @@ +// 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 Microsoft.AspNetCore.SignalR.Internal.Protocol; +using Newtonsoft.Json; + +namespace Microsoft.AspNetCore.SignalR +{ + public class JsonHubProtocolOptions + { + public JsonSerializerSettings PayloadSerializerSettings { get; set; } = JsonHubProtocol.CreateDefaultSerializerSettings(); + } +} 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 0ab94fe4e0..657502efaf 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj @@ -9,11 +9,11 @@ - + diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs index 53accccc7e..a03c17e9a2 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs @@ -12,7 +12,6 @@ using System.Threading.Channels; using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.SignalR.Core; -using Microsoft.AspNetCore.SignalR.Core.Internal; using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal.Encoders; using Microsoft.AspNetCore.SignalR.Internal.Protocol; diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubEndPoint.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubEndPoint.cs index ab87e8b365..5f1b889f72 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubEndPoint.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubEndPoint.cs @@ -12,7 +12,6 @@ using System.Threading.Channels; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR.Core; -using Microsoft.AspNetCore.SignalR.Core.Internal; using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.Sockets; diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs index b30944c6ab..320d0097b8 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs @@ -2,9 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNetCore.SignalR.Internal.Protocol; -using MsgPack.Serialization; -using Newtonsoft.Json; namespace Microsoft.AspNetCore.SignalR { @@ -16,8 +13,6 @@ namespace Microsoft.AspNetCore.SignalR /// public static readonly TimeSpan DefaultKeepAliveInterval = TimeSpan.FromSeconds(15); - public JsonSerializerSettings JsonSerializerSettings { get; set; } = JsonHubProtocol.CreateDefaultSerializerSettings(); - public SerializationContext MessagePackSerializationContext { get; set; } = MessagePackHubProtocol.CreateDefaultSerializationContext(); public TimeSpan NegotiateTimeout { get; set; } = TimeSpan.FromSeconds(5); /// diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs index fe2a59f7bd..7cbaab3baa 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs @@ -1,8 +1,12 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; +using System.Linq; using Microsoft.AspNetCore.SignalR.Internal.Protocol; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Newtonsoft.Json; @@ -11,23 +15,37 @@ namespace Microsoft.AspNetCore.SignalR.Internal public class DefaultHubProtocolResolver : IHubProtocolResolver { private readonly IOptions _options; + private readonly ILogger _logger; + private readonly Dictionary _availableProtocols; - public DefaultHubProtocolResolver(IOptions options) + public DefaultHubProtocolResolver(IOptions options, IEnumerable availableProtocols, ILogger logger) { - _options = options; + _options = options ?? throw new ArgumentNullException(nameof(options)); + _logger = logger ?? NullLogger.Instance; + _availableProtocols = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach(var protocol in availableProtocols) + { + if(_availableProtocols.ContainsKey(protocol.Name)) + { + throw new InvalidOperationException($"Multiple Hub Protocols with the name '{protocol.Name}' were registered."); + } + _logger.RegisteredSignalRProtocol(protocol.Name, protocol.GetType()); + _availableProtocols.Add(protocol.Name, protocol); + } } public IHubProtocol GetProtocol(string protocolName, HubConnectionContext connection) { - switch (protocolName?.ToLowerInvariant()) + protocolName = protocolName ?? throw new ArgumentNullException(nameof(protocolName)); + + if (_availableProtocols.TryGetValue(protocolName, out var protocol)) { - case "json": - return new JsonHubProtocol(JsonSerializer.Create(_options.Value.JsonSerializerSettings)); - case "messagepack": - return new MessagePackHubProtocol(_options.Value.MessagePackSerializationContext); - default: - throw new NotSupportedException($"The protocol '{protocolName ?? "(null)"}' is not supported."); + _logger.FoundImplementationForProtocol(protocolName); + return protocol; } + + throw new NotSupportedException($"The protocol '{protocolName ?? "(null)"}' is not supported."); } } } diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreLoggerExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreLoggerExtensions.cs index 5024ed2555..493b1f4bfe 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreLoggerExtensions.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreLoggerExtensions.cs @@ -5,7 +5,7 @@ using System; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.SignalR.Core.Internal +namespace Microsoft.AspNetCore.SignalR.Internal { internal static class SignalRCoreLoggerExtensions { @@ -77,6 +77,13 @@ namespace Microsoft.AspNetCore.SignalR.Core.Internal private static readonly Action _transportBufferFull = LoggerMessage.Define(LogLevel.Debug, new EventId(4, nameof(TransportBufferFull)), "Unable to send Ping message to client, the transport buffer is full."); + // Category: DefaultHubProtocolResolver + private static readonly Action _registeredSignalRProtocol = + LoggerMessage.Define(LogLevel.Debug, new EventId(0, nameof(RegisteredSignalRProtocol)), "Registered SignalR Protocol: {ProtocolName}, implemented by {ImplementationType}."); + + private static readonly Action _foundImplementationForProtocol = + LoggerMessage.Define(LogLevel.Debug, new EventId(1, nameof(FoundImplementationForProtocol)), "Found protocol implementation for requested protocol: {ProtocolName}."); + public static void UsingHubProtocol(this ILogger logger, string hubProtocol) { _usingHubProtocol(logger, hubProtocol, null); @@ -186,5 +193,15 @@ namespace Microsoft.AspNetCore.SignalR.Core.Internal { _transportBufferFull(logger, null); } + + public static void RegisteredSignalRProtocol(this ILogger logger, string protocolName, Type implementationType) + { + _registeredSignalRProtocol(logger, protocolName, implementationType, null); + } + + public static void FoundImplementationForProtocol(this ILogger logger, string protocolName) + { + _foundImplementationForProtocol(logger, protocolName, null); + } } } diff --git a/src/Microsoft.AspNetCore.SignalR.Core/JsonProtocolDependencyInjectionExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Core/JsonProtocolDependencyInjectionExtensions.cs new file mode 100644 index 0000000000..b755f40815 --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Core/JsonProtocolDependencyInjectionExtensions.cs @@ -0,0 +1,37 @@ +using System; +using Microsoft.AspNetCore.SignalR; +using Microsoft.AspNetCore.SignalR.Internal.Protocol; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class JsonProtocolDependencyInjectionExtensions + { + /// + /// Enables the JSON protocol for SignalR. + /// + /// + /// This has no effect if the JSON protocol has already been enabled. + /// + /// The representing the SignalR server to add JSON protocol support to. + /// The value of + public static ISignalRBuilder AddJsonProtocol(this ISignalRBuilder builder) => AddJsonProtocol(builder, _ => { }); + + /// + /// Enables the JSON protocol for SignalR and allows options for the JSON protocol to be configured. + /// + /// + /// Any options configured here will be applied, even if the JSON protocol has already been registered with the server. + /// + /// The representing the SignalR server to add JSON protocol support to. + /// A delegate that can be used to configure the + /// The value of + public static ISignalRBuilder AddJsonProtocol(this ISignalRBuilder builder, Action configure) + { + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.Services.Configure(configure); + return builder; + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs index cad16b740b..0cb45c22c3 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.SignalR; diff --git a/src/Microsoft.AspNetCore.SignalR.MsgPack/Microsoft.AspNetCore.SignalR.MsgPack.csproj b/src/Microsoft.AspNetCore.SignalR.MsgPack/Microsoft.AspNetCore.SignalR.MsgPack.csproj new file mode 100644 index 0000000000..f7df7d9aef --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.MsgPack/Microsoft.AspNetCore.SignalR.MsgPack.csproj @@ -0,0 +1,14 @@ + + + + Provides server-side support for the MsgPack protocol in ASP.NET Core SignalR + netstandard2.0 + true + + + + + + + + diff --git a/src/Microsoft.AspNetCore.SignalR.MsgPack/MsgPackProtocolDependencyInjectionExtensions.cs b/src/Microsoft.AspNetCore.SignalR.MsgPack/MsgPackProtocolDependencyInjectionExtensions.cs new file mode 100644 index 0000000000..c5420f7310 --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.MsgPack/MsgPackProtocolDependencyInjectionExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using Microsoft.AspNetCore.SignalR; +using Microsoft.AspNetCore.SignalR.Internal.Protocol; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class MsgPackProtocolDependencyInjectionExtensions + { + /// + /// Enables the MsgPack protocol for SignalR. + /// + /// + /// This has no effect if the MsgPack protocol has already been enabled. + /// + /// The representing the SignalR server to add MsgPack protocol support to. + /// The value of + public static ISignalRBuilder AddMessagePackProtocol(this ISignalRBuilder builder) => AddMessagePackProtocol(builder, _ => { }); + + /// + /// Enables the MsgPack protocol for SignalR and allows options for the MsgPack protocol to be configured. + /// + /// + /// Any options configured here will be applied, even if the MsgPack protocol has already been registered with the server. + /// + /// The representing the SignalR server to add MsgPack protocol support to. + /// A delegate that can be used to configure the + /// The value of + public static ISignalRBuilder AddMessagePackProtocol(this ISignalRBuilder builder, Action configure) + { + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.Services.Configure(configure); + return builder; + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/MessagePackHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs similarity index 95% rename from src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/MessagePackHubProtocol.cs rename to src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs index 930c71a260..82e610b433 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/MessagePackHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Runtime.ExceptionServices; using Microsoft.AspNetCore.SignalR.Internal.Formatters; +using Microsoft.Extensions.Options; using MsgPack; using MsgPack.Serialization; @@ -17,19 +18,21 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol private const int VoidResult = 2; private const int NonVoidResult = 3; - private readonly SerializationContext _serializationContext; + public static readonly string ProtocolName = "messagepack"; - public string Name => "messagepack"; + public SerializationContext SerializationContext { get; } + + public string Name => ProtocolName; public ProtocolType Type => ProtocolType.Binary; public MessagePackHubProtocol() - : this(CreateDefaultSerializationContext()) + : this(Options.Create(new MessagePackHubProtocolOptions())) { } - public MessagePackHubProtocol(SerializationContext serializationContext) + public MessagePackHubProtocol(IOptions options) { - _serializationContext = serializationContext; + SerializationContext = options.Value.SerializationContext; } public bool TryParseMessages(ReadOnlySpan input, IInvocationBinder binder, out IList messages) @@ -236,7 +239,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol packer.PackString(invocationMessage.InvocationId); } packer.PackString(invocationMessage.Target); - packer.PackObject(invocationMessage.Arguments, _serializationContext); + packer.PackObject(invocationMessage.Arguments, SerializationContext); } private void WriteStreamInvocationMessage(StreamInvocationMessage streamInvocationMessage, Packer packer) @@ -245,7 +248,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol packer.Pack(HubProtocolConstants.StreamInvocationMessageType); packer.PackString(streamInvocationMessage.InvocationId); packer.PackString(streamInvocationMessage.Target); - packer.PackObject(streamInvocationMessage.Arguments, _serializationContext); + packer.PackObject(streamInvocationMessage.Arguments, SerializationContext); } private void WriteStreamingItemMessage(StreamItemMessage streamItemMessage, Packer packer) @@ -253,7 +256,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol packer.PackArrayHeader(3); packer.Pack(HubProtocolConstants.StreamItemMessageType); packer.PackString(streamItemMessage.InvocationId); - packer.PackObject(streamItemMessage.Item, _serializationContext); + packer.PackObject(streamItemMessage.Item, SerializationContext); } private void WriteCompletionMessage(CompletionMessage completionMessage, Packer packer) @@ -274,7 +277,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol packer.PackString(completionMessage.Error); break; case NonVoidResult: - packer.PackObject(completionMessage.Result, _serializationContext); + packer.PackObject(completionMessage.Result, SerializationContext); break; } } @@ -395,7 +398,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol throw new FormatException($"Deserializing object of the `{type.Name}` type for '{field}' failed.", msgPackException); } - public static SerializationContext CreateDefaultSerializationContext() + internal static SerializationContext CreateDefaultSerializationContext() { // serializes objects (here: arguments and results) as maps so that property names are preserved var serializationContext = new SerializationContext { SerializationMethod = SerializationMethod.Map }; diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/MessagePackHubProtocolOptions.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/MessagePackHubProtocolOptions.cs new file mode 100644 index 0000000000..de417ac1e1 --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/MessagePackHubProtocolOptions.cs @@ -0,0 +1,13 @@ +// 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 Microsoft.AspNetCore.SignalR.Internal.Protocol; +using MsgPack.Serialization; + +namespace Microsoft.AspNetCore.SignalR +{ + public class MessagePackHubProtocolOptions + { + public SerializationContext SerializationContext { get; set; } = MessagePackHubProtocol.CreateDefaultSerializationContext(); + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Microsoft.AspNetCore.SignalR.Protocols.MsgPack.csproj b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Microsoft.AspNetCore.SignalR.Protocols.MsgPack.csproj new file mode 100644 index 0000000000..0b1e4602d9 --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Microsoft.AspNetCore.SignalR.Protocols.MsgPack.csproj @@ -0,0 +1,22 @@ + + + + + Implements the SignalR Hub Protocol over MsgPack. This package provides internal infrastructure. + To use MsgPack, use the Microsoft.AspNetCore.SignalR.Client.MsgPack (for the Client) or + Microsoft.AspNetCore.SignalR.MsgPack (for the Server) packages. + + netstandard2.0 + Microsoft.AspNetCore.SignalR + true + + + + + + + + + + + diff --git a/src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs b/src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs index 99431e7665..169ae0cc3d 100644 --- a/src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs +++ b/src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -17,7 +17,8 @@ namespace Microsoft.Extensions.DependencyInjection { services.Configure(configure); services.AddSockets(); - return services.AddSignalRCore(); + return services.AddSignalRCore() + .AddJsonProtocol(); } } } 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 4e32ffcd3f..6c7c640529 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 @@ -17,6 +17,8 @@ + + diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs index 348c1b7288..3952d62f50 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -19,7 +19,8 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests public void ConfigureServices(IServiceCollection services) { - services.AddSignalR(); + services.AddSignalR() + .AddMessagePackProtocol(); services.AddAuthorization(options => { options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy => diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs index d1d297cf42..ea4b0f164a 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Net.Http; diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs index 4223476913..25996b9452 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs @@ -1,7 +1,11 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.SignalR.Internal.Protocol; +using MsgPack.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using Xunit; namespace Microsoft.AspNetCore.SignalR.Client.Tests @@ -30,5 +34,53 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests Assert.Equal("loggerFactory", Assert.Throws(() => new HubConnectionBuilder().WithLoggerFactory(null)).ParamName); } + + [Fact] + public void WithJsonHubProtocolSetsHubProtocolToJsonWithDefaultOptions() + { + Assert.True(new HubConnectionBuilder().WithJsonProtocol().TryGetSetting(HubConnectionBuilderDefaults.HubProtocolKey, out var hubProtocol)); + var actualProtocol = Assert.IsType(hubProtocol); + Assert.IsType(actualProtocol.PayloadSerializer.ContractResolver); + } + + [Fact] + public void WithJsonHubProtocolSetsHubProtocolToJsonWithProvidedOptions() + { + var expectedOptions = new JsonHubProtocolOptions() + { + PayloadSerializerSettings = new JsonSerializerSettings() + { + DateFormatString = "JUST A TEST" + } + }; + + Assert.True(new HubConnectionBuilder().WithJsonProtocol(expectedOptions).TryGetSetting(HubConnectionBuilderDefaults.HubProtocolKey, out var hubProtocol)); + var actualProtocol = Assert.IsType(hubProtocol); + Assert.Equal("JUST A TEST", actualProtocol.PayloadSerializer.DateFormatString); + } + + [Fact] + public void WithMessagePackHubProtocolSetsHubProtocolToMsgPackWithDefaultOptions() + { + Assert.True(new HubConnectionBuilder().WithMessagePackProtocol().TryGetSetting(HubConnectionBuilderDefaults.HubProtocolKey, out var hubProtocol)); + var actualProtocol = Assert.IsType(hubProtocol); + Assert.Equal(SerializationMethod.Map, actualProtocol.SerializationContext.SerializationMethod); + } + + [Fact] + public void WithMessagePackHubProtocolSetsHubProtocolToMsgPackWithProvidedOptions() + { + var expectedOptions = new MessagePackHubProtocolOptions() + { + SerializationContext = new SerializationContext() + { + SerializationMethod = SerializationMethod.Array + } + }; + + Assert.True(new HubConnectionBuilder().WithMessagePackProtocol(expectedOptions).TryGetSetting(HubConnectionBuilderDefaults.HubProtocolKey, out var hubProtocol)); + var actualProtocol = Assert.IsType(hubProtocol); + Assert.Equal(SerializationMethod.Array, actualProtocol.SerializationContext.SerializationMethod); + } } } diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionExtensionsTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionExtensionsTests.cs index 65fc4e6556..0b49ce90a4 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionExtensionsTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionExtensionsTests.cs @@ -125,7 +125,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests public async Task ConnectionNotClosedOnCallbackArgumentCountMismatch() { var connection = new TestConnection(); - var hubConnection = new HubConnection(connection, new JsonHubProtocol(new JsonSerializer()), new LoggerFactory()); + var hubConnection = new HubConnection(connection, new JsonHubProtocol(), new LoggerFactory()); var receiveTcs = new TaskCompletionSource(); try diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionProtocolTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionProtocolTests.cs index a3bdc98478..2b3b2c09c5 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionProtocolTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionProtocolTests.cs @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests public async Task StreamCompletesWhenCompletionMessageIsReceived() { var connection = new TestConnection(); - var hubConnection = new HubConnection(connection, new JsonHubProtocol(new JsonSerializer()), new LoggerFactory()); + var hubConnection = new HubConnection(connection, new JsonHubProtocol(), new LoggerFactory()); try { await hubConnection.StartAsync(); 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 4ebefdd9b0..ac67f9b7a7 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 @@ -11,6 +11,7 @@ + diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs index 209ae66fd4..1b07927a71 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs @@ -7,6 +7,7 @@ using System.IO; using System.Text; using Microsoft.AspNetCore.SignalR.Internal.Formatters; using Microsoft.AspNetCore.SignalR.Internal.Protocol; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Xunit; @@ -67,13 +68,16 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol { expectedOutput = Frame(expectedOutput); - var jsonSerializer = new JsonSerializer + var protocolOptions = new JsonHubProtocolOptions { - NullValueHandling = nullValueHandling, - ContractResolver = camelCase ? new CamelCasePropertyNamesContractResolver() : new DefaultContractResolver() + PayloadSerializerSettings = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + ContractResolver = camelCase ? new CamelCasePropertyNamesContractResolver() : new DefaultContractResolver() + } }; - var protocol = new JsonHubProtocol(jsonSerializer); + var protocol = new JsonHubProtocol(Options.Create(protocolOptions)); using (var ms = new MemoryStream()) { @@ -90,14 +94,17 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol { input = Frame(input); - var jsonSerializer = new JsonSerializer + var protocolOptions = new JsonHubProtocolOptions { - NullValueHandling = nullValueHandling, - ContractResolver = camelCase ? new CamelCasePropertyNamesContractResolver() : new DefaultContractResolver() + PayloadSerializerSettings = new JsonSerializerSettings + { + NullValueHandling = nullValueHandling, + ContractResolver = camelCase ? new CamelCasePropertyNamesContractResolver() : new DefaultContractResolver() + } }; var binder = new TestBinder(expectedMessage); - var protocol = new JsonHubProtocol(jsonSerializer); + var protocol = new JsonHubProtocol(Options.Create(protocolOptions)); protocol.TryParseMessages(Encoding.UTF8.GetBytes(input), binder, out var messages); Assert.Equal(expectedMessage, messages[0], TestHubMessageEqualityComparer.Instance); diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj index bc58f85974..640df4b4f3 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj @@ -12,6 +12,7 @@ + diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs index 2141efa108..6a27ee21d7 100644 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs +++ b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs @@ -2,10 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.SignalR.Redis.Tests { @@ -51,7 +53,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests return null; } - public int Start(ILogger logger) + public void Start(ILogger logger) { logger.LogInformation("Starting docker container"); @@ -59,23 +61,41 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests // use static name 'redisTestContainer' so if the container doesn't get removed we don't keep adding more // use redis base docker image // 10 second timeout to allow redis image to be downloaded - return RunProcess(_path, $"run --rm -p 6379:6379 --name {_dockerContainerName} -d redis", logger, TimeSpan.FromSeconds(10)); + RunProcessAndThrowIfFailed(_path, $"run --rm -p 6379:6379 --name {_dockerContainerName} -d redis", logger, TimeSpan.FromSeconds(10)); } - public int Stop(ILogger logger) + public void Stop(ILogger logger) { logger.LogInformation("Stopping docker container"); - return RunProcess(_path, $"stop {_dockerContainerName}", logger, TimeSpan.FromSeconds(5)); + RunProcessAndThrowIfFailed(_path, $"stop {_dockerContainerName}", logger, TimeSpan.FromSeconds(5)); } - private static int RunProcess(string fileName, string arugments, ILogger logger, TimeSpan timeout) + public int RunCommand(string commandAndArguments, out string output) => + RunCommand(commandAndArguments, NullLogger.Instance, out output); + + public int RunCommand(string commandAndArguments, ILogger logger, out string output) + { + return RunProcess(_path, commandAndArguments, logger, TimeSpan.FromSeconds(5), out output); + } + + private static void RunProcessAndThrowIfFailed(string fileName, string arguments, ILogger logger, TimeSpan timeout) + { + var exitCode = RunProcess(fileName, arguments, logger, timeout, out var output); + + if(exitCode != 0) + { + throw new Exception($"Command '{fileName} {arguments}' failed with exit code '{exitCode}'. Output:{Environment.NewLine}{output}"); + } + } + + private static int RunProcess(string fileName, string arguments, ILogger logger, TimeSpan timeout, out string output) { var process = new Process { StartInfo = new ProcessStartInfo { FileName = fileName, - Arguments = arugments, + Arguments = arguments, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true @@ -84,9 +104,18 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests }; var exitCode = 0; + var lines = new ConcurrentQueue(); process.Exited += (_, __) => exitCode = process.ExitCode; - process.OutputDataReceived += (_, a) => LogIfNotNull(logger.LogInformation, "stdout: {0}", a.Data); - process.ErrorDataReceived += (_, a) => LogIfNotNull(logger.LogError, "stderr: {0}", a.Data); + process.OutputDataReceived += (_, a) => + { + LogIfNotNull(logger.LogInformation, "stdout: {0}", a.Data); + lines.Enqueue(a.Data); + }; + process.ErrorDataReceived += (_, a) => + { + LogIfNotNull(logger.LogError, "stderr: {0}", a.Data); + lines.Enqueue(a.Data); + }; process.Start(); @@ -95,6 +124,8 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests process.WaitForExit((int)timeout.TotalMilliseconds); + output = string.Join(Environment.NewLine, lines); + return exitCode; } @@ -106,4 +137,4 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests } } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj index 5ca77fbb65..0b668c4efb 100644 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj @@ -11,6 +11,8 @@ + + diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs index 562880a569..3df0d769a7 100644 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs +++ b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs @@ -9,7 +9,31 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class SkipIfDockerNotPresentAttribute : Attribute, ITestCondition { - public bool IsMet => Docker.Default != null; - public string SkipReason => "Docker is not installed on the host machine."; + public bool IsMet => CheckDocker(); + public string SkipReason { get; private set; } = "Docker is not available"; + + private bool CheckDocker() + { + if(Docker.Default != null) + { + // Docker is present, but is it working? + if (Docker.Default.RunCommand("ps", out var output) != 0) + { + SkipReason = $"Failed to invoke test command 'docker ps'. Output: {output}"; + } + else + { + // We have a docker + return true; + } + } + else + { + SkipReason = "Docker is not installed on the host machine."; + } + + // If we get here, we don't have a docker + return false; + } } } diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs index 149c1a4749..5567be0df1 100644 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs +++ b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs @@ -12,6 +12,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis.Tests public void ConfigureServices(IServiceCollection services) { services.AddSignalR() + .AddMessagePackProtocol() .AddRedis(options => { // We start the servers before starting redis so we want to time them out ASAP diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs index 734571d404..226104230e 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs @@ -42,6 +42,30 @@ namespace System.Threading.Tasks return await task; } + public static async Task OrThrowIfOtherFails(this Task task, Task otherTask) + { + var completed = await Task.WhenAny(task, otherTask); + if(completed == otherTask && otherTask.IsFaulted) + { + // Manifest the exception + otherTask.GetAwaiter().GetResult(); + throw new Exception("Unreachable code"); + } + else + { + // Await the task we were asked to await. Either it's finished, or the otherTask finished successfully, and it's not our job to check that + await task; + } + } + + public static async Task OrThrowIfOtherFails(this Task task, Task otherTask) + { + await OrThrowIfOtherFails((Task)task, otherTask); + + // If we get here, 'task' is finished and succeeded. + return task.GetAwaiter().GetResult(); + } + private static string GetMessage(string memberName, string filePath, int? lineNumber) { if (!string.IsNullOrEmpty(memberName)) diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTestUtils/Utils.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTestUtils/Utils.cs index 4ee7cdfbcf..14bf5d2ce4 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTestUtils/Utils.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTestUtils/Utils.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -54,8 +54,10 @@ namespace Microsoft.AspNetCore.SignalR.Tests.HubEndpointTestUtils { var services = new ServiceCollection(); services.AddOptions() - .AddLogging() - .AddSignalR(); + .AddLogging(); + + services.AddSignalR() + .AddMessagePackProtocol(); addServices?.Invoke(services); diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs index 5fc80a9569..2341b33bcf 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.SignalR.Tests.HubEndpointTestUtils; using Microsoft.AspNetCore.Sockets; using Microsoft.AspNetCore.Sockets.Features; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Moq; using MsgPack; using MsgPack.Serialization; @@ -969,7 +970,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests Assert.Equal("Second and Third", invocation.Arguments[0]); // Check that first client only got the completion message - var hubMessage= await firstClient.ReadAsync().OrTimeout(); + var hubMessage = await firstClient.ReadAsync().OrTimeout(); Assert.IsType(hubMessage); Assert.Null(firstClient.TryRead()); @@ -1338,7 +1339,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests var endPointLifetime = endPoint.OnConnectedAsync(client.Connection); - await client.Connected.OrTimeout(); + // Wait for a connection, or for the endpoint to fail. + await client.Connected.OrThrowIfOtherFails(endPointLifetime).OrTimeout(); var messages = await client.StreamAsync(method, 4).OrTimeout(); @@ -1470,13 +1472,15 @@ namespace Microsoft.AspNetCore.SignalR.Tests { var serviceProvider = HubEndPointTestUtils.CreateServiceProvider(services => { - services.AddSignalR(o => - { - o.JsonSerializerSettings = new JsonSerializerSettings + services + .AddSignalR() + .AddJsonProtocol(o => { - ContractResolver = new DefaultContractResolver() - }; - }); + o.PayloadSerializerSettings = new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver() + }; + }); }); var endPoint = serviceProvider.GetService>(); @@ -1532,20 +1536,19 @@ namespace Microsoft.AspNetCore.SignalR.Tests [Fact] public async Task HubOptionsCanUseCustomMessagePackSettings() { - var serializationContext = MessagePackHubProtocol.CreateDefaultSerializationContext(); - serializationContext.SerializationMethod = SerializationMethod.Array; - var serviceProvider = HubEndPointTestUtils.CreateServiceProvider(services => { - services.AddSignalR(options => - { - options.MessagePackSerializationContext = serializationContext; - }); + services.AddSignalR() + .AddMessagePackProtocol(options => + { + options.SerializationContext.SerializationMethod = SerializationMethod.Array; + }); }); var endPoint = serviceProvider.GetService>(); - using (var client = new TestClient(synchronousCallbacks: false, protocol: new MessagePackHubProtocol(serializationContext))) + var msgPackOptions = serviceProvider.GetRequiredService>(); + using (var client = new TestClient(synchronousCallbacks: false, protocol: new MessagePackHubProtocol(msgPackOptions))) { var transportFeature = new Mock(); transportFeature.SetupGet(f => f.TransportCapabilities).Returns(TransferMode.Binary); @@ -1633,7 +1636,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests var endPointLifetime = endPoint.OnConnectedAsync(client.Connection); - await client.Connected.OrTimeout(); + await client.Connected.OrThrowIfOtherFails(endPointLifetime).OrTimeout(); await client.SendInvocationAsync(nameof(MethodHub.SendAnonymousObject)).OrTimeout(); diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs index fb38adaf9f..ea571661a8 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs @@ -3,40 +3,67 @@ using System; using System.Collections.Generic; -using System.Threading.Channels; using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.Sockets; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Moq; -using Newtonsoft.Json; using Xunit; namespace Microsoft.AspNetCore.SignalR.Common.Protocol.Tests { public class DefaultHubProtocolResolverTests { + private static readonly IList AllProtocols = new List() + { + new JsonHubProtocol(), + new MessagePackHubProtocol() + }; + [Theory] [MemberData(nameof(HubProtocols))] public void DefaultHubProtocolResolverTestsCanCreateSupportedProtocols(IHubProtocol protocol) { var mockConnection = new Mock(new Mock().Object, TimeSpan.FromSeconds(30), NullLoggerFactory.Instance); + var resolver = new DefaultHubProtocolResolver(Options.Create(new HubOptions()), AllProtocols, NullLogger.Instance); Assert.IsType( protocol.GetType(), - new DefaultHubProtocolResolver(Options.Create(new HubOptions())).GetProtocol(protocol.Name, mockConnection.Object)); + resolver.GetProtocol(protocol.Name, mockConnection.Object)); } - [Theory] - [InlineData(null)] - [InlineData("dummy")] - public void DefaultHubProtocolResolverThrowsForNotSupportedProtocol(string protocolName) + [Fact] + public void DefaultHubProtocolResolverThrowsForNullProtocol() { var mockConnection = new Mock(new Mock().Object, TimeSpan.FromSeconds(30), NullLoggerFactory.Instance); - var exception = Assert.Throws( - () => new DefaultHubProtocolResolver(Options.Create(new HubOptions())).GetProtocol(protocolName, mockConnection.Object)); + var resolver = new DefaultHubProtocolResolver(Options.Create(new HubOptions()), AllProtocols, NullLogger.Instance); + var exception = Assert.Throws( + () => resolver.GetProtocol(null, mockConnection.Object)); - Assert.Equal($"The protocol '{protocolName ?? "(null)"}' is not supported.", exception.Message); + Assert.Equal("protocolName", exception.ParamName); + } + + [Fact] + public void DefaultHubProtocolResolverThrowsForNotSupportedProtocol() + { + var mockConnection = new Mock(new Mock().Object, TimeSpan.FromSeconds(30), NullLoggerFactory.Instance); + var resolver = new DefaultHubProtocolResolver(Options.Create(new HubOptions()), AllProtocols, NullLogger.Instance); + var exception = Assert.Throws( + () => resolver.GetProtocol("notARealProtocol", mockConnection.Object)); + + Assert.Equal("The protocol 'notARealProtocol' is not supported.", exception.Message); + } + + [Fact] + public void RegisteringMultipleHubProtocolsFails() + { + var mockConnection = new Mock(new Mock().Object, TimeSpan.FromSeconds(30), NullLoggerFactory.Instance); + var exception = Assert.Throws(() => new DefaultHubProtocolResolver(Options.Create(new HubOptions()), new[] { + new JsonHubProtocol(), + new JsonHubProtocol() + }, NullLogger.Instance)); + + Assert.Equal($"Multiple Hub Protocols with the name '{JsonHubProtocol.ProtocolName}' were registered.", exception.Message); } public static IEnumerable HubProtocols => 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 dda3884804..49e135404e 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj @@ -22,6 +22,7 @@ + diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/SignalRDependencyInjectionExtensionsTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/SignalRDependencyInjectionExtensionsTests.cs deleted file mode 100644 index 3652afb2de..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Tests/SignalRDependencyInjectionExtensionsTests.cs +++ /dev/null @@ -1,38 +0,0 @@ -// 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 Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using MsgPack.Serialization; -using Xunit; - -namespace Microsoft.AspNetCore.SignalR.Tests -{ - public class SignalRDependencyInjectionExtensionsTests - { - [Fact] - public void JSonSerializerSettingsShouldNotBeNullInOptions() - { - var services = new ServiceCollection(); - services.AddOptions(); - services.AddSignalR(); - var serviceProvider = services.BuildServiceProvider(); - var hubOptions = serviceProvider.GetService>(); - Assert.NotNull(hubOptions.Value.JsonSerializerSettings); - } - - [Fact] - public void MessagePackSerializationContextInOptionsIsSetAndHasDefaultSettings() - { - var services = new ServiceCollection(); - services.AddOptions(); - services.AddSignalR(); - var serviceProvider = services.BuildServiceProvider(); - var hubOptions = serviceProvider.GetService>(); - var serializationContext = hubOptions.Value.MessagePackSerializationContext; - Assert.NotNull(serializationContext); - Assert.Equal(SerializationMethod.Map, serializationContext.SerializationMethod); - Assert.True(serializationContext.CompatibilityOptions.AllowAsymmetricSerializer); - } - } -} diff --git a/test/xunit.runner.json b/test/xunit.runner.json index 874abebe0b..f30651267e 100644 --- a/test/xunit.runner.json +++ b/test/xunit.runner.json @@ -1,4 +1,4 @@ { - "longRunningTestSeconds": 5, + "longRunningTestSeconds": 30, "diagnosticMessages": true }