亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Self Host模式下的ASP. NET Web API是如何進行請求的監聽與處理的?

2019-11-17 01:26:33
字體:
來源:轉載
供稿:網友

Self Host模式下的asp. NET Web API是如何進行請求的監聽與處理的?

構成asp.net Web API核心框架的消息處理管道既不關心請求消息來源于何處,也不需要考慮響應消息歸于何方。當我們采用Web Host模式將一個ASP.NET應用作為目標Web API的宿主時,實際上是由ASP.NET管道解決了這兩個問題。具體來說,ASP.NET自身的URL路由系統借助于HttpControllerHandler這個自定義的HttpHandler實現了ASP.NET管道和ASP.NET Web API管道之間的“連通”,但是在Self Host寄宿模式下,請求的監聽、接收和響應又是如何實現的呢?[本文已經同步到《How ASP.NET Web API Works?》]

目錄 一、HttpBinding模型     Binding模型     HttpBinding     實例演示:直接利用HttpBinding進行請求的接收和響應 二、HttpSelfHostServer     HttpSelfHostConfiguration     HttpSelfHostServer與消息處理管道     實例演示:創建自定義HttpServer模擬HttpSelfHostServer的工作原理

一、HttpBinding模型

和WCF服務一樣,我們可以采用Self Host模式將Web API寄宿于任何一種類型的托管應用程序下,宿主可以是一個Windows Form應用、WPF應用、控制臺應用以及Windows Service。Self Host模式下的WCF和ASP.NET Web API不僅外在表現形式極為相似,其實在內部實現原理上也是一致的。

Binding模型

對于WCF具有基本了解的讀者應該都知道,它是一個基于消息的分布式通信框架,消息交換借助于客戶端和服務端對等的終結點(Endpoint)來完成,而終結點由經典的ABC(Address、Binding、Contract)三元素組成。WCF同樣具有一個處理消息的管道,這個管道是一組Channel的有序組合,WCF下的Channel相對于ASP.NET Web API下的HttpMessageHandler。

WCF的消息處理管道的締造者是作為終結點三要素之一的Binding。Binding不僅僅為服務端創建用于接收請求回復響應的管道,同時也為客戶端創建發送請求接收響應的管道。Binding模型本身也相對比較復雜,所以我們不可能對其進行詳細討論。如果讀者對此比較感興趣,可以參閱《WCF的綁定模型》。由于ASP.NET Web API只是利用HttpBinding創建服務端消息處理管道,所以我們只討論Binding的服務端模型。

從結構上講,一個Binding是若干BindingElement對象的有序組合。對于最終創建的消息處理管道來說,每個Channel都對應著一個BindingElement。BindingElement并非直接創建對應的Channel,由它直接創建的實際上是一個名為ChannelListener的對象,Channel由ChannelListener創建。右圖基本揭示了Binding的服務端模型。

顧名思義,ChannelListener用于請求的監聽。當Binding對象開啟(調用其Open方法)時,每個BindingElement會創建各自的ChannelListener。這些ChannelListener按照對應BindingElement的順序連接成串,位于底部(面向傳輸層)的ChannelListener被綁定到某個端口進行請求的監聽。一旦探測到抵達的請求,它會利用由所有ChannelListener創建的Channel組成的管道來接收并處理該請求。對于最終需要返回的響應消息,則按照從上到下的順序被這個管道進行處理并最終返回給客戶端。

對于這個由Channel組成消息處理管道來說,有兩種類型的Channel是必不可少的。一種是面向傳輸層用于發送和接收消息的TransportChannel,另一種被稱為MessageEncodingChannel則負責對接收的消息實施解碼并對發送的消息實施編碼。TransportChannel由TransportChannelListener創建,而后者由TransportBindingElement創建。與之類似,MessageEncodingBindingElement是MessageEncodingChannelListener的創建者,而后者又是MessageEncodingChannel的創建者。

如果采用Self Host寄宿模式,請求的監聽是由一個類型為HttpBinding的Binding對象創建的ChannelListener管道來完成的,由它創建的管道實現了針對請求的接收和針對響應的回復。HttpBinding類型定義在“System.Web.Http.SelfHost.Channels”命名空間下,我們接下來對它進行詳細講述。

HttpBinding

