ASP.NET Core – Implementing custom server

By Dawid on (tags: ASP.NET, core, hosting, server, categories: code)

In previous blog post I’ve show you how to host ASP.NET Core application using Kestrel server. But why not to write our own server – in ASP.NET Core that is actually quite simple.

Like show in previous blog post ASP.NET Core provide an extension method UseKestrel() which specifies the Kestrel server will be used by the app (it creates the web server and hosts the code). But there is actually another one – UseServer(IServer server). Let’s try to use it and provide our own hosting server.

   1: public class CustomServer : IServer
   2: {
   3:     public IFeatureCollection Features { get; } = new FeatureCollection();
   5:     public void Dispose() {...}
   7:     public void Start<TContext>(IHttpApplication<TContext> application)
   8:     {
   9:         //start listening for request
  11:         Features.Set<IHttpRequestFeature>(new HttpRequestFeature());
  12:         Features.Set<IHttpResponseFeature>(new HttpResponseFeature());
  14:         var context = application.CreateContext(Features);
  15:         application.ProcessRequestAsync(context);
  16:     }
  17: }

So how the requests are getting handled in the server?

Each server has collection of server features. Those are interfaces which exposes some functionality of the server. For example feature Features.Set<IServerAddressesFeature>(new ServerAddressesFeature()) is exposing information’s about addresses on which server is listening for requests. There is much, much more of those features…

IHttpResponseFeature and IHttpRequestFeature are required by all of the servers – please remember about that! In the ASP.NET everything is about HttpContext but not in ASP.NET Core. In Core, HttpContext is just a wrapper around set of request features. To create one use CreateContext() method on the application object.

The main method of the server is the Start<TContext>(IHttpApplication<TContext> application) method – it’s processing each of the request which comes in.

That is basically it, now we just have to wire it up and start using our new server.

   1: public class Program
   2: {
   3:     public static void Main(string[] args)
   4:     {
   5:         var host = new WebHostBuilder()
   6:             .UseServer(new CustomServer())
   8:             ...
  10:         host.Run();
  11:     }
  12: }