dotnet / dotnet/aspnetcore

Allow running two IServer implementations side by side

Open
#58,288 5 comments 0 reactions 0 assignees View on GitHub
area-networking Needs: Attention :wave:
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] 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();`
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(IHttpApplication 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.d__2.MoveNext() in /_/src/Servers/Kestrel/Core/src/LocalhostListenOptions.cs:line 63
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.d__3.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 247
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.d__0.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 32
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.d__31.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 309
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.d__28`1.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 225
at Tunnels.CompositeServer.d__5`1.MoveNext() in C:\Users\tj\source\repos\Tunnels\Tunnels\CompositeServer.cs:line 15
at Microsoft.AspNetCore.Hosting.GenericWebHostService.d__40.MoveNext() in /_/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs:line 161
at Microsoft.Extensions.Hosting.Internal.Host.<b__15_1>d.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 136
at Microsoft.Extensions.Hosting.Internal.Host.d__18`1.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 390
at Microsoft.Extensions.Hosting.Internal.Host.d__15.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 145
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.d__4.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 67
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.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.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.<g__OnBind|0>d.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 199
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.d__3.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 90
at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.d__61.MoveNext() in /_/src/Servers/Kestrel/Core/src/ListenOptions.cs:line 224
at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.d__1.MoveNext() in /_/src/Servers/Kestrel/Core/src/AnyIPListenOptions.cs:line 42
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.EndpointsStrategy.d__2.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 219
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.d__0.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/AddressBinder.cs:line 32
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.d__31.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 309
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.d__28`1.MoveNext() in /_/src/Servers/Kestrel/Core/src/Internal/KestrelServerImpl.cs:line 225
at Tunnels.CompositeServer.d__5`1.MoveNext() in C:\Users\tj\source\repos\Tunnels\Tunnels\CompositeServer.cs:line 15
at Microsoft.AspNetCore.Hosting.GenericWebHostService.d__40.MoveNext() in /_/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs:line 161
at Microsoft.Extensions.Hosting.Internal.Host.<b__15_1>d.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 136
at Microsoft.Extensions.Hosting.Internal.Host.d__18`1.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 390
at Microsoft.Extensions.Hosting.Internal.Host.d__15.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs:line 145
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.d__4.MoveNext() in /_/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs:line 67
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.