OWIN چیست

ASP.NET Core برای پشتیبانی از OWIN Specification ،فراهم کردن قابلیت های مورد نیاز برای اجرای برنامه های ASP.NET Core در سرورهای وابسته به OWIN و همچنین برای پشتیبانی از میان افزارهای وابسته به OWIN بر روی سرورهای ASP.NET Core ، ساخته شده است.

OWIN چیست

ASP.NET Core از OWIN(Open Web Interface for .Net) پشتیبانی می کند، و به برنامه های تحت وب اجازه می دهد ، که از وب سرورها جدا شوند .به علاوه OWIN ، یک راه استاندارد ، برای میان افزارهایی که در Pipeline ، (برای مدیریت درخواست های فردی و پاسخ های مربوط به آن )استفاده شده اند، را مشخص می کند.برنامه ها ومیان افزارهای ASP.NET Core   می توانند با برنامه ها ، سرورهاو میان افزارهایی که براساس OWIN  می باشند، تعامل داشته باشند.

بخش بندی:

-اجرای میان افزار OWIN در ASP.NET Pipeline.

-استفاده از ASP.NET Hosting روی سروری که براساس OWIN می باشد.

-اجرای ASP.NET Core روی سروری که براساس OWIN می باشد و دارای پشتیبانی WebSocketها می باشد.

-کلیدهای OWIN

اجرای میان افزار OWIN در ASP.NET Pipeline

ASP.NET Core مربوط به  پشتیبانی OWIN ، به عنوان بخشی از پکیج Microsoft.AspNetCore.Owin انتشار یافته است.   شما می توانید پشتیبانی OWIN را در پروژه خود با اضافه کردن این پکیج که یکی از متعلقات فایل Project.json   می باشد ، وارد کنید.که در زیر نشان داده شده است:

"dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.Owin": "1.0.0-rc1-final"
  },

میان افزار OWIN ، مطابق با مشخصات OWIN  می باشد ، که مشخص می کند

اینترفیس IDictionary<string, object> باید استفاده شود، و همچنین نیاز دارد تا کلیدهای خاصی تنظیم شود(مانند owin.ResponseBody) .ما می توانیم یک مثال ساده از یک میان افزار که ازمشخصات OWIN پیروی می کند برای نمایش "Hello World" ،ایجاد کنیم.این کار مطابق زیر انجام می شود.

public Task OwinHello(IDictionary<string, object> environment)
{
    string responseText = "Hello World via OWIN";
    byte[] responseBytes = Encoding.UTF8.GetBytes(responseText);

    // OWIN Environment Keys: http://owin.org/spec/owin-1.0.0.html
    var responseStream = (Stream)environment["owin.ResponseBody"];
    var responseHeaders = (IDictionary<string, string[]>)environment["owin.ResponseHeaders"];

    responseHeaders["Content-Length"] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) };
    responseHeaders["Content-Type"] = new string[] { "text/plain" };

    return responseStream.WriteAsync(responseBytes, 0, responseBytes.Length);

