
Просмотрите или скачайте образец кода
Выполнение связующего ПО в процессе ASP.NET
Поддержка OWIN со стороны ASP.NET Core развертывается в рамках пакета
Microsoft.AspNetCore.Owin. Чтобы импортировать поддержку OWIN в свой проект, добавьте пакет в виде зависимости в файл project.json:"dependencies": { "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.AspNetCore.Owin": "1.0.0" },
Связующее ПО OWIN соответствует спецификации OWIN, которая требует использовать интерфейс
Func<IDictionary<string, object>, Task> и настроить определенные ключи (например, 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/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.В следующем коде показано, как добавить связующее ПО
OwinHello (см. выше) в процесс ASP.NET с помощью метода расширения UseOwin.public void Configure(IApplicationBuilder app) { app.UseOwin(pipeline => { pipeline(next => OwinHello); }); }
Вы можете настроить и другие действия для процесса OWIN.
Заголовки ответов следует менять только перед первой записью в поток ответов.
Не нужно выполнять много вызовов к
UseOwin: это снижает производительность. Компоненты OWIN работают лучше, если их объединить.app.UseOwin(pipeline => { pipeline(next => { // do something before return OwinHello; // do something after }); });
Хостинг ASP.NET на OWIN-сервере
На OWIN-серверах можно размещать приложения ASP.NET. Один из таких серверов — Nowin, веб-сервер .NET OWIN. В пример для этой статьи мы добавили проект, который ссылается на Nowin и использует его для создания
IServer, способного самостоятельно размещать ASP.NET Core.using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; namespace NowinSample { public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseNowin() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } }
IServer — это интерфейс, который требует свойство Features и метод Start.Start отвечает за настройку и запуск сервера. Для этого используется серия вызовов API, настраивающих адреса, которые были проанализированы из IServerAddressesFeature. Обратите внимание: конфигурация переменной _builder указывает, что запросы будет обрабатывать параметр appFunc, ранее настроенный в методе. Эта функция вызывается по каждому запросу для обработки входящих запросов.Также мы добавим расширение
IWebHostBuilder, чтобы упростить добавление и настройку сервера Nowin.using System; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.Extensions.DependencyInjection; using Nowin; using NowinSample; namespace Microsoft.AspNetCore.Hosting { public static class NowinWebHostBuilderExtensions { public static IWebHostBuilder UseNowin(this IWebHostBuilder builder) { return builder.ConfigureServices(services => { services.AddSingleton<IServer, NowinServer>(); }); } public static IWebHostBuilder UseNowin(this IWebHostBuilder builder, Action<ServerBuilder> configure) { builder.ConfigureServices(services => { services.Configure(configure); }); return builder.UseNowin(); } } }
Затем необходимо вызвать расширение в Program.cs, чтобы выполнить приложение ASP.NET с помощью этого пользовательского сервера:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; namespace NowinSample { public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseNowin() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } }
Подробнее о серверах ASP.NET.
Выполните ASP.NET Core на OWIN-сервере и воспользуйтесь поддержкой WebSockets
Еще один способ использовать OWIN-серверы в ASP.NET Core — получить доступ к функциям типа WebSockets. Веб-сервер .NET OWIN из предыдущего примера поддерживает встроенные веб-сокеты, которые можно использовать в приложении 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); } }
Этот образец настраивается с помощью того же
NowinServer, что и предыдущий; единственное различие заключается в способе настройки приложения в методе Configure. Тест с помощью простого клиента веб-сокета демонстрирует приложение:
Среда OWIN
Среду OWIN можно создать с помощью
HttpContext.var environment = new OwinEnvironment(HttpContext); var features = new OwinFeatureCollection(environment);
Ключи OWIN
Для передачи информации через обмен данными HTTP-запрос/ответ OWIN необходим объект
IDictionary<string,object>. ASP.NET Core реализует ключи, указанные ниже. См. основную спецификацию, расширения и Основные правила работы с OWIN.Запрос данных (OWIN v1.0.0)
| Ключ | Значение (тип) | Описание |
|---|---|---|
| owin.RequestScheme | Строка | |
| owin.RequestMethod | Строка | |
| owin.RequestPathBase | Строка | |
| owin.RequestPath | Строка | |
| owin.RequestQueryString | Строка | |
| owin.RequestProtocol | Строка | |
| owin.RequestHeaders | IDictionary<string,string[]> | |
| owin.RequestBody | Поток |
Запрос данных (OWIN v1.1.0)
| Ключ | Значение (тип) | Описание |
|---|---|---|
| owin.RequestId | Строка | Необязательно |
Ответные данные (OWIN v1.0.0)
| Ключ | Значение (тип) | Описание |
|---|---|---|
| owin.ResponseStatusCode | int | Необязательно |
| owin.ResponseReasonPhrase | Строка | Необязательно |
| owin.ResponseHeaders | IDictionary<string,string[]> | |
| owin.ResponseBody | Поток |
Другие данные (OWIN v1.0.0)
| Ключ | Значение (тип) | Описание |
|---|---|---|
| owin.CallCancelled | CancellationToken | |
| owin.Version | Строка |
Общие ключи
| Ключ | Значение (тип) | Описание |
|---|---|---|
| ssl.ClientCertificate | X509Certificate | |
| ssl.LoadClientCertAsync | FuncTask | |
| server.RemoteIpAddress | Строка | |
| server.RemotePort | Строка | |
| server.LocalIpAddress | Строка | |
| server.LocalPort | Строка | |
| server.IsLocal | bool | |
| server.OnSendingHeaders | ActionActionobject,object |
SendFiles v0.3.0
| Ключ | Значение (тип) | Описание |
|---|---|---|
| sendfile.SendAsync | См. Передача подписи | По запросу |
Opaque v0.3.0
| Ключ | Значение (тип) | Описание |
|---|---|---|
| opaque.Version | Строка | |
| opaque.Upgrade | OpaqueUpgrade | См. Передача подписи |
| opaque.Stream | Поток | |
| opaque.CallCancelled | CancellationToken |
WebSocket v0.3.0
| Ключ | Значение (тип) | Описание |
|---|---|---|
| websocket.Version | Строка | |
| websocket.Accept | WebSocketAccept | См. Передача подписи |
| websocket.AcceptAlt | Не указано | |
| websocket.SubProtocol | Строка | См. шаг 5.5 в Разделе 4.2.2 RFC6455 |
| websocket.SendAsync | WebSocketSendAsync | См. Передача подписи |
| websocket.ReceiveAsync | WebSocketReceiveAsync | См. Передача подписи |
| websocket.CloseAsync | WebSocketCloseAsync | См. Передача подписи |
| websocket.CallCancelled | CancellationToken | |
| websocket.ClientCloseStatus | int | Необязательно |
| websocket.ClientCloseDescription | Строка | Необязательно |

