Understanding OWIN – hosting and middleware

In my previous post about OWIN, I talked a bit about what OWIN is, and why it is important. This time, I want to take a little more of a dive into how we can use it, and how we code things using it.

var http = require('http');
var server = http.createServer(function(req,res) {
res.end('Hello World');
});
server.listen(8080);
console.log('Server running...listening on port 8080');

The above code snippet has nothing at all to do with OWIN. It is actually Node.js code for creating a web server and responding to HTTP requests. However, the above code is the main reason I like Node. The simplicity and tiny amount of code needed to get going is awesome!

It doesn’t do much, but it gives as a very crude, but powerful starting point in just a couple of lines of code. It is then up to us to take it from there and do what we want. Something we often do by turning to our package manager and asking for some cool functionality that someone else has already built.

So why am I showing Node code when I am supposed to be talking about OWIN? Well, mostly because the above code, besides being JavaScript and not C#, is actually not that far from how we get started with OWIN…but let’s back up just a little before we create some code.

Before I start showing how we build the same thing in OWIN, I want to mention the current options for hosting OWIN. Because without a host, OWIN wont actually give us that much…

There are currently 4 hosts readily available to us from Microsoft. 3 of them come out of project Katana, Microsoft’s “OWIN project”, and one come out of project Helios.

In project Katana, you have, as I mentioned, 3 hosts. You have the Web host, which will host OWIN in IIS together with ASP.NET. You have the self-host option, which creates a HttpListener based server and lets you host OWIN wherever you want. And finally you have OwinHost.exe, which is a free-standing OWIN host that will spin up a process for you, and host your OWIN stuff by telling it what assembly it is in.

However, Microsoft “recently” (late 2013) released a pre-release of a new OWIN host called project Helios. The goal of project Helios is to be able to host OWIN in IIS without having to include the ASP.NET pipeline, and thus not having to include System.Web etc. Instead, Helios is much closer to the metal, offering better performance and smaller memory footprint. However, it comes at a price… It requires you to run Windows 8 or Server 2012, .NET Framework 4.5.1 and Full Trust. In a lot of cases, this is not a problem, but in some cases it might be. If it isn’t, and you only want OWIN and not ASP.NET, then Helios will give you some performance and memory benefits that might be interesting.

Do remember that it is still an alpha release, so it might come with some caveats…

Ok, now that we have looked at the different hosting options, I guess it is time to create some code…

I’m going to be using the self-host option in this post, so I start by creating a new Console Application Project in Visual Studio. Then I use NuGet to install Microsoft.Owin.SelfHost. This will install the required Owin stuff and then open a “readme.txt” file including everything you need to know to get started. In my case, I just kill that page, and keep going. In your case, you can either read it and see what it says, or close it and read what to do here. It is pretty much the same thing…

The next step is to create a Startup class. The default convention is to name it Startup, but it isn’t mandatory. Especially not in the self-host case. However, if you want to use it in the other Katana hosts, it is a different story. Katana hosts assume that the Startup class is called Startup, and placed in a namespace with the same name as the assembly.

If you don’t name it Startup, you can add an assembly attribute called OwinStartup, which tells anyone who cares that you have  what you have chosen to name it something else.

You can also add a “redirect” in your applications config file by adding an appSetting called owin:appStartup containing the name of the startup class…

But as I said, for self-hosting it doesn’t matter, as we will manually tell OWIN what class to use…

Ok, so I create a new class called Startup. Inside it, I declare a single method with the following signature: public void Configuration(IAppBuilder app).

Once I have a start up class, I go to my Main method and add the following code to start a new server

static void Main(string[] args)
{
using (WebApp.Start<Startup>("http://localhost:1337"))
{
Console.WriteLine("Server listening on port 1337...");
Console.WriteLine("Press any key to close...");
Console.ReadLine();
}
}

That is pretty much it!

Except for the fact that nothing is actually happening right now. I haven’t yet told OWIN what to do when a request comes in… So let’s do that!

To handle incoming requests, you add what is called a middleware. A middleware is some form of thing that listens to incoming requests and does something with it. It can either look at the request, potentially making some changes, and then pipe it on to the next middleware. Or it can handle the request and return a response.

Returning a response will pass the response back through the middleware in-front of the current one, letting them do what they want to the response as well. And any piece of middleware is allowed to do whatever it wants with both the requests and responses going through the pipeline… And they are called in the order that they are added to the pipeline.

Ok, so let’s add something to the OWIN request pipeline… Something simple… Like a hello world message…

To do so, I go back to my Configuration() method in my Startup class and add the following

public void Configuration(IAppBuilder app)
{
app.Use((context, next) =>
{
context.Response.Write("Hello World");
return Task.FromResult(0);
});
}

As you can see, I use the Use() method on the IAppBuilder interface to include a piece of middleware (I still call it middleware as it is so simple, but being that it actually is the whole application, I guess it is really an application and not just a piece of middleware…).

