Reputation:
I created a new .NET Core worker project with the template provided by Visual Studio. I want to listen for incoming TCP messages and HTTP requests. I'm following David Fowler's "Multi-protocol Server with ASP.NET Core and Kestrel" repository on how to set up Kestrel.
As far as I know, all I have to do is to install the Microsoft.AspNetCore.Hosting package to get access to the UseKestrel
method.
In the Program.cs file I'm currently doing this
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
Unfortunately, I can't append UseKestrel
to the ConfigureServices
method. I think this is because I'm working with the IHostBuilder
interface instead of the IWebHostBuilder
interface.
This project should not be a Web API project, it should remain as a Worker project.
How can I configure Kestrel for this?
I tried to change the code to the code from the sample repository:
using System.Net;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
namespace Service
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// ...
})
.UseKestrel(options =>
{
// ...
});
}
}
When doing so it is still not able to resolve WebHost
and comes up with these errors:
There is no argument given that corresponds to the required formal parameter 'middleware' of 'ConnectionBuilderExtensions.Run(IConnectionBuilder, Func<ConnectionContext, Task>)'
The name 'WebHost' does not exist in the current context
I think this happens because the worker project does not use a Web SDK.
Upvotes: 6
Views: 26528
Reputation: 71
For .NET 5.0 as follows.
Add a Framework reference to ASP.NET:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Add a web configuration to file program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
config.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true);
Configuration = config.Build();
})
// Worker
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<ServiceDemo>();
})
// Web site
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseKestrel(options =>
{
// HTTP 5000
options.ListenLocalhost(58370);
// HTTPS 5001
options.ListenLocalhost(44360, builder =>
{
builder.UseHttps();
});
});
});
Configure class Startup
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app)
{
var serverAddressesFeature = app.ServerFeatures.Get<IServerAddressesFeature>();
app.UseStaticFiles();
app.Run(async (context) =>
{
context.Response.ContentType = "text/html";
await context.Response
.WriteAsync("<!DOCTYPE html><html lang=\"en\"><head>" +
"<title></title></head><body><p>Hosted by Kestrel</p>");
if (serverAddressesFeature != null)
{
await context.Response
.WriteAsync("<p>Listening on the following addresses: " +
string.Join(", ", serverAddressesFeature.Addresses) +
"</p>");
}
await context.Response.WriteAsync("<p>Request URL: " +
$"{context.Request.GetDisplayUrl()}<p>");
});
}
}
Upvotes: 6
Reputation: 579
You enable the HTTP workload using IHostbuilder you need to add .ConfigureWebHostDefaults
in your Host.CreateDefaultBuilder
. Since Kestrel is web server you can only configure it from a webhost.
In your program.cs file
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseKestrel(options =>
{
// TCP 8007
options.ListenLocalhost(8007, builder =>
{
builder.UseConnectionHandler<MyEchoConnectionHandler>();
});
// HTTP 5000
options.ListenLocalhost(5000);
// HTTPS 5001
options.ListenLocalhost(5001, builder =>
{
builder.UseHttps();
});
});
});
Or
public static IHostBuilder CreateHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(options =>
{
// TCP 8007
options.ListenLocalhost(8007, builder =>
{
builder.UseConnectionHandler<MyEchoConnectionHandler>();
});
// HTTP 5000
options.ListenLocalhost(5000);
// HTTPS 5001
options.ListenLocalhost(5001, builder =>
{
builder.UseHttps();
});
});
Since you are enabling HTTP workloads using a web server then you project must be of type web. WebHost will be enabled only if the project is of type web. So you need to change your SDK to use web in your csproj file.
<Project Sdk="Microsoft.NET.Sdk.Web">
Reference:
Upvotes: 7