Partilhar via


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
    Отлично!!!, наконец появилась полностью законченная статья из трёх самостоятельных блоков. Однако, предлагаю в эту статью внести следующие исправления:
  1. Отредактировать блок, цитата: "Просто, у нас уже есть альтернативный вариант. А списывать ASP.NET и IIS со счетов ещё рано. А про то, как будет выглядеть конвейер IIS/ASP.NET при использовании OWIN, я покажу в следующей статье." на "Просто, у нас уже есть альтернативный вариант, а списывать ASP.NET и IIS со счетов ещё рано. Про то, как будет выглядеть конвейер IIS/ASP.NET при использовании OWIN, я покажу в следующей статье."
  2. В цитате: "Предлагаю посмотреть и познакомиться с полным описанием конвейера обработки запросов IIS и ASP.NET, который был проиллюстрирован тут, если вы пока ещё этого не сделали.", заменить "...проиллюстрирован тут..." на фразу "...проиллюстрирован в статье" со вставкой на фразу "...проиллюстрирован в статье" ссылку на соответствующую статью или на фразу "проиллюстрирован в примере ниже (выше) этой статьи".
  3. Отредактировать блок, цитата: "Всё начинается с того, что не используются никакие WAS и W3SVC, хотя эти службы имеют и выполняют свою положительную роль в составе IIS. А управляемая обёртка System.Net.HttpListener, которая напрямую работает с HTTP.SYS." на "Всё начинается с того, что не используются никакие WAS и W3SVC, хотя эти службы имеют и выполняют свою положительную роль в составе IIS. Управляемой обёрткой служит класс System.Net.HttpListener, который напрямую работает с HTTP.SYS."
  4. В предложении, цитата: ""Класс не новый, он появился ещё со времён .NET 2.0 и широко используется., в..." лишняя "точка", нужно её убрать.
  5. Предложение, цитата: "Реальный пример, как я уже отметил есть тут." отредактировать так же как и в пункте 2. Я не виноват!!!, это всё моё фасеточное зрение!!! ;)  :)) Жду новых статей!!!
  • Anonymous
    December 28, 2014
    Жук, тебе не программистом, а редакторов в районную газету работать))

  • Anonymous
    December 28, 2014
    Жук, спасибо за ценные замечания! Исправил вроде.

  • Anonymous
    December 29, 2014
    ;) не совсем исправил:

  1. "Управляемой обёртка служит класс..." правильнее будет "обёрткой...";
  2. в предложении, цитата: "Но всё же, есть некоторые соглашения, вез которых модуль не будет работать.", наверное всё же "без которых модуль...";
  3. Предложение, цитата: "Реальный пример, как я уже отметил есть тут." непонятно к чему относится, если к коду конфигурации, то наверное правильней так и написать, ссылка на вторую часть цикла статей есть же в предыдущем предложении.
  • Anonymous
    December 29, 2014
    Спасибо, и это исправил.

  • Anonymous
    February 19, 2016
    "Ниже показана схема работы конвейера (ссылка на pdf файл высокого качества)."  А можно ссылку? Эта не на то ссылается (

  • Anonymous
    February 19, 2016
    Исправил ссылку, спасибо.