Skip to content

Commit

Permalink
✨ BD.Common8.SourceGenerator.Ipc.Server
Browse files Browse the repository at this point in the history
  • Loading branch information
AigioL committed Dec 16, 2023
1 parent aa1fca8 commit 414e34a
Show file tree
Hide file tree
Showing 13 changed files with 530 additions and 289 deletions.
14 changes: 6 additions & 8 deletions src/BD.Common8.Bcl/Random2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,6 @@ public static Random Shared()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double NextDouble() => Shared().NextDouble();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static char RandomCharAt(string s, int index)
{
if (index == s.Length) index = 0;
else if (index > s.Length) index %= s.Length;
return s[index];
}

/// <summary>
/// 生成随机字符串,长度为固定传入字符串
/// </summary>
Expand All @@ -85,6 +77,12 @@ void EachGenerate(int i)
{
var index = random.Next(0, randomChars.Length);
var temp = RandomCharAt(randomChars, index);
static char RandomCharAt(string s, int index)
{
if (index == s.Length) index = 0;
else if (index > s.Length) index %= s.Length;
return s[index];
}
result[i] = temp;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@ namespace BD.Common8.Ipc;

public static partial class IpcServiceCollectionServiceExtensions
{
/// <summary>
/// 添加 Ipc 服务器配置接口与实现类
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <typeparam name="TImplementation"></typeparam>
/// <param name="services"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IServiceCollection AddIpcServer<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService, IEndpointRouteMapGroup, IHubEndpointRouteMapHub
{
IpcServerService.OnMapGroupEvent += TImplementation.OnMapGroup;
IpcServerService.OnMapHubEvent += TImplementation.OnMapHub;
return services;
}

/// <summary>
/// Adds a singleton service of the type specified in <typeparamref name="TService"/> with an
/// implementation type specified in <typeparamref name="TImplementation"/> to the
Expand All @@ -13,12 +30,12 @@ public static partial class IpcServiceCollectionServiceExtensions
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
/// <seealso cref="ServiceLifetime.Singleton"/>
public static IServiceCollection AddSingletonWithIpc<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IServiceCollection AddSingletonWithIpcServer<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService, IEndpointRouteMapGroup, IHubEndpointRouteMapHub
{
IpcServerService.OnMapGroupEvent += TImplementation.OnMapGroup;
IpcServerService.OnMapHubEvent += TImplementation.OnMapHub;
services.AddIpcServer<TService, TImplementation>();
return services.AddSingleton(typeof(TService), typeof(TImplementation));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace BD.Common8.Ipc.Services;

/// <summary>
/// 用于定义以指定 prefix 为前缀的所有终结点。
/// <para>Ipc 服务接口必须继承此接口,且调用 <see cref="IpcServiceCollectionServiceExtensions.AddSingletonWithIpc{TService, TImplementation}(IServiceCollection)"/> 添加到 <see cref="Ioc"/></para>
/// <para>Ipc 服务接口必须继承此接口,且调用 <see cref="IpcServiceCollectionServiceExtensions.AddSingletonWithIpcServer{TService, TImplementation}(IServiceCollection)"/> 添加到 <see cref="Ioc"/></para>
/// </summary>
public partial interface IEndpointRouteMapGroup
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ static bool IsUsePort(IPAddress address, int port)
builder.Services.AddLogging(ConfigureLogging);
builder.Services.ConfigureHttpJsonOptions(ConfigureHttpJsonOptions);
builder.Services.AddSignalR(ConfigureSignalR).AddJsonProtocol();
builder.Services.AddHttpContextAccessor();

ConfigureServices(builder.Services);

Expand Down Expand Up @@ -305,8 +306,46 @@ protected virtual void ConfigureHub(HttpConnectionDispatcherOptions options)
options.Transports = HttpTransportType.WebSockets;
}

public HubEndpointConventionBuilder MapHub<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods)] THub>([StringSyntax("Route")] string pattern) where THub : Hub
public IServiceProvider Services => app.ThrowIsNull().Services;

readonly Dictionary<Type, Type> serviceToHubs = [];

/// <summary>
/// 根据服务接口类型值获取对应的 <see cref="IHubContext"/>
/// </summary>
/// <param name="serviceType"></param>
/// <returns></returns>
public IHubContext GetHubContext(Type serviceType)
{
if (!serviceToHubs.TryGetValue(serviceType, out var hubType))
{
// 服务接口类型,没有找到对应的 Hub 类型,抛出异常
throw ThrowHelper.GetArgumentOutOfRangeException(serviceType);
}

var hubContextType = typeof(IHubContext<>).MakeGenericType(hubType);
var hubContext = app.ThrowIsNull().Services.GetRequiredService(hubContextType);
if (hubContext is IHubContext hubContext_)
{
return hubContext_;
}
// IHubContext 泛型与非泛型都应为 Microsoft.AspNetCore.SignalR.Internal.HubContext<THub> 实现
// https://github.com/dotnet/aspnetcore/blob/v8.0.0/src/SignalR/server/Core/src/Internal/HubContext.cs
ThrowHelper.ThrowArgumentNullException(nameof(hubContext_));
return null!;
}

/// <summary>
/// 根据服务接口类型泛型获取对应的 <see cref="IHubContext"/>
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <returns></returns>
public IHubContext GetHubContext<TService>() where TService : class
=> GetHubContext(typeof(TService));

public HubEndpointConventionBuilder MapHub<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods)] THub>([StringSyntax("Route")] string pattern) where THub : Hub
{
serviceToHubs.TryAdd(typeof(TService), typeof(THub));
return app!.MapHub<THub>(pattern, ConfigureHub);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,20 @@ protected MethodPara[] GetMethodParas(IMethodSymbol method,
}
return methodParas;
}

/// <summary>
/// 根据方法参数返回请求方法
/// </summary>
/// <param name="category"></param>
/// <returns></returns>
protected string GetRequestMethod(MethodParametersCategory category)
{
var requestMethod = category switch
{
MethodParametersCategory.FromBody or
MethodParametersCategory.GeneratorModelFromBody => nameof(HttpMethod.Post),
_ => nameof(HttpMethod.Get),
};
return requestMethod;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,7 @@ void WriteMethodBodyWithWebApi()
";

"""u8);
var requestMethod = category switch
{
MethodParametersCategory.FromBody or
MethodParametersCategory.GeneratorModelFromBody => nameof(HttpMethod.Post),
_ => nameof(HttpMethod.Get),
};
var requestMethod = GetRequestMethod(category);
stream.WriteFormat(
"""
var requestMethod = HttpMethod.{0};
Expand Down Expand Up @@ -411,5 +406,6 @@ void WriteMethodBodyWithSignalR()
}

stream.WriteCurlyBracketRight();
stream.WriteNewLine();
}
}
Loading

0 comments on commit 414e34a

Please sign in to comment.