Dispose Hubs from ActivatorUtilities
This commit is contained in:
parent
7c8eeb11f4
commit
28e3c8331b
|
|
@ -43,6 +43,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SocialWeather", "samples\So
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.SignalR.Test.Server", "test\Microsoft.AspNetCore.SignalR.Test.Server\Microsoft.AspNetCore.SignalR.Test.Server.xproj", "{A0BF246B-FE7D-4E12-99BF-FFDC131B85D8}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.SignalR.Tests", "test\Microsoft.AspNetCore.SignalR.Tests\Microsoft.AspNetCore.SignalR.Tests.xproj", "{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -105,6 +107,10 @@ Global
|
|||
{A0BF246B-FE7D-4E12-99BF-FFDC131B85D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A0BF246B-FE7D-4E12-99BF-FFDC131B85D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A0BF246B-FE7D-4E12-99BF-FFDC131B85D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -124,5 +130,6 @@ Global
|
|||
{300979F6-A02E-407A-B8DF-F6200806C18D} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
|
||||
{8D789F94-CB74-45FD-ACE7-92AF6E55042E} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
|
||||
{A0BF246B-FE7D-4E12-99BF-FFDC131B85D8} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
|
||||
{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -63,9 +63,15 @@ namespace Microsoft.AspNetCore.SignalR
|
|||
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
var hub = scope.ServiceProvider.GetService<THub>() ?? Activator.CreateInstance<THub>();
|
||||
InitializeHub(connection, hub);
|
||||
bool created;
|
||||
var hub = CreateHub(scope.ServiceProvider, connection, out created);
|
||||
|
||||
await hub.OnConnectedAsync();
|
||||
|
||||
if (created)
|
||||
{
|
||||
hub.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
await DispatchMessagesAsync(connection);
|
||||
|
|
@ -74,9 +80,15 @@ namespace Microsoft.AspNetCore.SignalR
|
|||
{
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
var hub = scope.ServiceProvider.GetService<THub>() ?? Activator.CreateInstance<THub>();
|
||||
InitializeHub(connection, hub);
|
||||
bool created;
|
||||
var hub = CreateHub(scope.ServiceProvider, connection, out created);
|
||||
|
||||
await hub.OnDisconnectedAsync();
|
||||
|
||||
if (created)
|
||||
{
|
||||
hub.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
await _lifetimeManager.OnDisconnectedAsync(connection);
|
||||
|
|
@ -132,11 +144,22 @@ namespace Microsoft.AspNetCore.SignalR
|
|||
}
|
||||
}
|
||||
|
||||
private void InitializeHub(Connection connection, THub hub)
|
||||
private THub CreateHub(IServiceProvider provider, Connection connection, out bool created)
|
||||
{
|
||||
var hub = provider.GetService<THub>();
|
||||
created = false;
|
||||
|
||||
if (hub == null)
|
||||
{
|
||||
hub = ActivatorUtilities.CreateInstance<THub>(provider);
|
||||
created = true;
|
||||
}
|
||||
|
||||
hub.Clients = _hubContext.Clients;
|
||||
hub.Context = new HubCallerContext(connection);
|
||||
hub.Groups = new GroupManager<THub>(connection, _lifetimeManager);
|
||||
|
||||
return hub;
|
||||
}
|
||||
|
||||
private void DiscoverHubMethods()
|
||||
|
|
@ -169,17 +192,8 @@ namespace Microsoft.AspNetCore.SignalR
|
|||
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
{
|
||||
var hub = scope.ServiceProvider.GetService<THub>();
|
||||
|
||||
bool created = false;
|
||||
|
||||
if (hub == null)
|
||||
{
|
||||
hub = Activator.CreateInstance<THub>();
|
||||
created = true;
|
||||
}
|
||||
|
||||
InitializeHub(connection, hub);
|
||||
bool created;
|
||||
var hub = CreateHub(scope.ServiceProvider, connection, out created);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -212,8 +226,7 @@ namespace Microsoft.AspNetCore.SignalR
|
|||
|
||||
if (created)
|
||||
{
|
||||
// Dispose the object if it's disposable and we created it
|
||||
(hub as IDisposable)?.Dispose();
|
||||
hub.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
// 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.IO.Pipelines;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Internal;
|
||||
using Microsoft.AspNetCore.Sockets;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.SignalR.Tests
|
||||
{
|
||||
public class HubEndpointTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task HubsAreDisposed()
|
||||
{
|
||||
var trackDispose = new TrackDispose();
|
||||
var serviceProvider = CreateServiceProvider(s => s.AddSingleton(trackDispose));
|
||||
|
||||
var endPoint = serviceProvider.GetService<HubEndPoint<TestHub>>();
|
||||
|
||||
using (var connectionWrapper = new ConnectionWrapper())
|
||||
{
|
||||
var endPointTask = endPoint.OnConnectedAsync(connectionWrapper.Connection);
|
||||
|
||||
await connectionWrapper.HttpConnection.Input.ReadingStarted;
|
||||
|
||||
// kill the connection
|
||||
connectionWrapper.Connection.Channel.Dispose();
|
||||
|
||||
await endPointTask;
|
||||
|
||||
Assert.Equal(2, trackDispose.DisposeCount);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestHub : Hub
|
||||
{
|
||||
private TrackDispose _trackDispose;
|
||||
|
||||
public TestHub(TrackDispose trackDispose)
|
||||
{
|
||||
_trackDispose = trackDispose;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool dispose)
|
||||
{
|
||||
if (dispose)
|
||||
{
|
||||
_trackDispose.DisposeCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TrackDispose
|
||||
{
|
||||
public int DisposeCount = 0;
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServiceProvider(Action<ServiceCollection> addServices = null)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddOptions()
|
||||
.AddLogging()
|
||||
.AddSignalR();
|
||||
|
||||
addServices?.Invoke(services);
|
||||
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
private class ConnectionWrapper : IDisposable
|
||||
{
|
||||
private PipelineFactory _factory;
|
||||
private HttpConnection _httpConnection;
|
||||
|
||||
public Connection Connection;
|
||||
public HttpConnection HttpConnection => (HttpConnection)Connection.Channel;
|
||||
|
||||
public ConnectionWrapper(string format = "json")
|
||||
{
|
||||
_factory = new PipelineFactory();
|
||||
_httpConnection = new HttpConnection(_factory);
|
||||
|
||||
var lifetime = new ApplicationLifetime(new Logger<ApplicationLifetime>(new LoggerFactory()), Enumerable.Empty<IApplicationLifetimeEvents>());
|
||||
var connectionManager = new ConnectionManager(lifetime);
|
||||
|
||||
Connection = connectionManager.AddNewConnection(_httpConnection).Connection;
|
||||
Connection.Metadata["formatType"] = format;
|
||||
Connection.User = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Connection.Channel.Dispose();
|
||||
_httpConnection.Dispose();
|
||||
_factory.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>1ce2b3be-056c-41e3-a5f5-6a1ef1d288ba</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Microsoft.AspNetCore.SignalR.Tests")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("1ce2b3be-056c-41e3-a5f5-6a1ef1d288ba")]
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"buildOptions": {
|
||||
"warningsAsErrors": true
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"dotnet-test-xunit": "2.2.0-*",
|
||||
"Microsoft.AspNetCore.Hosting": "1.2.0-*",
|
||||
"Microsoft.AspNetCore.Sockets": {
|
||||
"target": "project"
|
||||
},
|
||||
"Microsoft.AspNetCore.SignalR": {
|
||||
"target": "project"
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": "1.2.0-*",
|
||||
"Microsoft.Extensions.Logging": "1.2.0-*",
|
||||
"xunit": "2.2.0-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"netcoreapp1.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"version": "1.1.0-*",
|
||||
"type": "platform"
|
||||
}
|
||||
}
|
||||
},
|
||||
"net451": { }
|
||||
},
|
||||
"testRunner": "xunit"
|
||||
}
|
||||
Loading…
Reference in New Issue