Starting HubOptions (#743)

* Added JsonSerializerSettings
This commit is contained in:
BrennanConroy 2017-08-23 15:30:08 -07:00 committed by GitHub
parent 76ea3cf24c
commit 978f5cebc0
6 changed files with 81 additions and 6 deletions

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection
@ -9,6 +10,12 @@ namespace Microsoft.Extensions.DependencyInjection
{ {
public static ISignalRBuilder AddSignalR(this IServiceCollection services) public static ISignalRBuilder AddSignalR(this IServiceCollection services)
{ {
return AddSignalR(services, _ => { });
}
public static ISignalRBuilder AddSignalR(this IServiceCollection services, Action<HubOptions> configure)
{
services.Configure(configure);
services.AddSockets(); services.AddSockets();
return services.AddSignalRCore(); return services.AddSignalRCore();
} }

View File

@ -13,13 +13,14 @@ using System.Threading.Tasks.Channels;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR.Features; using Microsoft.AspNetCore.SignalR.Features;
using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal;
using Microsoft.AspNetCore.SignalR.Internal.Encoders;
using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.SignalR.Internal.Protocol;
using Microsoft.AspNetCore.Sockets; using Microsoft.AspNetCore.Sockets;
using Microsoft.AspNetCore.Sockets.Features; using Microsoft.AspNetCore.Sockets.Features;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Internal; using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.SignalR.Internal.Encoders; using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.SignalR namespace Microsoft.AspNetCore.SignalR
{ {
@ -36,16 +37,19 @@ namespace Microsoft.AspNetCore.SignalR
private readonly ILogger<HubEndPoint<THub>> _logger; private readonly ILogger<HubEndPoint<THub>> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IHubProtocolResolver _protocolResolver; private readonly IHubProtocolResolver _protocolResolver;
private readonly IOptions<HubOptions> _hubOptions;
public HubEndPoint(HubLifetimeManager<THub> lifetimeManager, public HubEndPoint(HubLifetimeManager<THub> lifetimeManager,
IHubProtocolResolver protocolResolver, IHubProtocolResolver protocolResolver,
IHubContext<THub> hubContext, IHubContext<THub> hubContext,
IOptions<HubOptions> hubOptions,
ILogger<HubEndPoint<THub>> logger, ILogger<HubEndPoint<THub>> logger,
IServiceScopeFactory serviceScopeFactory) IServiceScopeFactory serviceScopeFactory)
{ {
_protocolResolver = protocolResolver; _protocolResolver = protocolResolver;
_lifetimeManager = lifetimeManager; _lifetimeManager = lifetimeManager;
_hubContext = hubContext; _hubContext = hubContext;
_hubOptions = hubOptions;
_logger = logger; _logger = logger;
_serviceScopeFactory = serviceScopeFactory; _serviceScopeFactory = serviceScopeFactory;

View File

@ -0,0 +1,12 @@
// 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 Newtonsoft.Json;
namespace Microsoft.AspNetCore.SignalR
{
public class HubOptions
{
public JsonSerializerSettings JsonSerializerSettings { get; set; }
}
}

View File

@ -3,18 +3,26 @@
using System; using System;
using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.SignalR.Internal.Protocol;
using Microsoft.Extensions.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Microsoft.AspNetCore.SignalR.Internal namespace Microsoft.AspNetCore.SignalR.Internal
{ {
public class DefaultHubProtocolResolver : IHubProtocolResolver public class DefaultHubProtocolResolver : IHubProtocolResolver
{ {
private readonly IOptions<HubOptions> _options;
public DefaultHubProtocolResolver(IOptions<HubOptions> options)
{
_options = options;
}
public IHubProtocol GetProtocol(string protocolName, HubConnectionContext connection) public IHubProtocol GetProtocol(string protocolName, HubConnectionContext connection)
{ {
switch (protocolName?.ToLowerInvariant()) switch (protocolName?.ToLowerInvariant())
{ {
case "json": case "json":
return new JsonHubProtocol(new JsonSerializer()); return new JsonHubProtocol(JsonSerializer.Create(_options.Value.JsonSerializerSettings));
case "messagepack": case "messagepack":
return new MessagePackHubProtocol(); return new MessagePackHubProtocol();
default: default:

View File

@ -10,9 +10,10 @@ using System.Threading.Tasks.Channels;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.SignalR.Internal.Protocol;
using Microsoft.AspNetCore.SignalR.Tests.Common; using Microsoft.AspNetCore.SignalR.Tests.Common;
using Microsoft.CSharp;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Moq; using Moq;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.SignalR.Tests namespace Microsoft.AspNetCore.SignalR.Tests
@ -491,7 +492,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
await Task.WhenAll(firstClient.Connected, secondClient.Connected).OrTimeout(); await Task.WhenAll(firstClient.Connected, secondClient.Connected).OrTimeout();
await firstClient.SendInvocationAsync("BroadcastMethod", "test").OrTimeout(); await firstClient.SendInvocationAsync(nameof(MethodHub.BroadcastMethod), "test").OrTimeout();
foreach (var result in await Task.WhenAll( foreach (var result in await Task.WhenAll(
firstClient.ReadAsync(), firstClient.ReadAsync(),
@ -813,6 +814,43 @@ namespace Microsoft.AspNetCore.SignalR.Tests
} }
} }
[Fact]
public async Task HubOptionsCanUseCustomJsonSerializerSettings()
{
var serviceProvider = CreateServiceProvider(services =>
{
services.AddSignalR(o =>
{
o.JsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
});
});
var endPoint = serviceProvider.GetService<HubEndPoint<MethodHub>>();
using (var client = new TestClient())
{
var endPointLifetime = endPoint.OnConnectedAsync(client.Connection);
await client.Connected.OrTimeout();
await client.SendInvocationAsync(nameof(MethodHub.BroadcastItem)).OrTimeout();
var message = await client.ReadAsync().OrTimeout() as InvocationMessage;
var customItem = message.Arguments[0].ToString();
// Originally "Message" and "paramName"
Assert.Contains("message", customItem);
Assert.Contains("paramName", customItem);
client.Dispose();
await endPointLifetime.OrTimeout();
}
}
private static void AssertHubMessage(HubMessage expected, HubMessage actual) private static void AssertHubMessage(HubMessage expected, HubMessage actual)
{ {
// We aren't testing InvocationIds here // We aren't testing InvocationIds here
@ -1060,6 +1098,11 @@ namespace Microsoft.AspNetCore.SignalR.Tests
return Clients.All.InvokeAsync("Broadcast", message); return Clients.All.InvokeAsync("Broadcast", message);
} }
public Task BroadcastItem()
{
return Clients.All.InvokeAsync("Broadcast", new { Message = "test", paramName = "test" });
}
public Task<int> TaskValueMethod() public Task<int> TaskValueMethod()
{ {
return Task.FromResult(42); return Task.FromResult(42);

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks.Channels;
using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal;
using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.SignalR.Internal.Protocol;
using Microsoft.AspNetCore.Sockets; using Microsoft.AspNetCore.Sockets;
using Microsoft.Extensions.Options;
using Moq; using Moq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xunit; using Xunit;
@ -22,7 +23,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Protocol.Tests
var mockConnection = new Mock<HubConnectionContext>(Channel.CreateUnbounded<HubMessage>().Out, new Mock<ConnectionContext>().Object); var mockConnection = new Mock<HubConnectionContext>(Channel.CreateUnbounded<HubMessage>().Out, new Mock<ConnectionContext>().Object);
Assert.IsType( Assert.IsType(
protocol.GetType(), protocol.GetType(),
new DefaultHubProtocolResolver().GetProtocol(protocol.Name, mockConnection.Object)); new DefaultHubProtocolResolver(Options.Create(new HubOptions())).GetProtocol(protocol.Name, mockConnection.Object));
} }
[Theory] [Theory]
@ -32,7 +33,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Protocol.Tests
{ {
var mockConnection = new Mock<HubConnectionContext>(Channel.CreateUnbounded<HubMessage>().Out, new Mock<ConnectionContext>().Object); var mockConnection = new Mock<HubConnectionContext>(Channel.CreateUnbounded<HubMessage>().Out, new Mock<ConnectionContext>().Object);
var exception = Assert.Throws<NotSupportedException>( var exception = Assert.Throws<NotSupportedException>(
() => new DefaultHubProtocolResolver().GetProtocol(protocolName, mockConnection.Object)); () => new DefaultHubProtocolResolver(Options.Create(new HubOptions())).GetProtocol(protocolName, mockConnection.Object));
Assert.Equal($"The protocol '{protocolName ?? "(null)"}' is not supported.", exception.Message); Assert.Equal($"The protocol '{protocolName ?? "(null)"}' is not supported.", exception.Message);
} }