Binding存在的目的在于創建用于處理和傳輸消息的信道棧,組成信道棧的每一個Channel均對應著一個BindingElement,所以Binding本身處理消息的能力由其BindingElement的組成來決定,我們可以通過分析BindingElement的組成來了解消息最終是如何處理的?,F在我們就來討論一下ASP.NET Web API在Self Host模式下使用的HttpBinding由哪些BindingElement構成。

如左圖所示,HttpBinding僅僅由兩種必需的BindingElement構成,TransportBindingElement的類型決定于最終采用的傳輸協議。如果采用單純的HTTP協議,采用的TransportBindingElement是一個HttpTransportBindingElement對象。在采用HTTPS協議的情況下,TransportBindingElement的類型是HttpsTransportBindingElement。

我們現在著重來分析與消息編碼/解碼相關的BindingElement,從圖3-11可以看出這是一個HttpMessageEncodingBindingElement對象(HttpMessageEncodingBindingElement是一個定義在程序集“System.Web.Http.SelfHost.dll”中的內部類型),它最終會創建一個MessageEncoder對象完成針對消息的編碼/解碼工作。

ASP.NET Web API分別利用 HttPRequestMessage和HttpResponseMessage對象表示消息處理管道處理的請求和響應,而WCF消息處理管道的請求和響應均是一個Message對象(Message是定義在命名空間“System.ServiceModel.Channels”下的一個抽象類型)。經過HttpMessageEncoder解碼后的Message對象會轉成一個HttpRequestMessage對象并傳入ASP.NET Web API消息處理管道進行處理,由此管道返回的HttpResponseMessage對象需要轉換成一個Message對象并由HttpMessageEncoder根據需求進行解碼。

這個具體的消息實際上是一個HttpMessage對象,HttpMessage繼承自抽象類Message,它是一個定義在程序集“System.Web.Http.SelfHost.dll”中的內部類型。如下面的代碼片斷所示,HttpMessage實際上是對一個HttpRequestMessage或者HttpResponseMessage對象的封裝,兩個方法GetHttpRequestMessage和GetHttpResponseMessage分別用于提取被封裝的HttpRequestMessage和HttpResponseMessage對象。

   1: internal sealed class HttpMessage : Message
   2: {
   3:     //其他成員   
   4:     public HttpMessage(HttpRequestMessage request);
   5:     public HttpMessage(HttpResponseMessage response);
   6:    
   7:     public HttpRequestMessage  GetHttpRequestMessage(bool extract);
   8:     public HttpResponseMessage GetHttpResponseMessage(bool extract);
   9: }

這兩個方法均具有一個布爾類型的參數extract,它表示是否“抽取”被封裝的HttpRequestMessage/HttpResponseMessage對象。如果指定的參數值為True,方法執行之后被封裝的HttpRequestMessage/HttpResponseMessage對象會從HttpMessage對象中抽取出來,所以再次調用它們會返回Null。

再次將我們的關注點拉回到由HttpBinding創建的消息處理管道上。當我們開啟HttpBinding后,它利用創建的ChannelListener管道監聽請求。一旦探測到抵達的請求后,基于HTTP/HTTPS協議的TransportChannel會負責接收請求。接收的二進制數據會由MessageEncoder解碼后生成一個HttpRequestMessage對象,該對象進而被封裝成一個HttpMessage對象,傳入消息處理管道的HttpRequestMessage是直接通過調用GetHttpRequestMessage方法從該HttpMessage對象中提取的。

當ASP.NET Web API消息處理管道完成了請求的處理并最終輸出一個HttpResponseMessage對象后,該對象同樣先被封裝成一個HttpMessage對象。在通過傳輸層將響應返回給客戶端之前,需要利用MessageEncoder對其進行編碼,而解碼的內容實際上就是調用GetHttpResponseMessage方法提取的HttpResponseMessage對象。

實例演示:直接利用HttpBinding進行請求的接收和響應

當我們采用Self Host寄宿模式將一個非Web應用程序作為目標Web API的宿主時,最終網絡監聽任務實際上是由HttpBinding創建的ChannelListener管道來完成的,而ChannelListener管道創建的消息處理管道最終實現了對請求的接收和對響應的發送。為了讓讀者對此具有深刻的認識,我們通過一個簡單的實例來演示如何直接使用HttpBinding實現對請求的監聽、接收和響應。

