2022-04-03 13:34:55 +08:00
|
|
|
using System;
|
2021-05-30 19:16:20 +08:00
|
|
|
using System.Diagnostics;
|
2022-04-03 13:34:55 +08:00
|
|
|
using System.IO;
|
2021-05-30 19:16:20 +08:00
|
|
|
using BililiveRecorder.Core;
|
2022-04-03 13:34:55 +08:00
|
|
|
using BililiveRecorder.Web.Api;
|
2022-04-03 14:47:54 +08:00
|
|
|
using BililiveRecorder.Web.Graphql;
|
2021-05-30 19:16:20 +08:00
|
|
|
using GraphQL;
|
2022-04-03 14:52:11 +08:00
|
|
|
using GraphQL.Execution;
|
2021-05-30 19:16:20 +08:00
|
|
|
using GraphQL.Server;
|
2022-04-03 14:52:11 +08:00
|
|
|
using GraphQL.SystemReactive;
|
2021-05-30 19:16:20 +08:00
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
using Microsoft.Extensions.Logging;
|
2022-04-03 13:34:55 +08:00
|
|
|
using Microsoft.OpenApi.Models;
|
2021-05-30 19:16:20 +08:00
|
|
|
|
|
|
|
namespace BililiveRecorder.Web
|
|
|
|
{
|
|
|
|
public class Startup
|
|
|
|
{
|
|
|
|
// TODO 减少引用的依赖数量
|
|
|
|
|
|
|
|
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
|
|
|
|
{
|
|
|
|
this.Configuration = configuration;
|
|
|
|
this.Environment = environment;
|
|
|
|
}
|
|
|
|
|
|
|
|
public IConfiguration Configuration { get; }
|
|
|
|
|
|
|
|
public IWebHostEnvironment Environment { get; }
|
|
|
|
|
|
|
|
// This method gets called by the runtime. Use this method to add services to the container.
|
|
|
|
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
|
|
{
|
|
|
|
services.Configure<KestrelServerOptions>(o => o.AllowSynchronousIO = true);
|
|
|
|
|
|
|
|
services.TryAddSingleton<IRecorder>(new FakeRecorderForWeb());
|
|
|
|
|
|
|
|
services
|
2022-04-03 14:52:11 +08:00
|
|
|
.AddAutoMapper(c =>
|
|
|
|
{
|
|
|
|
c.AddProfile<DataMappingProfile>();
|
|
|
|
})
|
2021-05-30 19:16:20 +08:00
|
|
|
.AddCors(o => o.AddDefaultPolicy(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()))
|
2022-04-03 14:52:11 +08:00
|
|
|
;
|
|
|
|
|
|
|
|
// Graphql API
|
|
|
|
GraphQL.MicrosoftDI.GraphQLBuilderExtensions.AddGraphQL(services)
|
|
|
|
.AddServer(true)
|
|
|
|
.AddWebSockets()
|
|
|
|
.AddNewtonsoftJson()
|
|
|
|
.AddSchema<RecorderSchema>()
|
|
|
|
.AddSubscriptionDocumentExecuter()
|
|
|
|
.AddDefaultEndpointSelectorPolicy()
|
|
|
|
.AddGraphTypes(typeof(RecorderSchema).Assembly)
|
|
|
|
.Configure<ErrorInfoProviderOptions>(opt => opt.ExposeExceptionStackTrace = this.Environment.IsDevelopment() || Debugger.IsAttached)
|
|
|
|
.ConfigureExecution(options =>
|
2021-05-30 19:16:20 +08:00
|
|
|
{
|
|
|
|
options.EnableMetrics = this.Environment.IsDevelopment() || Debugger.IsAttached;
|
2022-04-03 14:52:11 +08:00
|
|
|
var logger = options.RequestServices?.GetRequiredService<ILogger<Startup>>();
|
|
|
|
options.UnhandledExceptionDelegate = ctx => logger?.LogError(ctx.OriginalException, "Graphql Error: {Error}");
|
2021-05-30 19:16:20 +08:00
|
|
|
})
|
|
|
|
;
|
2022-04-03 13:34:55 +08:00
|
|
|
|
|
|
|
// REST API
|
|
|
|
services
|
|
|
|
.AddSwaggerGen(c =>
|
|
|
|
{
|
|
|
|
c.SwaggerDoc("brec", new OpenApiInfo
|
|
|
|
{
|
|
|
|
Title = "录播姬 REST API",
|
2022-04-03 14:52:11 +08:00
|
|
|
Description = "录播姬网站 [rec.danmuji.org](https://rec.danmuji.org/) \n录播姬 GitHub [Bililive/BililiveRecorder](https://github.com/Bililive/BililiveRecorder) \n\n" +
|
|
|
|
"除了 REST API 以外,录播姬还有 Graphql API 可以使用。\n\n" +
|
|
|
|
"API 中的 objectId 在重启后会重新生成,不保存到配置文件。",
|
2022-04-03 13:34:55 +08:00
|
|
|
Version = "v1"
|
|
|
|
});
|
|
|
|
|
|
|
|
var filePath = Path.Combine(AppContext.BaseDirectory, "BililiveRecorder.Web.xml");
|
|
|
|
c.IncludeXmlComments(filePath);
|
|
|
|
})
|
|
|
|
.AddRouting(c =>
|
|
|
|
{
|
|
|
|
c.LowercaseUrls = true;
|
|
|
|
c.LowercaseQueryStrings = true;
|
|
|
|
})
|
|
|
|
.AddMvcCore(option =>
|
|
|
|
{
|
|
|
|
|
|
|
|
})
|
2022-04-03 14:47:54 +08:00
|
|
|
.AddApiExplorer()
|
|
|
|
.AddNewtonsoftJson();
|
2021-05-30 19:16:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) => app
|
|
|
|
.UseCors()
|
|
|
|
.UseWebSockets()
|
2022-04-03 13:34:55 +08:00
|
|
|
.UseRouting()
|
|
|
|
.UseEndpoints(endpoints =>
|
2021-05-30 19:16:20 +08:00
|
|
|
{
|
2022-04-03 13:34:55 +08:00
|
|
|
endpoints.MapControllers();
|
|
|
|
|
|
|
|
endpoints.MapGraphQL<RecorderSchema>();
|
|
|
|
endpoints.MapGraphQLWebSockets<RecorderSchema>();
|
|
|
|
|
|
|
|
endpoints.MapSwagger();
|
|
|
|
endpoints.MapGraphQLPlayground();
|
|
|
|
endpoints.MapGraphQLGraphiQL();
|
|
|
|
endpoints.MapGraphQLAltair();
|
|
|
|
endpoints.MapGraphQLVoyager();
|
|
|
|
|
|
|
|
endpoints.MapGet("/", async context =>
|
2021-05-30 19:16:20 +08:00
|
|
|
{
|
2022-04-02 21:08:04 +08:00
|
|
|
context.Response.ContentType = "text/html";
|
|
|
|
await context.Response.WriteAsync(ConstStrings.HOME_PAGE_HTML, encoding: System.Text.Encoding.UTF8).ConfigureAwait(false);
|
2022-04-03 13:34:55 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
endpoints.MapGet("favicon.ico", async context =>
|
2021-05-30 19:16:20 +08:00
|
|
|
{
|
2022-04-03 13:34:55 +08:00
|
|
|
context.Response.StatusCode = 404;
|
|
|
|
await context.Response.WriteAsync(string.Empty);
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.UseSwaggerUI(c =>
|
|
|
|
{
|
|
|
|
c.SwaggerEndpoint("brec/swagger.json", "录播姬 REST API");
|
|
|
|
})
|
|
|
|
.Use(next => async context =>
|
|
|
|
{
|
|
|
|
context.Response.Redirect("/");
|
|
|
|
await context.Response.WriteAsync(string.Empty);
|
2021-05-30 19:16:20 +08:00
|
|
|
})
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|