日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.Net Core HttpClient处理响应压缩

發布時間:2023/12/4 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net Core HttpClient处理响应压缩 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

????在上篇文章[ASP.NET Core中的響應壓縮]中我們談到了在ASP.NET Core服務端處理關于響應壓縮的請求,服務端的主要工作就是根據Content-Encoding頭信息判斷采用哪種方式壓縮并返回。之前在群里有人問道過,現在的網絡帶寬這么高了還有必要在服務端針對請求進行壓縮嗎?確實,如今分布式和負載均衡技術這么成熟,很多需要處理高并發大數據的場景都可以通過增加服務器節點來進行。但是,在資源受限的情況下,或者是還沒必要為了某一個點去增加新的服務器節點的時候,我們還是要采用一些程序本身的常規處理手段來進行處理。筆者個人認為響應壓縮的使用場景是這樣的,在帶寬壓力比較緊張的情況,且CPU資源比較充足的情況下,使用響應壓縮整體效果還是比較明顯的。
????有壓縮就有解壓,而解壓的工作就是在請求客戶端處理的。比如瀏覽器,這是我們最常用的Http客戶端,許多瀏覽器都是默認在我們發出請求的時候(比如我們瀏覽網頁的時候)在Request Head中添加Content-Encoding,然后根據響應信息處理相關解壓。這些都源于瀏覽器已經內置了關于請求壓縮和解壓的機制。類似的還有許多,比如常用的代理抓包工具Filder也是內置這種機制的。只不過需要手動去處理,但實現方式都是一樣的。有時候我們在自己寫程序的過程中也需要使用這種機制,在傳統的.Net HttpWebRequest類庫中,并沒有這種機制,后來版本中加入了HttpClient,有自帶的機制可以處理這種操作,.Net Core作為后起之秀直接將HttpClient扶正,并且在此基礎上改良了HttpClientFactory,接下來我們就來探究一下在.Net Core中使用HttpClient處理響應壓縮的機制。

使用方式

首先我們來看一下直接在HttpClient中如何處理響應壓縮

//自定義HttpClientHandler實例 HttpClientHandler httpClientHandler = new HttpClientHandler {AutomaticDecompression = DecompressionMethods.GZip }; //使用傳遞自定義HttpClientHandler實例的構造函數 using (HttpClient client = new HttpClient(httpClientHandler)) {var response = await client.GetAsync($"http://MyDemo/Home/GetPerson?userId={userId}"); }

這個操作還是非常簡單的,我們操作的并不是HttpClient的屬性而是HttpClientHandler中的屬性,我們在之前的文章[.NET Core HttpClient源碼探究]中曾探討過,HttpClient的本質其實就是HttpMessageHandler,而HttpClient真正使用到的是HttpMessageHandler最重要的一個子類HttpClientHandler,所有的請求操作都是通過HttpMessageHandler進行的。我們可以看到AutomaticDecompression接受的是DecompressionMethods枚舉,既然是枚舉就說明包含了不止一個值,接下來我們查看DecompressionMethods中的源碼