我們創建一個空的控制臺程序作為監聽服務器,它相當于Self Host寄宿模式下的宿主程序。如下面的代碼片斷所示,我們創建了一個HttpBinding,并指定監聽地址("http://127.0.0.1:3721")調用其BuildChannelListener<IReplyChannel>方法創建了一個ChannelListener管道(返回的是組成管道的第一個ChannelListener對象)。在調用Open方法開啟該ChannelListener管道之后,我們調用其AcceptChannel方法創建了消息處理管道,返回的是組成管道的第一個Channel對象。在Open方法將其開啟后,我們在一個While循環中調用Channel對象的ReceiveRequest方法進行請求的監聽和接收。

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         Uri listenUri = new Uri("http://127.0.0.1:3721");
   6:         Binding binding = new HttpBinding();
   7:  
   8:         //創建、開啟信道監聽器
   9:         IChannelListener<IReplyChannel> channelListener = binding.BuildChannelListener<IReplyChannel>(listenUri);
  10:         channelListener.Open();
  11:  
  12:         //創建、開啟回復信道
  13:         IReplyChannel channel = channelListener.AcceptChannel(TimeSpan.MaxValue);
  14:         channel.Open();
  15:  
  16:         //開始監聽
  17:         while (true)
  18:         {
  19:             //接收輸出請求消息
  20:             RequestContext requestContext = channel.ReceiveRequest(TimeSpan.MaxValue);
  21:             PrintRequestMessage(requestContext.RequestMessage);
  22:             //消息回復
  23:             requestContext.Reply(CreateResponseMessage());
  24:         }
  25:     }
  26: }

對于成功接收的消息,我們調用具有如下定義的PrintRequestMessage方法將相關的信息打印在控制臺上。通過上面的介紹我們知道這個接收到的消息實際上是一個HttpMessage對象,由于這是一個內部類型,所以我們只能以反射的方式調用其GetHttpRequestMessage方法獲取被封裝的HttpRequestMessage對象。在得到表示請求的HttpRequestMessage對象之后,我們將請求地址和所有報頭輸出到控制臺上。

   1: private static void PrintRequestMessage(Message message)
   2: {
   3:     MethodInfo method = message.GetType().GetMethod("GetHttpRequestMessage");
   4:     HttpRequestMessage request = (HttpRequestMessage)method.Invoke(message, new object[]{false});
   5:  
   6:     Console.WriteLine("{0, -15}:{1}", "RequestUri", request.RequestUri);
   7:     foreach (var header in request.Headers)
   8:     {
   9:         Console.WriteLine("{0, -15}:{1}", header.Key, string.Join("," ,header.Value.ToArray()));
  10:     }
  11: }

