[OWIN] Uniéndolo todo sin KATANA IAppBuilder

Decía en una ocasión que no todo el OWIN es Katana y nombraba un par de proyectos que me llaman mucho la atención, escribí  transcribí un ejemplo con Nowin, Simple.Web y Fix y dejé el tema hasta ahí.

En esta entrada escribiré más código para demostrar un par de objetivos del estándar OWIN, el uso de pequeños módulos para el desarrollo de nuestras aplicaciones e impulsar el desarrollo de herramientas oss (Incluso por fuera de MSFT)

image

Como ya sabemos existen varios elementos que componen una aplicación OWIN (Host, server, Middleware, Fws), el punto de la interoperabilidad lo define el AppFunc y como se inicia la aplicación lo “define” la especificación.

El como pegamos los Middlewares/Frameworks al pipeline o como construimos unos que se ajusten es aún un tema discutido por la comunidad, pues bien sabemos, Microsoft hace uso del IAppBuilder del Owin.dll, paquete e interfaz que mucha gente ve como parte de la especificación, pero no lo es, por el contrario, la comunidad misma discute el futuro de esa Interfaz y del Owin.dll. Así mismo, Mark Rendle ha hecho una propuesta muy útil, algo que ya se usa en Fix, y que solo necesita una lambda, pero aun esta en discusión y no hace parte de la especificación.

Ya vimos en el anterior post a Nowin y Simple.Web, para ver lo sencillo que es conectar y desconectar, veamos lo mismo con Nancy!

NancyFx, Nowin y Fix

En este ejemplo conectaremos estos tres elementos en un self-hosting, corriendo sobre el Nowin Server. El código necesario:

    class Program
    {
        static void Main()
        {
            var nancyOptions = new NancyOptions { Bootstrapper = new DefaultNancyBootstrapper() };

            var app = new Fixer()
                .Use((env, next) => new NancyOwinHost(next, nancyOptions).Invoke(env))
                .Build();

            // Set up the Nowin server
            var builder = ServerBuilder.New()
                .SetPort(8888)
                .SetOwinApp(app);

            // Run
            using (builder.Start())
            {
                Console.WriteLine("Listening on port 1337. Enter to exit.");
                Console.ReadLine();
            }
        }
    }

    public class Home : NancyModule
    {
        public Home()
        {
            Get["/"] = _ => View["home"];
        }
    }

    public class CustomRootPathProvider : IRootPathProvider
    {
        public string GetRootPath()
        {
            return @"C:\PathDondeEstanLosHtml\";
        }
    }

La parte interesante del ejemplo esta en las líneas:

            var nancyOptions = new NancyOptions { Bootstrapper = new DefaultNancyBootstrapper() };
            var app = new Fixer()
                .Use((env, next) => new NancyOwinHost(next, nancyOptions).Invoke(env))
                .Build();

El método Use de la clase Fixer hace uso de la firma propuesta por Mark y como el bien lo dice, no rompe nada! y finalmente una invocación al método Build que retornará el AppFunc valido y cuyo diccionario será poblado luego por el server y dará inicio al big bang 😛

Ya es cuestión de opinión, pero la firma de este delegado me parece una propuesta excelente.

Ahora habrá quien este pensando que no me gusta nada de Microsoft.Owin.* y crea que es malo o que no es cool. Pues todo lo contrario! si es OWIN es bienvenido. Veamos el siguiente ejemplo.

NOWIN, WEB API y Fix

