Tools4ever Tech Blog

Self-Hosted Web-Server door middel van OWIN

Roy Versteeg - Sr. Software Engineer | 3 januari 2017

Als je een webapplicatie maakt voor het Microsoft platform zal je meestal gebruik maken van ASP.NET, Web-API en voor real-time updates aan de client kant van SignalR. Standaard zal je dit allemaal hosten op een IIS server of op Azure. Dat is prima als het puur een webapplicatie is. Echter heb je soms een applicatie die zelf als service op het client systeem draait, maar die ook een interface voor de gebruiker moet hebben. Het is voor deployment lastig om dan ook nog IIS in te richten.

Met de komst van de Open Web Interface for .NET (OWIN) web stack is het echter erg eenvoudig geworden om binnen je applicatie zelf een webserver te hosten, en alsnog gebruik te maken van dezelfde technologieën die je binnen IIS zou gebruiken.

In deze blog ga ik een kort voorbeeld geven hoe je een site op kunt zetten die door middel van Web-API en SignalR kan communiceren. De webapplicatie zelf zal een simpele single page applicatie zijn. Dat kan bijvoorbeeld een Angular2 applicatie zijn.

Om te beginnen moet er een aantal NuGet packages geïnstalleerd worden:

  • Microsoft.Owin.Host.HttpListener
  • Microsoft.owin.Hosting

Nadat deze packages geïnstalleerd zijn kunnen we beginnen met het bootstrappen van de applicatie.
In het voorbeeld werk ik met een simpele console applicatie, maar het kan ook prima in een windows service, of elke andere .NET project.
In de start van onze applicatie moeten we de initialisatie van de OWIN-stack regelen. Dat doen we eenvoudig door de volgende code:

In de generic parameter van WebApp geven we een type mee die de initialisatie voor zijn rekening neemt. Die class moet een methode hebben met de naam Configuration en een parameter van het type IAppBuilder:

Op dit moment gebeurt er nog even niks in de configuratie, maar hier gaan we straks de verschillende delen van onze applicatie toevoegen.

Met deze code wordt op poort 5000 een webserver gestart, die echter verder nog niks doet. Om dit te kunnen hosten heb je wel genoeg rechten nodig. Het kan zijn dat de user die de applicatie draait die niet heeft, in dat geval kun je die toevoegen met het volgende commando:

 

Static Files

Nu gaan we beginnen met het toevoegen van een module om statische files te kunnen hosten. Deze gebruiken we straks om onze Single Page Application (SPA) aan de client te hosten.

Om dit voor elkaar te krijgen voegen we de volgende NuGet packages toe:

  • Microsoft.Owin.FileSystems
  • Microsoft.Owin.StaticFiles

Nu passen we de Configuration methode van onze startup class aan naar het volgende:

Dit zorgt er voor dat de wwwroot folder onder onze applicatie via http beschikbaar gemaakt wordt. We geven daarbij aan dat index.html de default file is.

Als je dit compileert en in wwwroot een simpele index.html zet zal deze al getoond worden als je in http://localhost:5000 opvraagt.

Omdat we als website waarschijnlijk een moderne webapplicatie gaan maken, willen we ook nog dat alle URL’s, die opgevraagd worden die niet naar een file verwijzen, automatisch een failover hebben naar de index.html. Dit doen we om te zorgen dat client-side URL’s en HTML5 navigatie ook gebruikt kunnen worden.

Om dat voor elkaar te krijgen moeten we Owin middleware maken die de URL aanpast op het moment dat een file niet bestaat.

Onze middleware ziet er als volgt uit:

We verwachten een FileSystem als input parameter waarbij we kunnen controleren of de opgevraagde file ook daadwerkelijk bestaat. Als dat niet het geval is dan passen we de request URL aan naar index.html

Om deze middleware te gebruiken plaatsen we de volgende regel code:

op de regel voor app.UseFileServer(options)

Als je de applicatie nu draait kun je alle URL’s relatief aan localhost:5000 opvragen, en krijg je de default pagina te zien.

Binnen de wwwroot map kun je nu dus je volledige SPA plaatsen en zal dit goed werken.

Web-API

Voor een webapplicatie heb je natuurlijk ook data nodig. Deze data gaan we aanleveren door middel van een Web-API.

Om binnen je applicatie Web-API controllers te kunnen hosten voeg je de volgende NuGet package toe:

  • Microsoft.AspNet.WebApi.OwinSelfHost

Aan het begin van de configuratie methode ( voor het registreren van de fileserver ) voegen we de volgende code toe:

Dit zorgt ervoor dat alle requests onder de /api sub-url doorgestuurd worden naar de Web-API controllers.

Nu maken we een eenvoudige Web-API controller:

SignalR

Ook het toevoegen van SignalR is erg eenvoudig. Je installeert de volgende package:

  •  Microsoft.AspNet.SignalR

En je voegt de volgende regel code toe aan je configuratie methode:

  • app.MapSignalR();

Dan is het alleen nog een kwestie van een Hub toevoegen.

Dit is een erg eenvoudige Hub die een enkele methode heeft waar een client een message naar toe kan sturen, en die wordt dan naar alle andere verbonden clients doorgestuurd.

Een Angular2 Client implementatie kan er bijvoorbeeld als volgt uitzien:

Hiervoor is het wel nodig dat de jquery.signalR.min.js library geladen is binnen je project. Hoe verder om te gaan met SignalR valt buiten de scope van deze blog, maar er is genoeg informatie te vinden op internet.

Bekijk een voorbeeld project hier: https://github.com/rversteeg/self_host_owin_blog

Conclusie

Met bovenstaande delen is het eenvoudig om een complete Web-applicatie te hosten vanuit je eigen Windows applicatie. De applicatie zal als het goed is ook zonder al te veel moeite op een Mono of .NET Core omgeving draaien, waardoor het dus ook mogelijk is om een dergelijke applicatie op een ander platform dan Windows te draaien.