在對請求進行處理之后,我們需要創建一個Message對象對該請求予以響應,響應消息的創建是通過CreateResponseMessage方法完成的。如下面的代碼片斷所示,我們首先創建了一個響應狀態為“200, OK”的HttpResponseMessage對象,并將其表示主體內容的Content屬性設置為一個ObjectContent<Em

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
92看片淫黄大片欧美看国产片| 欧美综合国产精品久久丁香| 精品国产网站地址| 亚洲欧美国产高清va在线播| 国产精品自产拍在线观| 欧美裸体xxxx| 狠狠色狠狠色综合日日小说| 国产精品爽黄69| 日韩在线观看网站| 欧美亚洲国产日韩2020| 精品成人69xx.xyz| 欧美精品在线免费播放| 97国产精品久久| 国产精品久久久久久一区二区| 奇米四色中文综合久久| 亚洲最新av在线网站| 26uuu国产精品视频| 色偷偷av一区二区三区乱| 欧美精品在线极品| 午夜精品一区二区三区在线播放| 亚洲性无码av在线| 自拍视频国产精品| 色av吧综合网| 国产精彩精品视频| 日韩电影在线观看免费| 精品激情国产视频| 九九热精品视频国产| 精品美女永久免费视频| 中文字幕亚洲色图| 一区二区三区视频在线| 欧美一级视频在线观看| 日韩av在线精品| 精品亚洲一区二区三区| 欧美大码xxxx| 精品视频一区在线视频| 亚洲香蕉在线观看| 97涩涩爰在线观看亚洲| 97成人精品区在线播放| 国产成人在线播放| 欧美午夜视频一区二区| 最近更新的2019中文字幕| 久久成人人人人精品欧| 日韩精品视频在线播放| 色哟哟网站入口亚洲精品| 91精品国产沙发| 日韩中文字幕久久| 国产精品一区二区av影院萌芽| 97人人做人人爱| 亚洲性线免费观看视频成熟| 久久精品一区中文字幕| 亚洲精品电影在线观看| 久久久久亚洲精品国产| 欧美亚洲激情视频| 国产成人在线亚洲欧美| 欧美极品少妇xxxxx| 成人网在线观看| 国产精品久久77777| 91av在线视频观看| 欧美在线视频一区| 国产一区二区丝袜| 亚洲国产欧美自拍| 日韩免费av片在线观看| 国产精品情侣自拍| 欧美高清视频一区二区| 日韩精品福利在线| 欧美日韩国产色视频| 欧美肥老妇视频| 国产主播在线一区| 日韩国产高清污视频在线观看| 一区二区三区国产在线观看| 久久国产精品影视| 中日韩美女免费视频网站在线观看| 日韩一区视频在线| 欧美性生交大片免网| 欧美性色xo影院| 久久久91精品国产一区不卡| 国产精品九九久久久久久久| 欧美精品在线视频观看| 综合国产在线视频| 国产成人精品av在线| 亚洲人成电影在线观看天堂色| 日韩欧美aaa| 亚洲天堂一区二区三区| 亚洲一区二区免费在线| 日韩中文字幕亚洲| 国产精品久久久久久久9999| 国产精品久久久久久久久久ktv| 51精品国产黑色丝袜高跟鞋| 久久69精品久久久久久久电影好| 成人xxxxx| 精品久久久久久中文字幕一区奶水| 久久精视频免费在线久久完整在线看| 国产精品偷伦一区二区| 日韩av在线电影网| 欧美一级视频在线观看| 国产成人亚洲综合青青| 日韩精品极品在线观看播放免费视频| 亚洲国产小视频在线观看| 91在线看www| 欧美日韩福利在线观看| 亚洲天堂av综合网| 国产精品一区二区三区在线播放| 最近2019年手机中文字幕| 成人激情视频免费在线| 日本成人免费在线| 国产精品极品美女在线观看免费| 欧美黄色小视频| 亚洲影影院av| 久国内精品在线| 亚洲无限乱码一二三四麻| 亚洲区免费影片| 亚洲自拍在线观看| 国产精品亚洲欧美导航| 国产精品视频区| 久久人91精品久久久久久不卡| 韩国一区二区电影| 亚洲综合在线小说| 97精品视频在线观看| 日韩av电影在线播放| 欧美大码xxxx| 国产精品天天狠天天看| 成人av在线亚洲| 国产一区二区三区中文| 中文字幕亚洲一区二区三区五十路| 亚洲精品一区久久久久久| 国产在线视频一区| 国产午夜精品一区理论片飘花| 欧美精品手机在线| 成人免费看吃奶视频网站| 欧美高清在线视频观看不卡| 成人黄色片网站| 尤物yw午夜国产精品视频明星| 欧美激情精品久久久| 97视频在线观看免费高清完整版在线观看| 精品国产乱码久久久久久虫虫漫画| 欧美亚洲国产日韩2020| 亚洲va欧美va国产综合剧情| 久久人人看视频| 麻豆一区二区在线观看| 欧美成人精品一区二区| 欧美三级欧美成人高清www| 色综合五月天导航| 久久资源免费视频| 欧美精品九九久久| 国产精品欧美风情| 狠狠综合久久av一区二区小说| 久久久久久久国产精品| 97在线视频观看| 国产精品欧美风情| 亚洲男人天堂2024| 69久久夜色精品国产69乱青草| 成人激情免费在线| 欧美丰满老妇厨房牲生活| 少妇av一区二区三区| 久久精品国产亚洲一区二区| 日韩亚洲综合在线| 欧美精品久久久久a| 大胆欧美人体视频| 午夜精品一区二区三区在线视| 尤物精品国产第一福利三区| 精品国产91乱高清在线观看| 日韩精品视频在线播放| 亚洲深夜福利视频| 国产精品麻豆va在线播放|