Browse Source

#2747: Initial SignalR Package

pull/3947/head
Halil İbrahim Kalkan 6 years ago
parent
commit
2d4ab63deb
  1. 9
      framework/Volo.Abp.sln
  2. 3
      framework/src/Volo.Abp.AspNetCore.SignalR/FodyWeavers.xml
  3. 30
      framework/src/Volo.Abp.AspNetCore.SignalR/FodyWeavers.xsd
  4. 27
      framework/src/Volo.Abp.AspNetCore.SignalR/Properties/launchSettings.json
  5. 23
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo.Abp.AspNetCore.SignalR.csproj
  6. 115
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpAspNetCoreSignalRModule.cs
  7. 43
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalRConventionalRegistrar.cs
  8. 14
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalROptions.cs
  9. 43
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/HubConfig.cs
  10. 33
      framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/HubRouteAttribute.cs
  11. 1
      nupkg/common.ps1

9
framework/Volo.Abp.sln

@ -283,7 +283,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.TextTemplating", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.TextTemplating.Tests", "test\Volo.Abp.TextTemplating.Tests\Volo.Abp.TextTemplating.Tests.csproj", "{251C7FD3-D313-4BCE-8068-352EC7EEA275}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Validation.Abstractions", "src\Volo.Abp.Validation.Abstractions\Volo.Abp.Validation.Abstractions.csproj", "{FA5D1D6A-2A05-4A3D-99C1-2B6C1D1F99A3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Validation.Abstractions", "src\Volo.Abp.Validation.Abstractions\Volo.Abp.Validation.Abstractions.csproj", "{FA5D1D6A-2A05-4A3D-99C1-2B6C1D1F99A3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.SignalR", "src\Volo.Abp.AspNetCore.SignalR\Volo.Abp.AspNetCore.SignalR.csproj", "{B64FCE08-E9D2-4984-BF12-FE199F257416}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -847,6 +849,10 @@ Global
{FA5D1D6A-2A05-4A3D-99C1-2B6C1D1F99A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA5D1D6A-2A05-4A3D-99C1-2B6C1D1F99A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA5D1D6A-2A05-4A3D-99C1-2B6C1D1F99A3}.Release|Any CPU.Build.0 = Release|Any CPU
{B64FCE08-E9D2-4984-BF12-FE199F257416}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B64FCE08-E9D2-4984-BF12-FE199F257416}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B64FCE08-E9D2-4984-BF12-FE199F257416}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B64FCE08-E9D2-4984-BF12-FE199F257416}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -991,6 +997,7 @@ Global
{9E53F91F-EACD-4191-A487-E727741F1311} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{251C7FD3-D313-4BCE-8068-352EC7EEA275} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{FA5D1D6A-2A05-4A3D-99C1-2B6C1D1F99A3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{B64FCE08-E9D2-4984-BF12-FE199F257416} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

3
framework/src/Volo.Abp.AspNetCore.SignalR/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
framework/src/Volo.Abp.AspNetCore.SignalR/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

27
framework/src/Volo.Abp.AspNetCore.SignalR/Properties/launchSettings.json

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:53900/",
"sslPort": 44362
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Volo.Abp.SignalR": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

23
framework/src/Volo.Abp.AspNetCore.SignalR/Volo.Abp.AspNetCore.SignalR.csproj

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Volo.Abp.AspNetCore.SignalR</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.SignalR</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<IsPackable>true</IsPackable>
<OutputType>Library</OutputType>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore\Volo.Abp.AspNetCore.csproj" />
</ItemGroup>
</Project>

115
framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpAspNetCoreSignalRModule.cs

@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.SignalR
{
[DependsOn(
typeof(AbpAspNetCoreModule)
)]
public class AbpAspNetCoreSignalRModule : AbpModule
{
private static readonly MethodInfo MapHubGenericMethodInfo =
typeof(AbpAspNetCoreSignalRModule)
.GetMethod("MapHub", BindingFlags.Static | BindingFlags.NonPublic);
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddConventionalRegistrar(new AbpSignalRConventionalRegistrar());
AutoAddHubTypes(context.Services);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddSignalR();
Configure<AbpEndpointRouterOptions>(options =>
{
options.EndpointConfigureActions.Add(endpointContext =>
{
var signalROptions = endpointContext
.ScopeServiceProvider
.GetRequiredService<IOptions<AbpSignalROptions>>()
.Value;
foreach (var hubConfig in signalROptions.Hubs)
{
MapHubType(
hubConfig.HubType,
endpointContext.Endpoints,
hubConfig.RoutePattern,
opts =>
{
foreach (var configureAction in hubConfig.ConfigureActions)
{
configureAction(opts);
}
}
);
}
});
});
}
private void AutoAddHubTypes(IServiceCollection services)
{
var hubTypes = new List<Type>();
services.OnRegistred(context =>
{
if (typeof(Hub).IsAssignableFrom(context.ImplementationType))
{
hubTypes.Add(context.ImplementationType);
}
});
services.Configure<AbpSignalROptions>(options =>
{
foreach (var hubType in hubTypes)
{
options.Hubs.Add(HubConfig.Create(hubType));
}
});
}
private void MapHubType(
Type hubType,
IEndpointRouteBuilder endpoints,
string pattern,
Action<HttpConnectionDispatcherOptions> configureOptions)
{
MapHubGenericMethodInfo
.MakeGenericMethod(hubType)
.Invoke(
this,
new object[]
{
endpoints,
pattern,
configureOptions
}
);
}
// ReSharper disable once UnusedMember.Local (used via reflection)
private static void MapHub<THub>(
IEndpointRouteBuilder endpoints,
string pattern,
Action<HttpConnectionDispatcherOptions> configureOptions)
where THub : Hub
{
endpoints.MapHub<THub>(
pattern,
configureOptions
);
}
}
}