[Flags] public enum DecompressionMethods {// 使用所有壓縮解壓縮算法。All = -1,// 不使用解壓None = 0x0,// 使用gzip解壓算法GZip = 0x1,// 使用deflate解壓算法Deflate = 0x2,// 使用Brotli解壓算法Brotli = 0x4 }

該枚舉默認都是針對常用輸出解壓算法,接下來我們看一下在HttpClientFactory中如何處理響應壓縮。在之前的文章[.NET Core HttpClientFactory+Consul實現服務發現]中我們曾探討過HttpClientFactory的大致工作方式默認PrimaryHandler傳遞的就是HttpClientHandler實例,而且在我們注冊HttpClientFactory的時候是可以通過ConfigurePrimaryHttpMessageHandler自定義PrimaryHandler的默認值,接下來我們具體代碼實現

services.AddHttpClient("mydemo", c => {c.BaseAddress = new Uri("http://MyDemo/"); }).ConfigurePrimaryHttpMessageHandler(provider=> new HttpClientHandler {AutomaticDecompression = DecompressionMethods.GZip });

其實在注冊HttpClientFactory的時候還可以使用自定義的HttpClient,具體的使用方式是這樣的

services.AddHttpClient("mydemo", c => {c.BaseAddress = new Uri("http://MyDemo/"); }).ConfigureHttpClient(provider => new HttpClient(new HttpClientHandler {AutomaticDecompression = DecompressionMethods.GZip }));

HttpClient確實幫我們做了好多事情,只需要簡單的配置一下就開啟了針對響應壓縮的處理。這更勾起了我們對HttpClient的探討,接下來我們就通過源碼的方式查看它是如何發起可響應壓縮請求,并解壓響應結果的。

源碼探究

通過上面的使用方式我們得知,無論使用哪種形式,最終都是針對HttpClientHandler做配置操作,接下來我們查看HttpClientHandler類[點擊查看源碼????]中AutomaticDecompression屬性的代碼

public DecompressionMethods AutomaticDecompression {get => _underlyingHandler.AutomaticDecompression;set => _underlyingHandler.AutomaticDecompression = value; }

它本身的值操作來自_underlyingHandler這個對象,也就是說讀取和設置都是在操作_underlyingHandler.AutomaticDecompression,我們查找到_underlyingHandler對象的聲明位置

private readonly SocketsHttpHandler _underlyingHandler;

這里說明一下,HttpClient的實質工作類是HttpClientHandler,而HttpClientHandler真正發起請求是依靠的SocketsHttpHandler這個類,也就是說SocketsHttpHandler是最原始發起請求的類。HttpClientHandler本質還是通過SocketsHttpHandler發起的Http請求,接下來我們就查看SocketsHttpHandler類[點擊查看源碼????]是如何處理AutomaticDecompression這個屬性的

public DecompressionMethods AutomaticDecompression {get => _settings._automaticDecompression;set{CheckDisposedOrStarted();_settings._automaticDecompression = value;} }

這里的_settings不再是具體的功能類,而是用于初始化或者保存SocketsHttpHandler的部分屬性值的配置類

private readonly HttpConnectionSettings _settings = new HttpConnectionSettings();

這里我們不在分析SocketsHttpHandler出處理響應壓縮之外的其他代碼,所以具體就不再看這些了,直接查找_settings._automaticDecompression屬性引用的地方,最終找到了這段代碼

if (settings._automaticDecompression != DecompressionMethods.None) {handler = new DecompressionHandler(settings._automaticDecompression, handler); }

這里就比較清晰了,真正處理請求響應壓縮相關的都是在DecompressionHandler中。正如我們之前所說的,HttpClient真正的工作方式就是一些實現自HttpMessageHandler的子類在工作,它把不同功能的實現模塊都封裝成了具體的Handler中。當你需要使用哪個模塊的功能,直接使用對應的Handler操作類去發送處理請求即可。這種設計思路在ASP.NET Core中體現的也是淋漓盡致,ASP.NET Core采用的是構建不同終結點去處理和輸出請求。通過這些我們可以得知DecompressionHandler才是今天的主題,接下來我們就來查看DecompressionHandler類的源碼[點擊查看源碼????]就不粘貼全部源碼了,我們先來看最核心的SendAsync方法,這個方法是發送請求的執行方法

internal override async ValueTask<HttpResponseMessage> SendAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken) {//判斷是否是GZIP壓縮請求,如果是則添加請求頭Accept-Encoding頭為gzipif (GZipEnabled && !request.Headers.AcceptEncoding.Contains(s_gzipHeaderValue)){request.Headers.AcceptEncoding.Add(s_gzipHeaderValue);}//判斷是否是Deflate壓縮請求,如果是則添加請求頭Accept-Encoding頭為deflateif (DeflateEnabled && !request.Headers.AcceptEncoding.Contains(s_deflateHeaderValue)){request.Headers.AcceptEncoding.Add(s_deflateHeaderValue);}//判斷是否是Brotli壓縮請求,如果是則添加請求頭Accept-Encoding頭為brotliif (BrotliEnabled && !request.Headers.AcceptEncoding.Contains(s_brotliHeaderValue)){request.Headers.AcceptEncoding.Add(s_brotliHeaderValue);}//發送請求HttpResponseMessage response = await _innerHandler.SendAsync(request, async, cancellationToken).ConfigureAwait(false);Debug.Assert(response.Content != null);//獲取返回的Content-Encoding輸出頭信息ICollection<string> contentEncodings = response.Content.Headers.ContentEncoding;if (contentEncodings.Count > 0){string? last = null;//獲取最后一個值foreach (string encoding in contentEncodings){last = encoding;}//根據響應頭判斷服務端采用的是否為gzip壓縮if (GZipEnabled && last == Gzip){//使用gzip解壓算法解壓返回內容,并從新賦值到response.Contentresponse.Content = new GZipDecompressedContent(response.Content);}//根據響應頭判斷服務端采用的是否為deflate壓縮else if (DeflateEnabled && last == Deflate){//使用deflate解壓算法解壓返回內容,并從新賦值到response.Contentresponse.Content = new DeflateDecompressedContent(response.Content);}//根據響應頭判斷服務端采用的是否為brotli壓縮else if (BrotliEnabled && last == Brotli){//使用brotli解壓算法解壓返回內容,并從新賦值到response.Contentresponse.Content = new BrotliDecompressedContent(response.Content);}}return response; }

通過上面的邏輯我們可以看到GZipEnabled、DeflateEnabled、BrotliEnabled三個bool類型的變量,中三個變量決定了采用哪種請求壓縮方式,主要實現方式是

internal bool GZipEnabled => (_decompressionMethods & DecompressionMethods.GZip) != 0; internal bool DeflateEnabled => (_decompressionMethods & DecompressionMethods.Deflate) != 0; internal bool BrotliEnabled => (_decompressionMethods & DecompressionMethods.Brotli) != 0;

主要就是根據我們配置的DecompressionMethods枚舉值判斷想獲取哪種方式的壓縮結果,解壓的實現邏輯都封裝在GZipDecompressedContent、DeflateDecompressedContent、BrotliDecompressedContent中,我們看一下他們的具體的代碼

private sealed class GZipDecompressedContent : DecompressedContent {public GZipDecompressedContent(HttpContent originalContent): base(originalContent){ }//使用GZipStream類對返回的流進行解壓protected override Stream GetDecompressedStream(Stream originalStream) =>new GZipStream(originalStream, CompressionMode.Decompress);}private sealed class DeflateDecompressedContent : DecompressedContent{public DeflateDecompressedContent(HttpContent originalContent): base(originalContent){ }//使用DeflateStream類對返回的流進行解壓protected override Stream GetDecompressedStream(Stream originalStream) =>new DeflateStream(originalStream, CompressionMode.Decompress);}private sealed class BrotliDecompressedContent : DecompressedContent{public BrotliDecompressedContent(HttpContent originalContent) :base(originalContent){ }//使用BrotliStream類對返回的流進行解壓protected override Stream GetDecompressedStream(Stream originalStream) =>new BrotliStream(originalStream, CompressionMode.Decompress);} }

其主要的工作方式就是使用對應壓縮算法的解壓方法得到原始信息。簡單總結一下,HttpClient關于壓縮相關的處理機制是,首先根據你配置的DecompressionMethods判斷你想使用那種壓縮算法。然后匹配到對應的壓縮算法后添加Accept-Encoding請求頭為你期望的壓縮算法。最后根據響應結果獲取Content-Encoding輸出頭信息,判斷服務端采用的是哪種壓縮算法,并采用對應的解壓方法解壓獲取原始數據。

總結

????通過本次探討HttpClient關于響應壓縮的處理我們可以了解到,HttpClient無論從設計上還是實現方式上都有非常高的靈活性和擴展性,這也是為什么到了.Net Core上官方只推薦使用HttpClient一種Http請求方式。由于使用比較簡單,實現方式比較清晰,這里就不過多拗述。主要是是想告訴大家HttpClient默認可以直接處理響應壓縮,而不是和之前我們使用HttpWebRequest的時候還需要手動編碼的方式去實現。

????歡迎掃碼關注我的公眾號????

總結

以上是生活随笔為你收集整理的.Net Core HttpClient处理响应压缩的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 污污视频在线播放 | 欧美日韩1 | 国产美女视频免费观看下载软件 | 北岛玲av在线 | 久久久久亚洲av片无码 | 瑟瑟在线观看 | 国产97色在线 | 国产 | 欧美精品一区二区在线播放 | www.日日日 | www国产精品内射熟女 | 中文字幕不卡在线观看 | 玖玖999 | www.久久 | 加勒比日韩| 久久国产精品二区 | 成人精品国产免费网站 | 性奶老妇 视频 | 好吊色视频一区二区三区 | 少妇三级 | 麻豆人妻少妇精品无码专区 | 国产成人黄色av | 激情爱爱网站 | 先锋av资源网| 色四虎| 免费黄色在线播放 | 人人妻人人爽一区二区三区 | 黄色特级一级片 | 黄色私人影院 | 久久综合99 | 欧美午夜精品 | 五月天久久婷婷 | 国产日韩精品在线 | 狼人av在线 | 黄色免费av网站 | 四虎影院在线免费播放 | 国产99精品| 青青射 | 国产亚洲精久久久久久无码77777 | 日韩中文字幕在线观看 | 国产真实生活伦对白 | 天天综合入口 | 国产性av| 亚洲第一福利视频 | 樱花草涩涩www在线播放 | 男人天堂2021 | 亚洲综合一区二区三区 | 亚洲一二三精品 | 在线h片| 小视频国产 | 中文字幕亚洲区 | 91中文字日产乱幕4区 | 青草伊人网 | 天天插天天操天天干 | 亚洲av无码一区二区三区人 | 亚洲呦呦 | 九九在线免费视频 | 色97色 | 久久99影院 | avtt男人天堂| 国产福利免费 | 男女日皮视频 | 国产精品午夜福利 | 日韩在线观看视频一区二区三区 | 亚洲www视频 | 欧美性生交大片免费看app麻豆 | 久久久午夜电影 | 国产精品jizz在线观看无码 | 少妇喷白浆| 黄色观看网站 | 欧美亚洲一区二区三区四区 | 福利午夜视频 | 香蕉影院在线观看 | 爱爱爱爱网站 | 在线观看免费高清在线观看 | 欧美一级黄视频 | 91久久综合 | 国产极品美女在线 | 欧美成人h版| 国产精品亚洲一区二区无码 | 拔插拔插海外华人永久免费 | 激情午夜视频 | 国产大片中文字幕 | 丰满少妇一区 | 日本精品视频在线播放 | 99色国产| 性生活网址 | 国产日产亚洲系列最新 | 色碰视频| 一级h片| 91成人看片| 国产91边播边对白在线 | 最新中文字幕av | 欧美激情一区二区三区免费观看 | 精品产国自在拍 | 国产精品亚洲五月天丁香 | 超碰精品在线观看 | 怨女1988国语版在线观看高清 | 久热青草| 97人妻精品视频一区 |