You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.5 KiB
140 lines
4.5 KiB
#if NETCORE
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
|
using Microsoft.AspNetCore.ResponseCompression;
|
|
|
|
namespace Apewer.Web
|
|
{
|
|
|
|
/// <summary></summary>
|
|
public abstract class AspNetCoreStartup
|
|
{
|
|
|
|
/// <summary>处理 WebSocket 请求。</summary>
|
|
/// <remarks>默认值:FALSE。</remarks>
|
|
public virtual bool UseWebSocket { get; protected set; } = false;
|
|
|
|
/// <summary>WebSocket 保持活动的间隔时间,单位为秒。</summary>
|
|
/// <remarks>默认值:10。</remarks>
|
|
public virtual int KeepAlive { get; } = 10;
|
|
|
|
/// <summary>处理请求。</summary>
|
|
/// <param name="context"></param>
|
|
public abstract void OnContext(HttpContext context);
|
|
|
|
/// <summary>使用压缩。</summary>
|
|
public virtual bool UseCompression { get => false; }
|
|
|
|
/// <summary>处理 WebSocket 请求。</summary>
|
|
public virtual void OnWebSocket(HttpContext context, System.Net.WebSockets.WebSocket webSocket) { }
|
|
|
|
/// <summary>限制请求体的字节数,默认值:1073741824(1GB)。</summary>
|
|
public virtual long MaxRequestBodySize { get => 1073741824L; }
|
|
|
|
#region Runtime
|
|
|
|
bool _usedWebSocket = false;
|
|
IConfiguration _configuration;
|
|
|
|
/// <summary></summary>
|
|
public AspNetCoreStartup() { }
|
|
|
|
/// <summary></summary>
|
|
public AspNetCoreStartup(IConfiguration configuration) => _configuration = configuration;
|
|
|
|
/// <summary>使用此方法添加服务到容器。</summary>
|
|
/// <remarks>此方法由运行时调用。</remarks>
|
|
public void ConfigureServices(IServiceCollection services)
|
|
{
|
|
var maxRequestBodySize = MaxRequestBodySize;
|
|
if (maxRequestBodySize < 1L) maxRequestBodySize = 1073741824L;
|
|
|
|
services.Configure<KestrelServerOptions>(options =>
|
|
{
|
|
// 同步 IO。
|
|
options.AllowSynchronousIO = true;
|
|
|
|
// 限制请求大小。
|
|
options.Limits.MaxRequestBodySize = maxRequestBodySize;
|
|
|
|
// 在 Response 中不包含 Server 属性。
|
|
options.AddServerHeader = false;
|
|
});
|
|
|
|
services.Configure<IISServerOptions>(options =>
|
|
{
|
|
// 同步 IO。
|
|
options.AllowSynchronousIO = true;
|
|
|
|
// 限制请求大小。
|
|
options.MaxRequestBodySize = maxRequestBodySize;
|
|
});
|
|
|
|
if (UseCompression)
|
|
{
|
|
services.AddResponseCompression(options =>
|
|
{
|
|
options.EnableForHttps = true;
|
|
options.Providers.Add<BrotliCompressionProvider>();
|
|
options.Providers.Add<GzipCompressionProvider>();
|
|
});
|
|
}
|
|
|
|
services.AddControllers();
|
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
|
}
|
|
|
|
/// <remarks>此方法由运行时调用。</remarks>
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
{
|
|
if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
|
|
|
|
_usedWebSocket = UseWebSocket;
|
|
if (_usedWebSocket)
|
|
{
|
|
var wsOptions = new WebSocketOptions();
|
|
var keepAlive = KeepAlive;
|
|
if (keepAlive > 0) wsOptions.KeepAliveInterval = TimeSpan.FromSeconds(keepAlive);
|
|
app.UseWebSockets(wsOptions);
|
|
}
|
|
|
|
app.Run(Handler);
|
|
}
|
|
|
|
Task Handler(HttpContext context)
|
|
{
|
|
try
|
|
{
|
|
if (_usedWebSocket && UseWebSocket)
|
|
{
|
|
if (context.WebSockets.IsWebSocketRequest)
|
|
{
|
|
using (var ws = context.WebSockets.AcceptWebSocketAsync())
|
|
{
|
|
OnWebSocket(context, ws.Result);
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
|
|
OnContext(context);
|
|
}
|
|
catch { }
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|