2017-02-15 22 views
2

У меня есть веб-API ASP.NET со следующим действием контроллера для обслуживания, возможно, больших (< 1-200 МБ) 3D-моделей, которые хранятся в формате JSON где-то на диске (за пределами веб-корень):Как сжимать и кэшировать файлы с помощью IIS, когда имя файла определяется контроллером ASP.NET Web API

public HttpResponseMessage GetModel(Guid accessToken, Guid modelId) 
{ 
    Guid projectId = MyBackend.Validate(accessToken); 
    string fileName = MyPaths.GetModelFile(projectId, modelId); 

    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK); 
    response.Content = new StringContent(File.ReadAllText(fileName), 
             Encoding.UTF8, "application/json"); 
    return response; 
} 

в моей Global.asax у меня есть эта строка:

GlobalConfiguration.Configuration.MessageHandlers.Insert(
     0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor())); 

Когда я вызываю API конечной точки, содержание сжат GZIP, как ожидается, , но IIS (8.5) не кэширует сжатые результаты, поэтому он должен повторно компилировать s соответствующий файл для каждого запроса. Я ожидаю, что он не кэшируется, потому что контроллер считывает JSON в память и обслуживает его как StringContent.

Я почти ничего не знаю о IIS и немного об ASP.NET Web API. Как я могу лучше всего обслуживать файлы JSON, чтобы они были сжаты И убедитесь, что IIS кэширует сжатые результаты, чтобы их не нужно было повторно сжимать каждый раз? (И если по какой-то причине это звучит как плохая идея, что я должен делать?)

ответ

1

Я предлагаю создать кэш, на котором у вас есть полный контроль над ним, вместо делегирования сжатия IIS или, в этом случае, Web Обработчики сообщений API. Это лучший способ оптимизировать использование ЦП, жертвуя дисковым пространством.

Создайте каталог на своем сервере и сохраните временные файлы со сжатым контентом. Затем в вашем запросе API проверьте, создан ли сжатый файл для вашей 3D-модели. Если нет, создайте его на лету и сохраните на диске. В следующий раз, когда запрашивается модель, результат будет уже рассчитан, и вам нужно будет только вернуть содержимое сжатого файла.

// Calculate a path for your cache file. 
var compressedCacheFilename = GetCachePath(filename); 
Stream compressedStream; 
if (File.Exists(compressedCacheFilename)) { 
    compressedStream = new FileStream(compressedCacheFilename, FileMode.Open, FileAccess.Read); 
} 
else { 
    /* Use the best compression algorithm for your data 
     and store it to the corresponding path. */ 
    compressedStream = compressor.CompressTo(
     new FileStream(filename, FileMode.Open, FileAccess.Read), 
     compressedCacheFilename 
    ); 
} 

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK); 
response.Content = new StreamContent(compressedStream); 
response.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); 
response.Content.Headers.ContentEncoding.Clear(); 
response.Content.Headers.ContentEncoding.Add("gzip"); // your compression algorithm 

Обратите внимание, что в примере кода, я использую StreamContent вместо StringContent, потому что первый использует меньше памяти. Также важно знать, что это предполагает, что модели не будут меняться. Вероятно, для этого вам понадобится максимальная емкость на диске.

 Смежные вопросы

  • Нет связанных вопросов^_^