ポイントは3つあります。
- GZipStreamを使って入力データを圧縮する
- HttpClientHandlerのAutomaticDecompressionプロパティを設定する
- HTTPリクエストヘッダのContent-Encodingをgzipに設定する
GZipStreamを使って入力データを圧縮する
圧縮用にMemoryStreamをインスタンス化し、GZipStreamでラップします。
usingをネストしているのはGZipStreamをCloseするタイミングで圧縮が実行されるからです。
byte[] data = null;
using (var memory = new MemoryStream()) {
using (var gzip = new GZipStream(memory, CompressionMode.Compress)) {
int input = 0;
byte[] buffer = new byte[1];
while (-1 != (input = Console.Read())) {
buffer[0] = Convert.ToByte(input);
gzip.Write(buffer, 0, buffer.Length);
}
}
data = memory.ToArray();
}
HttpClientHandlerのAutomaticDecompressionプロパティを設定する
リクエストボディの圧縮は実装する必要がありますが、レスポンスの解凍は.NET Frameworkが対応しています。
var clientHandler = new HttpClientHandler(); clientHandler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
HTTPリクエストヘッダのContent-Encodingをgzipに設定する
コンテンツがgzip圧縮されていることを示すため、Content-Encodingをgzipに設定します。
using(var client = new HttpClient(clientHandler))
using(var content = new ByteArrayContent(data))
{
content.Headers.ContentEncoding.Add("gzip");
using(var message = client.PostAsync(url, content).Result)
{
Console.WriteLine(message.Content.ReadAsStringAsync().Result);
}
}
一般的に、HTTPリクエストが圧縮を必要とするほど大きくなることはありません。
全ての画面データを毎回やりとりするような設計であれば、効果があるかもしれません。
プログラム全体を以下に記載します。
// csc /reference:System.Net.Http.dll GZipHttpClient.cs
namespace gziphttpclient {
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Http;
public class GZipHttpClient {
public static void Main(string[] args) {
const string url = "http://localhost:8080/echo";
byte[] data = null;
using (var memory = new MemoryStream()) {
using (var gzip = new GZipStream(memory, CompressionMode.Compress)) {
int input = 0;
byte[] buffer = new byte[1];
while (-1 != (input = Console.Read())) {
buffer[0] = Convert.ToByte(input);
gzip.Write(buffer, 0, buffer.Length);
}
}
data = memory.ToArray();
}
var clientHandler = new HttpClientHandler();
clientHandler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
using(var client = new HttpClient(clientHandler))
using(var content = new ByteArrayContent(data))
{
content.Headers.ContentEncoding.Add("gzip");
using(var message = client.PostAsync(url, content).Result)
{
Console.WriteLine(message.Content.ReadAsStringAsync().Result);
}
}
}
}
}
参考
GZipStream Class
HttpClientHandler Class
関連
FilterでHTTP通信のGZIP圧縮に対応する
0 件のコメント:
コメントを投稿