43
framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalRConventionalRegistrar.cs

@ -0,0 +1,43 @@
using System;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.SignalR
{
public class AbpSignalRConventionalRegistrar : ConventionalRegistrarBase
{
public override void AddType(IServiceCollection services, Type type)
{
if (IsConventionalRegistrationDisabled(type))
{
return;
}
if (!IsHub(type))
{
return;
}
var serviceTypes = ExposedServiceExplorer.GetExposedServices(type);
TriggerServiceExposing(services, type, serviceTypes);
foreach (var serviceType in serviceTypes)
{
services.Add(
ServiceDescriptor.Describe(
serviceType,
type,
ServiceLifetime.Transient
)
);
}
}
private static bool IsHub(Type type)
{
return typeof(Hub).IsAssignableFrom(type);
}
}
}

14
framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalROptions.cs

@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.SignalR
{
public class AbpSignalROptions
{
public List<HubConfig> Hubs { get; }
public AbpSignalROptions()
{
Hubs = new List<HubConfig>();
}
}
}

43
framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/HubConfig.cs

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.SignalR;
namespace Volo.Abp.AspNetCore.SignalR
{
public class HubConfig
{
[NotNull]
public Type HubType { get; }
[NotNull]
public string RoutePattern { get; set; }
[NotNull]
public List<Action<HttpConnectionDispatcherOptions>> ConfigureActions { get; set; }
public HubConfig(
[NotNull] Type hubType,
[NotNull] string routePattern)
{
HubType = Check.NotNull(hubType, nameof(hubType));
RoutePattern = Check.NotNullOrWhiteSpace(routePattern, nameof(routePattern));
ConfigureActions = new List<Action<HttpConnectionDispatcherOptions>>();
}
public static HubConfig Create<THub>()
where THub : Hub
{
return Create(typeof(THub));
}
public static HubConfig Create(Type hubType)
{
return new HubConfig(
hubType,
HubRouteAttribute.GetRoutePattern(hubType)
);
}
}
}

33
framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/HubRouteAttribute.cs

@ -0,0 +1,33 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.SignalR;
namespace Volo.Abp.AspNetCore.SignalR
{
public class HubRouteAttribute : Attribute
{
public string RoutePattern { get; set; }
public HubRouteAttribute(string routePattern)
{
RoutePattern = routePattern;
}
public static string GetRoutePattern<THub>()
where THub : Hub
{
return GetRoutePattern(typeof(THub));
}
public static string GetRoutePattern(Type hubType)
{
var routeAttribute = hubType.GetSingleAttributeOrNull<HubRouteAttribute>();
if (routeAttribute != null)
{
return routeAttribute.RoutePattern;
}
return "/signalr-hubs/" + hubType.Name.RemovePostFix("Hub").ToKebabCase();
}
}
}

1
nupkg/common.ps1

@ -41,6 +41,7 @@ $projects = (
"framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared",
"framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets",
"framework/src/Volo.Abp.AspNetCore.Serilog",
"framework/src/Volo.Abp.AspNetCore.SignalR",
"framework/src/Volo.Abp.AspNetCore.TestBase",
"framework/src/Volo.Abp.Auditing",
"framework/src/Volo.Abp.Authorization",

Loading…
Cancel
Save