Allow running two IServer implementations side by side
- 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
Assessment
This issue has not been assessed yet.