Description
openedon Oct 8, 2024
Is there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
I need to create an API that will allow two types of communication, a standard way using HTTP requests and a second using AMQP messages.
I've implemented a custom IServer and I was able to plug it into the default ASP.NET Core Web API (.NET8) project using:
builder.Services.AddSingleton<IServer, RabbitMqServer>();
but this disables the default communication via HTTP.
I've tried creating a composite server using https://github.com/stop-cran/AspNetCoreExtras.Solace.Server as a reference,
public class CompositeServer(RabbitMqServer rabbitMqServer, KestrelServer kestrelServer) : IServer
{
public IFeatureCollection Features => kestrelServer.Features;
public async Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken) where TContext : notnull
{
await rabbitMqServer.StartAsync(application, cancellationToken);
await kestrelServer.StartAsync(application, cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await rabbitMqServer.StopAsync(cancellationToken);
await kestrelServer.StopAsync(cancellationToken);
}
public void Dispose()
{
rabbitMqServer.Dispose();
kestrelServer.Dispose();
}
}
But when I try to start project from VS I get this errors:
System.IO.IOException
HResult=0x80131620
Message=Failed to bind to address http://localhost:5016.
Source=Microsoft.AspNetCore.Server.Kestrel.Core
StackTrace:
at Microsoft.AspNetCore.Server.Kestrel.Core.LocalhostListenOptions.<BindAsync>d__2.MoveNext() in /_/src/Servers/Kestrel/Core/src/LocalhostListenOptions.cs:line 63
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.<BindAsync>d__3.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 247
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAsync>d__0.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 32
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<BindAsync>d__31.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 309
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<StartAsync>d__28`1.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 225
at Tunnels.CompositeServer.<StartAsync>d__5`1.MoveNext() in C:\Users\tj\source\repos\Tunnels\Tunnels\CompositeServer.cs:line 15
at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__40.MoveNext() in /_/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs:line 161
at Microsoft.Extensions.Hosting.Internal.Host.<<StartAsync>b__15_1>d.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 136
at Microsoft.Extensions.Hosting.Internal.Host.<ForeachService>d__18`1.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 390
at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__15.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 145
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 67
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 79
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host) in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 53
at Tunnels.Program.Main(String[] args) in C:\Users\tj\source\repos\Tunnels\Tunnels\Program.cs:line 44
This exception was originally thrown at this call stack:
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.TransportManager.BindAsync(System.Net.EndPoint, Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.EndpointConfig, System.Threading.CancellationToken) in TransportManager.cs
Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync.__OnBind|0(Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, System.Threading.CancellationToken) in KestrelServerImpl.cs
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBindContext, System.Threading.CancellationToken) in AddressBinder.cs
Microsoft.AspNetCore.Server.Kestrel.Core.LocalhostListenOptions.BindAsync(Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBindContext, System.Threading.CancellationToken) in LocalhostListenOptions.cs
Inner Exception 1:
AggregateException: One or more errors occurred. (No registered IConnectionListenerFactory supports endpoint IPEndPoint: 127.0.0.1:5016) (No registered IConnectionListenerFactory supports endpoint IPEndPoint: [::1]:5016)
Inner Exception 2:
InvalidOperationException: No registered IConnectionListenerFactory supports endpoint IPEndPoint: 127.0.0.1:5016
I've tried configuring Kestrel via
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(5000); // Change to a different port if needed
});
but this gives me this error:
System.InvalidOperationException
HResult=0x80131509
Message=No registered IConnectionListenerFactory supports endpoint IPEndPoint: 0.0.0.0:5000
Source=Microsoft.AspNetCore.Server.Kestrel.Core
StackTrace:
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.TransportManager.<BindAsync>d__10.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/Infrastructure/TransportManager.cs:line 62
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<>c__DisplayClass28_0`1.<<StartAsync>g__OnBind|0>d.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 199
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindEndpointAsync>d__3.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 90
at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.<BindAsync>d__61.MoveNext() in /_/src/Servers/Kestrel/Core/src/ListenOptions.cs:line 224
at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.<BindAsync>d__1.MoveNext() in /_/src/Servers/Kestrel/Core/src/AnyIPListenOptions.cs:line 42
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.EndpointsStrategy.<BindAsync>d__2.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 219
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAsync>d__0.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 32
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<BindAsync>d__31.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 309
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<StartAsync>d__28`1.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 225
at Tunnels.CompositeServer.<StartAsync>d__5`1.MoveNext() in C:\Users\tj\source\repos\Tunnels\Tunnels\CompositeServer.cs:line 15
at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__40.MoveNext() in /_/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs:line 161
at Microsoft.Extensions.Hosting.Internal.Host.<<StartAsync>b__15_1>d.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 136
at Microsoft.Extensions.Hosting.Internal.Host.<ForeachService>d__18`1.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 390
at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__15.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 145
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 67
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 79
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host) in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 53
at Tunnels.Program.Main(String[] args) in C:\Users\tj\source\repos\Tunnels\Tunnels\Program.cs:line 49
Describe the solution you'd like
Ideally, we should be able to easily add additional IServer implementations to projects, so they can work side by side.
Additional context
I want to reuse as many features as I can, my idea is to configure authorization, cache, rate limiting, etc in my app and allow invoking requests via HTTP and AMQP.
If there is an easier way to "dispatch" a request from AMQP message and catch the response please let me know.