Microsoft OWIN и конвейер обработки запросов ASP.NET. Часть третья, детальное описание конвейера OWIN для веб-приложения не использующего IIS и ASP.NET.
В данной статье я опишу конвейер обработки запросов веб-приложения, которое построено по спецификации OWIN с использованием проекта Katana. При этом не используются IIS/ASP.NET. Спецификация OWIN была описана в данной статье, а пример реального приложения (версия на английском), построенного по этой спецификации, был показан в данной. Не использовать IIS/ASP.NET, именно в этом случае мы получаем всю мощь и гибкость, используя Katana. Но я при этом не говорю, что надо отказываться от IIS. Просто, у нас уже есть альтернативный вариант, а списывать ASP.NET и IIS со счетов ещё рано. Про то, как будет выглядеть конвейер IIS/ASP.NET при использовании OWIN, я покажу в следующей статье. Предлагаю посмотреть и познакомиться с полным описанием конвейера обработки запросов IIS и ASP.NET, который был проиллюстрирован проиллюстрирован в статье "Общее описание конвейера IIS и ASP.NET до появления спецификации OWIN", если вы пока ещё этого не сделали. Чтобы можно было наглядно представить и сравнить, какие кординальные изменения произошли. Модернизация классического конвейера IIS 6, которая была сделана при переходе на IIS 7 и выше, так называемый "интегрированный режим" (как вы знаете он используется и в IIS 7.5, IIS 8, IIS 8.5), была большим шагом вперёд. Большим шагом впрерёд в сторону ещё большего использования управляемой среды и упраляемого кода (среда CLR, платформа .NET Framework) и уменьшения использования неуправляемого, что сильно облегчает жизнь и не может не радовать. Но вот полностью отказаться от использования "старого багажа" не так то просто. Одна из основных причин – поддержка и совместимость уже имеющихся приложений. Без этого никак. Ещё больший шаг впрерёд, или даже целых два это – OWIN, и проект Katana. Это новая инфраструктура, которая целиком и полностью опирается на управляемый код. Нативного кода тут нет, ну или почти нет. Весь конвейер обработки запросов строится при помощи управляемого кода .NET и он открыт. Ниже показана схема работы конвейера (ссылка на pdf файл высокого качества).
Всё начинается с того, что не используются никакие WAS и W3SVC, хотя эти службы имеют и выполняют свою положительную роль в составе IIS. Управляемой обёрткой служит класс System.Net.HttpListener, который напрямую работает с HTTP.SYS. Класс не новый, он появился ещё со времён .NET 2.0 и широко используется, в том числе и для написания собственнх HTTP-серверов или простых прослушивателей протокола. Но это не главное, главное то, что строится целая веб-инфраструктура при помощи управляемого кода (платформа .NET Framework) по спецификации OWIN. Примером такого сервера и служит класс OwinHttpListener из проекта Katana, использующий HttpListener из библиотеки FCL и представляет собой OWIN-совместимый сервер. Непосредственно он занимается приёмом и отправкой запросов. Здесь важную роль играет метод StartProcessingRequest(HttpListenerContext context). Дальше запрос передаётся на обработку модулям. Настройка модулей происходит не путём использования XML файла конфигурации, а при помощи кода конфигурации. Реальный пример, как я уже отметил есть тут. В отличие от конвейера IIS/ASP.NET запросы обрабатываются только модулями. Нет обработчиков HTTP-данных (HttpHandler) специально предназначенных для обработки результирующих данных. Модули OWIN не имеют ничего общего с HTTP-модулями (HttpModule) IIS. Они не подписываются на события, тут нет такого понятия, а вызываются цепочкой: каждый модуль может вызвать следующий или завершить обработку запроса. На них не закладывается жёсткое ограничение в виде реализации интерфейса. Но всё же, есть некоторые соглашения, без которых модуль не будет работать. В роли модуля может выступать как класс, так и отдельный метод. Метод обычно используется если задачи модуля небольшие, например – трассировка. Если надо подключить целую платформу типа Web API или SignalR, то тут уже разумнее иметь класс. Ниже представлены примеры кода в случае метода
using AppFunc = Func<IDictionary<string, object>, Task>;
//. . . . . . . . . . . . . . . . .
// Делегат в роли модуля.
var module = new Func<AppFunc, AppFunc>(
nextModule => enviroment =>
{
// Обработать запрос и отправить ответ
{
// Работа по обработке запроса.
}
// или передать управление следующему модулю.
return nextModule(enviroment);
});
и класса.
// Произвольный класс как модуль OWIN.
public class ArbitraryClass
{
private readonly Func<IDictionary<string, object>, Task> nextModule;
// Параметр nextModule обязательный, можно также передать любое количество
// других параметров.
public ArbitraryClass(Func<IDictionary<string, object>, Task> nextModule,
params object[] args)
{
Contract.Requires<ArgumentNullException>(nextModule != null);
this.nextModule = nextModule;
}
// Обработать запрос. Имя – Invoke и сигнатура обязательны.
public Task Invoke(IDictionary<string, object> enviroment)
{
// Обработать запрос и отправить ответ
{
// Работа по обработке запроса.
}
// или передать управление следующему модулю.
return this.nextModule(enviroment);
}
}
Как видно из вышеописанного, всё достаточно просто и открыто. Нет нативных модулей, отдельных обработчиков и прочего. То есть ковейер не так сложно устроен, как здесь. И это – здорово.
Comments
- Anonymous
December 27, 2014
Отлично!!!, наконец появилась полностью законченная статья из трёх самостоятельных блоков. Однако, предлагаю в эту статью внести следующие исправления:
- Отредактировать блок, цитата: "Просто, у нас уже есть альтернативный вариант. А списывать ASP.NET и IIS со счетов ещё рано. А про то, как будет выглядеть конвейер IIS/ASP.NET при использовании OWIN, я покажу в следующей статье." на "Просто, у нас уже есть альтернативный вариант, а списывать ASP.NET и IIS со счетов ещё рано. Про то, как будет выглядеть конвейер IIS/ASP.NET при использовании OWIN, я покажу в следующей статье."
- В цитате: "Предлагаю посмотреть и познакомиться с полным описанием конвейера обработки запросов IIS и ASP.NET, который был проиллюстрирован тут, если вы пока ещё этого не сделали.", заменить "...проиллюстрирован тут..." на фразу "...проиллюстрирован в статье" со вставкой на фразу "...проиллюстрирован в статье" ссылку на соответствующую статью или на фразу "проиллюстрирован в примере ниже (выше) этой статьи".
- Отредактировать блок, цитата: "Всё начинается с того, что не используются никакие WAS и W3SVC, хотя эти службы имеют и выполняют свою положительную роль в составе IIS. А управляемая обёртка System.Net.HttpListener, которая напрямую работает с HTTP.SYS." на "Всё начинается с того, что не используются никакие WAS и W3SVC, хотя эти службы имеют и выполняют свою положительную роль в составе IIS. Управляемой обёрткой служит класс System.Net.HttpListener, который напрямую работает с HTTP.SYS."
- В предложении, цитата: ""Класс не новый, он появился ещё со времён .NET 2.0 и широко используется., в..." лишняя "точка", нужно её убрать.
- Предложение, цитата: "Реальный пример, как я уже отметил есть тут." отредактировать так же как и в пункте 2. Я не виноват!!!, это всё моё фасеточное зрение!!! ;) :)) Жду новых статей!!!
Anonymous
December 28, 2014
Жук, тебе не программистом, а редакторов в районную газету работать))Anonymous
December 28, 2014
Жук, спасибо за ценные замечания! Исправил вроде.Anonymous
December 29, 2014
;) не совсем исправил:
- "Управляемой обёртка служит класс..." правильнее будет "обёрткой...";
- в предложении, цитата: "Но всё же, есть некоторые соглашения, вез которых модуль не будет работать.", наверное всё же "без которых модуль...";
- Предложение, цитата: "Реальный пример, как я уже отметил есть тут." непонятно к чему относится, если к коду конфигурации, то наверное правильней так и написать, ссылка на вторую часть цикла статей есть же в предыдущем предложении.
Anonymous
December 29, 2014
Спасибо, и это исправил.Anonymous
February 19, 2016
"Ниже показана схема работы конвейера (ссылка на pdf файл высокого качества)." А можно ссылку? Эта не на то ссылается (Anonymous
February 19, 2016
Исправил ссылку, спасибо.