در مثال بالا ، توجه کنید که   متد یک Task(دستور) برمیگرداند و <IDictionary<string, object را می پذیرد که مورد نیاز OWIN می باشد. در داخل متد، این پارامتر برای بازیابی  Objectهای owin.ResponseBody و owin.ResponseHeaders از  environment dictionary ، استفاده می کند.یکبار که  هدرها  متناسب با محتویاتی که بازگردانده می شوند ، تنظیم شوند، یکTask )دستور( برگردانده می شود که نوشتن ناهمزمان جریان(Stream) پاسخ را نمایش می دهد.

اضافه کردن میان افزار OWIN به ASP.NET Pipeline با استفاده از extention method ی به نام UseOwin ، به راحتی انجام می شود.با توجه به متد OwinHello که در بالا نشان دادیم، اضافه کردن آن به Pipeline ، به صورت زیر انجام می شود:

public void Configure(IApplicationBuilder app)
{
    app.UseOwin(pipeline =>
    {
        pipeline(next => OwinHello);
    });
}

شما قطعا می توانید ، actionهای دیگری را  به جای Owin pipeline  پیکربندی کنید.به یاد داشته باشید  که هدرهای  پاسخ   (response headers) فقط  باید در چارچوب اولین باری که response stream نوشته شده اند ویرایش شوند بنابراین  Pipeline  را طبق آن  پیکربندی کنید.

نکته:

برای جلوگیری از افت راندمان برنامه، اجازه فراخوانی های چندین باره UseOwin ، داده نمی شود.

Componentهای OWIN به خوبی عمل می کنند اگر بایکدیگر گروه بندی شده باشند.

app.UseOwin(pipeline =>
{
    pipeline(next =>
  {
      // do something before
      return OwinHello;
      // do something after
  });
});

نکته:

پشتیبانی OWIN در ASP.NET Core یک کار تکاملی می باشد که برای پروژه Katana  انجام شد.Component ی به نام IAppBuilder که مربوط به پروژه ی Katana می باشد با IApplicationBuilder جایگزین شده است، اما اگر شما میان افزاری که براساس katana می باشد

 را داشته باشید،شما می توانید از آن در داخل برنامه ASP.NET Core از طریق  bridge ، استفاده کنید.

استفاده از ASP.NET Hosting روی سروری که براساس OWIN می باشد

از آنجایی  که ASP.NET مطابق با مشخصات OWIN می باشد سرورهایی که براساس OWIN می باشند ،می توانند میزبان(host) برنامه های ASP.NET باشند.

 یکی از سرورها Nowin (.Net Owin web server)می باشد. در سمپل این مقاله ، ما یک پروژه ساده قرار دادیم که دارای رفرنسی از Nowin  می باشد و از آن برای ایجاد یک سرور ساده که دارای قابلیت  self-hosting ASP.NET Core است استفاده می کنیم.

using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Owin;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNet.Http.Features;
using Nowin;

namespace NowinSample
{
    public class NowinServerFactory : IServerFactory
    {
        private Func<IFeatureCollection, Task> _callback;

        private Task HandleRequest(IDictionary<string, object> env)
        {
            return _callback(new FeatureCollection(new OwinFeatureCollection(env)));
        }

        public IFeatureCollection Initialize(IConfiguration configuration)
        {
            var builder = ServerBuilder.New()
                        .SetAddress(IPAddress.Any)
                        .SetPort(5000)
                        .SetOwinApp(HandleRequest);

            var serverFeatures = new FeatureCollection();
            serverFeatures.Set<INowinServerInformation>(new NowinServerInformation(builder));
            return serverFeatures;
        }

        public IDisposable Start(IFeatureCollection serverFeatures, 
                                 Func<IFeatureCollection, Task> application)
        {
            var information = serverFeatures.Get<INowinServerInformation>();
            _callback = application;
            INowinServer server = information.Builder.Build();
            server.Start();
            return server;
        }

        private class NowinServerInformation : INowinServerInformation
        {
            public NowinServerInformation(ServerBuilder builder)
            {
                Builder = builder;
            }

            public ServerBuilder Builder { get; private set; }

            public string Name
            {
                get
                {
                    return "Nowin";
                }
            }
        }
    }
}

IServerFactory یک اینترفیس می باشد که  نیاز به متدهای Initialize و Start دارد.Initialize  باید یک نمونه از IFeatureCollection برگرداند، که ما با  INowinServerInformation که شامل نام سرور می باشد ، نمونه را مقداردهی  می کنیم(پیاده سازی های خاص ممکن است قابلیت های اضافه تری را فراهم کند) . در این مثال کلاس NowinServerInformation  در زمان ساخت به عنوان یک کلاس Private تعریف شده است و در صورت نیاز به وسیله Initialize برگردانده می شود.

Initialize  ، پیکربندی سرور را به عهده دارد ،که  این کار به این صورت است که   مجموعه ای از fluent API، کدهای سخت را فراخوانی می کنند. سرور، برای دریافت درخواست ها (از هر IP address)  روی پورت5000 ،منتظر است.

توجه کنید که خط آخر مربوط به پیکربندی مربوط به متغیر builder ،مشخص می کند که درخواست ها توسط متد Private ی به نام HandleRequest  مدیریت خواهند شد.

Start بعد از Initialize فراخوانی می شود  و IFeatureCollection ساخته شده توسط Initialize و فراخوانی بازگشتی از Func<IFeatureCollection, Task>  را می پذیرد،.این فراخوانی بازگشتی ، به یک فیلد local انتساب داده می شود و نهایتا در همه ی درخواستهایی که از متد private  به نام HandleRequest انجام می شود فراخوانی می شود.

 با توجه به موارد گفته شده  ، همه ی موارد مورد نیاز برای اجرای برنامه ASP.NET ، بر روی یک  سرور سفارشی سازی شده ، شامل دستورات زیر در project.json است  .

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },
  
  "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.Owin": "1.0.0-rc1-final",
    "Nowin": "0.22.0"
  },

  "commands": {
      "web": "Microsoft.AspNet.Hosting --server NowinSample"
  },

