Код: Выделить всё
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
Причина использования HTTP2 заключается в возможности выполнять вызовы gRPC, я использую библиотеки protobuf-net, и все работает нормально, когда бы я ни запускал свой API, Я получаю пару URL-адресов запуска (http и https), и вызовы HTTP и gRPC работают.
Моя основная проблема заключается в том, что я не могу настроить свое интеграционное тестовое приспособление, чтобы оно работало.
Прежде всего позвольте мне показать вам мой Program.cs
Код: Выделить всё
var builder = WebApplication.CreateBuilder(args);
ServiceRegistration.ConfigureServices(builder, "AdcTrains", "adc-trains",
containerBuilderAdditionalActions:
containerBuilder =>
{
},
additionalMiddlewareActions: webApp =>
{
if (webApp.Environment.IsDevelopment())
{
webApp.MapCodeFirstGrpcReflectionService();
}
webApp.MapGrpcService();
},
additionalPostBuildBehavior: async webApp =>
{
// write unit tests / integration tests rather than this
var tenantIdString = "19d74b3c-2955-4667-9bc5-15d67212469e";
var multitenantService = webApp.Services.GetRequiredService();
var tenantScope = multitenantService.GetTenantScope(tenantIdString);
var resolverService = tenantScope.Resolve();
var trainGrpcService = resolverService.ResolveService(Guid.Parse(tenantIdString));
});
///
/// Not to be removed, used for the testing project
///
public partial class Program { }
В нем я сначала включаю свой код gRPC
Код: Выделить всё
// this is actually exposing real grpc endpoints
services.AddCodeFirstGrpcReflection();
services.AddCodeFirstGrpc(config =>
{
config.ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal;
});
Это вся моя WebApplicationFactory, написанная согласно документации
Код: Выделить всё
///
/// This is the base fixture for all the integration tests
/// https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-8.0
///
public class CustomWebApplicationFactory : WebApplicationFactory, IAsyncLifetime where TProgram : class
{
protected const string TenantId = "19d74b3c-2955-4667-9bc5-15d67212469e";
// this will be initialized in InitializeAsync
public HttpClient HttpClient = default!;
public HubConnection WebHubConnection { get; set; }
public HubConnection RequestHubConnection { get; set; }
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Test");
builder
//.UseTestServer()
.ConfigureServices(services =>
{
services.AddCodeFirstGrpcReflection();
services.AddCodeFirstGrpc(config =>
{
config.ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal;
config.EnableDetailedErrors = true;
});
})
.UseUrls("https://localhost:7034")
.ConfigureKestrel(k =>
{
k.ConfigureEndpointDefaults(lo => lo.Protocols = HttpProtocols.Http1AndHttp2);
k.ListenAnyIP(7034, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
});
})
.Configure(app =>
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService();
});
});
}
#region IAsyncLifetime
public async Task InitializeAsync()
{
HttpClient = CreateClient();
var configuration = Services.GetRequiredService();
var testConfiguration = configuration.GetSection("TestConfiguration");
var httpClient = new HttpClient();
var tokenResponse = await httpClient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = testConfiguration.GetValue("Ids"),
ClientId = testConfiguration.GetValue("ClientId")!,
Scope = testConfiguration.GetValue("Scope"),
UserName = testConfiguration.GetValue("UserName")!,
Password = testConfiguration.GetValue("Password")!
});
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
HttpClient.DefaultRequestHeaders.Add("tenantId", TenantId);
// SignalR hookup
var hubConnectionService = new HubConnectionService(configuration);
var cancellationTokenSource = new CancellationTokenSource(15000);
// Front-end conn
WebHubConnection = await hubConnectionService.HubInitialize("webNotifications", tokenResponse.AccessToken, cancellationTokenSource.Token);
// Simulating the OBS system, basically in front-end == obs just so we can test easily
RequestHubConnection = await hubConnectionService.HubInitialize("trainRequest", tokenResponse.AccessToken, cancellationTokenSource.Token);
if (WebHubConnection.ConnectionId is null)
throw new Exception("Error at connecting to SignalR");
Log.Information("Hub connectionId: {hubConnectionId}", WebHubConnection.ConnectionId);
}
///
/// Logout
///
///
public async Task DisposeAsync()
{
var configuration = Services.GetRequiredService();
var testConfiguration = configuration.GetSection("TestConfiguration");
await HttpClient.RevokeTokenAsync(new TokenRevocationRequest
{
Token = HttpClient.DefaultRequestHeaders.Authorization!.Parameter,
Address = testConfiguration.GetValue("Ids")
});
}
#endregion
}
Код: Выделить всё
public class TrainGrpcConfigFixture : IClassFixture
{
private readonly CustomWebApplicationFactory _factory;
public TrainGrpcConfigFixture(CustomWebApplicationFactory factory)
=> _factory = factory;
[Fact]
public async Task Get_NvrSet_Response_ExpectData()
{
// Arrange
var grpcResolver = _factory.Services.GetService(typeof(IGrpcResolverService)) as IGrpcResolverService;
var trainGrpcService = grpcResolver.ResolveService();
var response = await trainGrpcService.GetNvrSetResponseAsync(new TrainConfig.Grpc.Models.Dtos.NvrSet.Requests.NvrSetRequest() { TrainId = 8 });
}
}
Поэтому я предполагаю, что по какой-то причине мой WebApi не запускается с определенным портом, как я пытался (7034), и он просто отвергает меня.
Я исчерпал все свои попытки, прежде чем писать здесь, я нашел несколько образцов, но они довольно старые и, кажется, со всего мира 2019~, пытался включить их сюда, но они не увенчались успехом.... поэтому я просто остановился на официальном документе для .NET 8, который не охватывает многое, связанное с go gRPC.
Подробнее здесь: https://stackoverflow.com/questions/788 ... -with-grpc