Потоковая передача изображений с использованием HttpHandler - PullRequest
4 голосов
/ 02 октября 2009

В течение долгого времени я заметил кое-что раздражающее при работе над проектами веб-приложений, использующими изображения на базе данных на моем локальном компьютере. Под локальным я подразумеваю, что это типичная среда с VS 2008 и SQL Server 2005 на моей рабочей станции. Всякий раз, когда я использую HttpHandler для отображения изображений на локальном компьютере, при каждой загрузке страницы отображаются только некоторые изображения.

Однако, когда я перемещаю приложение в размещенную среду, проблема обычно исчезает. Однако я просто перенес новый проект в размещенную среду и столкнулся с той же проблемой, что и в своей локальной системе - на этот раз сайт и БД находились на одном сервере в среде размещения. Кто-нибудь понял, что здесь происходит?

Вот обработчик:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FeaturedHandler : IHttpHandler
{
    Business biz = new Business();

    public void ProcessRequest(HttpContext context)
    {
        if (context.Request.QueryString["ListingID"] != null)
        {
            int listingID = Convert.ToInt32(context.Request.QueryString["ListingID"]);

            DataSet ds = biz.GetFeaturedImageByID(listingID);
            DataRow row = ds.Tables[0].Rows[0];
            byte[] featureImage = (byte[])row["Photo"];
            context.Response.ContentType = "image/jpeg";
            context.Response.OutputStream.Write(featureImage, 0, featureImage.Length);
        }
        else
            throw new ArgumentException("No ListingID parameter specified");
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
} 

Я пытался использовать БД на отдельном сервере, но столкнулся с той же проблемой. Должен ли я использовать DataReader вместо этого?

UPDATE Я должен был использовать DataReader изначально, так как я читаю двоичные данные.

Ответы [ 3 ]

4 голосов
/ 09 октября 2009

Я наконец получил все изображения для рендеринга, изменив значение свойства IsReusable на true :

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }

Очевидно, это сохраняет обработчик в памяти и может обрабатывать несколько запросов. При значении false он должен был создавать новый экземпляр обработчика для каждого входящего запроса.

2 голосов
/ 31 марта 2011

По этому:

Всякий раз, когда я использую HttpHandler для отображать изображения на моем местном, только часть изображений отображается на каждом загрузка страницы.

Вы имеете в виду, что одно и то же изображение появляется в местах, где должны появляться разные изображения, или что некоторые изображения появляются, а некоторые вообще не отображаются?

В вашем случае разница при переключении isReusable в true заключается в том, что new Business(); будет вызываться один раз для нескольких изображений. Если isReusable равно false, new Business(); будет вызываться один раз для каждого изображения. Это означает, что если у вас есть несколько изображений на странице, new Business(); будет вызываться несколько раз для этой конкретной страницы.

Также я настоятельно рекомендую изменить это:

if (context.Request.QueryString["ListingID"] != null)
{
    int listingID = Convert.ToInt32(context.Request.QueryString["ListingID"]);

с:

string listingIdParam = context.Request.QueryString["ListingID"];
if (listingIdParam != null)
{
    int listingID = Convert.ToInt32(listingIdParam);

Это избавит вас от исключений нулевых ссылок, которые обычно появляются только при большой нагрузке. Кроме того, вышеприведенное предотвратит подачу неправильного изображения в запрос, особенно когда isReusable имеет значение true.

Я не могу точно определить, в чем заключалась проблема, но могу с уверенностью сказать, что установка флага isReusable была просто обходным путем и не решает вашу проблему. Также, когда подобная проблема воспроизводима только в определенной среде, это означает, что это либо проблема с потоками, либо есть некоторая разница в обработке запросов (другой веб-сервер - IIS6, IIS7, сервер разработки).

Может быть, публикация класса Business, и его конструктор может пролить немного света. Также я предлагаю реализовать какую-либо регистрацию ошибок, чтобы перехватывать исключения в обработчике и просматривать их.

0 голосов
/ 22 февраля 2010

Если вы обслуживаете изображения напрямую, не забудьте установить правильные заголовки кэширования, т.е. Если вы этого не сделаете, вы действительно сильно ударитесь по своей базе данных и израсходуете пропускную способность.

Вам потребуется обработать следующие http-заголовки:

  • ETag
  • 1008 * Истекает *
  • Last-Modified
  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-Unmodified-С
  • Unless-Modified-Since

В качестве примера обработчика http, который выполняет эту проверку: http://code.google.com/p/talifun-web/wiki/StaticFileHandler

...