The middleware implementation is a Func<> that takes an IOwinContext and another Func<> as method parameters, and return a Task. The IOwinContext contains everything you need to know about the current context, which means the current request basically, and the Func<> is a reference to the next middleware in the pipeline… In this case, I just ignore any other middleware, write “Hello World” to the response and return!

To try it out, just press F5 to start the application, and then use the browser of your choice to browse to http://localhost:1337/. It should look like this

image

Ok, that was pretty simple, and as I mentioned earlier, very similar to Node…

But how do I write my middleware if I want to pass it on to the next and then listen to the response? Well, it isn’t very hard, but the syntax is full of new C# goodies, making it really neat to work with, but a little hard to figure out before someone shows it to you…

Let’s add a new piece of middleware that times how long a request takes… To do so, I add the following code before the existing call to Use()

app.Use(async (context, next) =>
{
var watch = new Stopwatch();
watch.Start();

await next();

watch.Stop();
Console.WriteLine("Request took {0} ms", watch.ElapsedMilliseconds);
});

Ok, so what is happening here? Well, quite a few things… First of all, the middleware is now marked as “async” allowing us to use “await”. The functionality is pretty simple. A Stopwatch is created, and started, before a call to the next middleware is called, and awaited. As soon as it returns, the Stopwatch is stopped, and the elapsed time is logged to the console.

Running it will look like this

image

As you can see, the first request took 3ms, and the following 2 took less than a millisecond to execute… That is pretty fast!

One thing to note is that when you start typing app.Use, Intellisense will give you 2 versions of this method. The one that we have used so far, and one that takes an object and an array of parameters. The one that we have used is one actually not the one defined on the interface, it is one defined as an extension method and provided to us by Microsoft. It is also available as a generic version called Use<T>. They both do the same thing…register pieces of code as middleware. Microsoft was also kind enough to give us a base class to use instead of having to use the somewhat complicated Func<> that we have been using so far.

The base class is called…wait for it….wait for it…OwinMiddleware! And it is brilliant…or…wait…it doesn’t actually do much, but at least it allows us to encapsulate our middleware nicely…

Turning our “diagnostics” middleware into OwinMiddleware looks like this

public class SimpleDiagnosticsMiddleware: OwinMiddleware
{
public SimpleDiagnosticsMiddleware(OwinMiddleware next) : base(next)
{
}

public async override Task Invoke(IOwinContext context)
{
var watch = new Stopwatch();
watch.Start();

await Next.Invoke(context);

watch.Stop();
Console.WriteLine("Request took {0} ms", watch.ElapsedMilliseconds);
}
}

As you can see, it is slightly more readable, but encapsulates our middleware in a reusable form which is quite nice… And registering it becomes a bit cleaner

public void Configuration(IAppBuilder app)
{
app.Use<SimpleDiagnosticsMiddleware>();

app.Use((context, next) =>
{
context.Response.Write("Hello World");
return Task.FromResult(0);
});
}

The last bit to have a look at is how we can have OWIN use different configurations for different “areas”. To do this, we use the extension method called Map(). It takes the path to look for, and a configuration callback to create the configuration to use for the specified “area”. Like this

app.Map("/diagnostic", app2 =>
{
app2.Use<SimpleDiagnosticsMiddleware>();
app2.Use((context, next) =>
{
context.Response.Write("Diagnostics Hello World");
return Task.FromResult(0);
});
});

In this case, any call that has a path that starts with “/diagnostic” will have the diagnostics middleware, and return “Diagnostics Hello World”.

This feature is quite neat as it means that we can have multiple different configurations in different “areas” of our application. And if we encapsulate our middleware in OwinMiddleware classes, building up these different pipelines will be easy, and very readable!

The last thing to look at is how we can package OWIN middleware in a way that works for reuse…just like the big boys do. Instead of calling Use<T>() for the different middleware to include, using an extension method is nicer and easier to read. And on top of that, it isn’t that hard to do.

As extension methods can only be added to static classes, I create a new class called SimpleDiagnosticsMiddlewareExtensions, and I make it static. Next I add a static extension method that looks like this

public static class SimpleDiagnosticsMiddlewareExtensions
{
public static void UseSimpleDiagnostics(this IAppBuilder app)
{
app.Use<SimpleDiagnosticsMiddleware>();
}
}

Next, I can modify my application configuration to use this method instead of the previous one, like this

app.Map("/diagnostic", app2 =>
{
app2.UseSimpleDiagnostics();
...
});

And if we wanted to add configuration, this could obviously just be passed in as a parameter to the UseSimpleDiagnostics() method and then passed on to the middleware class, making the registration nice and clean.

That’s it!

And as usual, the code is available here: DarksideCookie.Owin.HelloWorld.zip (5.51 kb)

Cheers!

Comments (1) -

myself browsing your blog from my new iphone! Just wanted to say I

love reading through your blog and loef and a large element ofin internet explorer,

Add comment