Esto es de lo que habla una de las metas de OWIN, los pequeños componentes que podemos emplear para construir nuestra aplicación, y la facilidad que supondría reemplazarlos. pues bien, veamos como conectar a nuestro servidor Nowin un ASP.NET WE API con Fix:

    class Program
    {
        static void Main(string[] args)
        {
            var app = new Fixer().Use(Start).Build();

            var builder = ServerBuilder.New()
                .SetPort(1234)
                .SetOwinApp(app);

            using (builder.Start())
            {
                Console.WriteLine("Listening on port 8888. Enter to exit.");
                Console.ReadLine();
            }
        }

        private static Task Start(IDictionary<string, object> env, Func<IDictionary<string, object>, Task> next)
        {
            IAppBuilder app = new Microsoft.Owin.Hosting.Builder.AppBuilderFactory().Create();
            app.UseWebApi(ConfigureWebApi());
            var build = app.Build();
            return build(env);
        }

        private static HttpConfiguration ConfigureWebApi()
        {
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }
                );
            return config;
        }
    }

    public class TestController : ApiController
    {
        public string Get()
        {
            return "Nicolas";
        }
    }

Aquí si no estoy seguro de que la implementación sea correcta, no estoy seguro si se pueda acceder directamente a ASP.NET WEB API OWIN sin la necesidad de emplear el IAppBuilder, aunque Fix también parece que incluirá el soporte para el AppBuilder empleado por MS Katana.

Y lo otro, es la dependencia entre todos los paquetes de katana, en serio, puede resultar contradictorio 😦 y claro, este si que necesita del nuevo System.web, me refiero a Owin.dll :P… ¡naaa, es exagerando!

*Si alguien tiene información o sugerencias sobre este ejemplo le agradezco me lo haga saber en los comentarios.

**NOTA: Si quieres ver una muestra de como conectar y desconectar componentes OWIN haciendo uso de Katana mira este excelente articulo de Eduard Tomas

¿Y todo esto para que si yo siempre lo subo a IIS? es uno de los interrogantes más frecuentes…

Hostear aplicaciones OWIN en Windows Azure Worker Role

Así como hemos estado hosteando todo esto en una aplicación de consola es muy sencillo llevarlo a un entorno “real” y ponerlo en un Windows Azure Worker Role. Ya se escribió sobre esto en el sitio oficial de ASP.NET, haciendo uso de Katana por supuesto.

aquí va mi código con Nowin, Simple.Web y Fix:

    public class WorkerRole : RoleEntryPoint
    {
        private IDisposable _server;

        public override void Run()
        {
            Trace.TraceInformation("WebApiRole entry point called", "Information");
            while (true)
            {
                Thread.Sleep(10000);
                Trace.TraceInformation("Working", "Information");
            }
        }

        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections
            ServicePointManager.DefaultConnectionLimit = 12;

            // New code:
            var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"];
            string baseUri = string.Format("{0}://{1}", endpoint.Protocol, endpoint.IPEndpoint);

            Func<IDictionary<string, object>, Task> app = new Fixer()
                .Use((env, next) => Application.Run(env, t => next(env)))
                .Build();

            ServerBuilder builder = ServerBuilder.New()
                .SetAddress(endpoint.IPEndpoint.Address)
                .SetPort(82)
                .SetOwinApp(app);
            _server = builder.Start();

            Trace.TraceInformation(String.Format("Starting OWIN at {0}", baseUri), "Information");

            return base.OnStart();
        }

        public override void OnStop()
        {
            if(_server != null)
                _server.Dispose();
            base.OnStop();
        }
    }

    [UriTemplate("/")]
    public class Index : IGet, IOutput
    {
        public Status Get()
        {
            return 200;
        }

        public RawHtml Output
        {
            get { return "</pre>
<h1>¡Hola Azure!</h1>
<pre>
"; }
        }
    }

La configuración del endpoint es escuchando tanto publico como privado por el puerto 80, pero si te fijas el servidor esta escuchando por el puerto 82, esto por el balanceador de cargas del compute emulator.

El resultado, pues simple 🙂

image

En conclusión, esperemos y participemos de estas decisiones, que como vemos, como comunidad de usuarios nos pueden llegar a afectar y no permitamos que la decisión se tome solo porque Microsoft uso esto o aquello en sus plantillas de Visual Studio.

Hasta el próximo post

Anuncios
[OWIN] Uniéndolo todo sin KATANA IAppBuilder

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s