زمانی که اجرا میگیرید ، این دستورات  بدنبال یک پکیجی به نام “NowinSample”  می گردند که شامل یک پیاده سازی  از IServerFactory  می باشد.اگر آن را پیدا کرد ، آن را مقدار دهی اولیه می کند و یک سرور را با جزئیاتی که در بالا گفته شد راه اندازی می کند.

اجرای ASP.NET Core روی سروری که براساس OWIN می باشد و دارای پشتیبانی WebSocketها می باشد

اگر بخواهیم یک مثال پیرامون به کارگیری ویژگی های سرورهای بر حسب OWIN  در تکنولوژی ASP.Net Core  بیان کنیم، می توانیم  WebSocket ها را نام ببریم. وب سرور .NET OWIN در مثال های قبلی استفاده شده است که از Web Socket های ساخته شده پشتیبانی می کند ، که می تواند توسط برنامه ی ASP.NET Core به کار گرفته شود.

public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.Use(async (context, next) =>
            {
                if (context.WebSockets.IsWebSocketRequest)
                {
                    WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
                    await EchoWebSocket(webSocket);
                }
                else
                {
                    await next();
                }
            });

            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello World");
            });
        }

        private async Task EchoWebSocket(WebSocket webSocket)
        {
            byte[] buffer = new byte[1024];
            WebSocketReceiveResult received = await webSocket.ReceiveAsync(
                new ArraySegment<byte>(buffer), CancellationToken.None);

            while (!webSocket.CloseStatus.HasValue)
            {
                // Echo anything we receive
                await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, received.Count), 
                    received.MessageType, received.EndOfMessage, CancellationToken.None);

                received = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), 
                    CancellationToken.None);
            }

            await webSocket.CloseAsync(webSocket.CloseStatus.Value, 
                webSocket.CloseStatusDescription, CancellationToken.None);
        }

        // Entry point for the application.        
        public static void Main(string[] args) => WebApplication.Run<Startup>(args);
    }
}

این نمونه  مانند   NowinServerFactory که قبلا استفاده کرده ایم پیکربندی شده است ، تنها تفاوتی که وجود دارد  درنحوه ی پیکربندی برنامه  در متد Configure می باشد.یک تست ساده با استفاده از یک Simple websocket client نشان می دهد این برنامه همانطوری که انتظار داشتیم کار می کند.

کلید های OWIN :

OWIN به شدت به استفاده از IDictionary<string,object>> که برای ارتباط اطلاعات از طریق تبادل درخواست/پاسخ HTTP می باشد بستگی دارد.ASP.NET Core ،تمامی کلیدهای مورد نیاز واختیاری که در مشخصات OWIN تعیین شده که برخی از آن ها مربوط به خود OWIN می باشد، را پیاده سازی می کند.توجه کنید برخی از کلیدها درمشخصات OWIN اختیاری می باشند ولی ممکن است از آن کلید ، در برخی از سناریوها استفاده شود.زمانی که از کلیدهای OWIN استفاده می کنید ، بهتر است لیست راهنمای کلید OWINو کلیدهای رایج را مرور کنید.

آموزش سی شارپ

دانلود نسخه ی PDF این مطلب