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.

148 lines
4.8 KiB

5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
  1. #if NETCORE
  2. using System;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Hosting;
  5. using Microsoft.Extensions.Hosting;
  6. using Microsoft.Extensions.Configuration;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using Microsoft.AspNetCore.Builder;
  9. using System.Threading.Tasks;
  10. using Microsoft.AspNetCore.Server.Kestrel.Core;
  11. using Microsoft.AspNetCore.ResponseCompression;
  12. namespace Apewer.Web
  13. {
  14. /// <summary></summary>
  15. public abstract class AspNetCoreStartup
  16. {
  17. /// <summary>处理 WebSocket 请求。</summary>
  18. /// <remarks>默认值:FALSE。</remarks>
  19. public virtual bool UseWebSocket { get; protected set; } = false;
  20. /// <summary>WebSocket 保持活动的间隔时间,单位为秒。</summary>
  21. /// <remarks>默认值:10。</remarks>
  22. public virtual int KeepAlive { get; } = 10;
  23. /// <summary>处理请求。</summary>
  24. /// <param name="context"></param>
  25. public abstract void OnContext(HttpContext context);
  26. /// <summary>使用压缩。</summary>
  27. public virtual bool UseCompression { get => false; }
  28. /// <summary>处理 WebSocket 请求。</summary>
  29. public virtual void OnWebSocket(HttpContext context, System.Net.WebSockets.WebSocket webSocket) { }
  30. /// <summary>限制请求体的字节数,默认值:1073741824(1GB)。</summary>
  31. public virtual long MaxRequestBodySize { get => 1073741824L; }
  32. // public virtual void IHttpContextAccessor(IHttpContextAccessor accessor) { }
  33. #region Runtime
  34. bool _usedWebSocket = false;
  35. IConfiguration _configuration;
  36. /// <summary></summary>
  37. public AspNetCoreStartup() { }
  38. /// <summary></summary>
  39. public AspNetCoreStartup(IConfiguration configuration) => _configuration = configuration;
  40. /// <summary>使用此方法添加服务到容器。</summary>
  41. /// <remarks>此方法由运行时调用。</remarks>
  42. public void ConfigureServices(IServiceCollection services)
  43. {
  44. var maxRequestBodySize = MaxRequestBodySize;
  45. if (maxRequestBodySize < 1L) maxRequestBodySize = 1073741824L;
  46. services.Configure<KestrelServerOptions>(options =>
  47. {
  48. // 同步 IO。
  49. options.AllowSynchronousIO = true;
  50. // 限制请求大小。
  51. options.Limits.MaxRequestBodySize = maxRequestBodySize;
  52. // 在 Response 中不包含 Server 属性。
  53. options.AddServerHeader = false;
  54. });
  55. services.Configure<IISServerOptions>(options =>
  56. {
  57. // 同步 IO。
  58. options.AllowSynchronousIO = true;
  59. // 限制请求大小。
  60. options.MaxRequestBodySize = maxRequestBodySize;
  61. });
  62. if (UseCompression)
  63. {
  64. services.AddResponseCompression(options =>
  65. {
  66. options.EnableForHttps = true;
  67. options.Providers.Add<BrotliCompressionProvider>();
  68. options.Providers.Add<GzipCompressionProvider>();
  69. });
  70. }
  71. // var serviceProvider = services.BuildServiceProvider();
  72. // if (serviceProvider != null)
  73. // {
  74. // IHttpContextAccessor(serviceProvider.GetRequiredService<IHttpContextAccessor>());
  75. // }
  76. services.AddControllers();
  77. services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
  78. }
  79. /// <remarks>此方法由运行时调用。</remarks>
  80. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  81. {
  82. if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
  83. _usedWebSocket = UseWebSocket;
  84. if (_usedWebSocket)
  85. {
  86. var wsOptions = new WebSocketOptions();
  87. var keepAlive = KeepAlive;
  88. if (keepAlive > 0) wsOptions.KeepAliveInterval = TimeSpan.FromSeconds(keepAlive);
  89. app.UseWebSockets(wsOptions);
  90. }
  91. app.Run(Handler);
  92. }
  93. Task Handler(HttpContext context)
  94. {
  95. try
  96. {
  97. if (_usedWebSocket && UseWebSocket)
  98. {
  99. if (context.WebSockets.IsWebSocketRequest)
  100. {
  101. using (var ws = context.WebSockets.AcceptWebSocketAsync())
  102. {
  103. OnWebSocket(context, ws.Result);
  104. }
  105. return Task.CompletedTask;
  106. }
  107. }
  108. OnContext(context);
  109. }
  110. catch { }
  111. return Task.CompletedTask;
  112. }
  113. #endregion
  114. }
  115. }
  116. #endif