Небуферизованный вывод из IHTTPHandler - PullRequest
3 голосов
/ 21 июля 2011

Я хочу передавать данные из класса IHttpHandler. Я загружаю большое количество строк из БД, сериализую и сжимаю их, а затем отправляю по проводам. С другой стороны, я хочу, чтобы мой клиент мог распаковать и десериализовать данные до того, как сервер завершит сериализацию всех объектов.

Я использую context.Response.OutputSteam.Write для записи своих данных, но кажется, что выходные данные помещаются в буфер перед отправкой клиенту. Есть ли способ избежать этой буферизации?

Ответы [ 2 ]

2 голосов
/ 22 июля 2011

Метод Response.Flush должен отправить его по проводам;Однако есть некоторые исключения.Если IIS использует динамическое сжатие, то есть настроено для сжатия динамического содержимого, IIS не будет очищать поток.Затем идет целое «чанкованное» кодирование передачи.Если вы не указали Content-Length, то получающий конец не знает, насколько большим будет тело ответа.Это достигается с помощью кодирования передачи по частям.Некоторые HTTP-серверы требуют, чтобы клиент использовал заголовок запроса Accept-Encoding, содержащий ключевое слово chunked.Другие просто по умолчанию chunked, когда вы начинаете писать байты до того, как указана полная длина;однако, они этого не делают, если вы указали свой собственный Transfer-Encoding заголовок ответа.

Если IIS 7 и сжатие отключены, Response.Flush всегда должно сработать, верно?На самом деле, нет.IIS 7 может иметь много модулей, которые перехватывают и взаимодействуют с запросом и ответом.Я не знаю, установлены ли они по умолчанию или включены, но вы все равно должны знать, что они могут повлиять на ваш желаемый результат.

... Я загружаю большое количество строкиз БД, сериализации и сжатия их, а затем отправки их по проводам ...

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

Возможно, вы захотите разбить записи на меньшие, удобочитаемые фрагменты по 10, 50 или 100 строк.Сожмите это и отправьте, затем работайте со следующим набором строк.Конечно, теперь вам нужно что-то написать клиенту, чтобы он знал, насколько велик каждый сжатый набор строк и когда они достигли конца.см. http://en.wikipedia.org/wiki/Chunked_transfer_encoding для примера того, как работает фрагментарный перевод.

0 голосов
/ 22 июля 2011

Вы можете использовать context.Response.Flush() или context.Response.OutputSteam.Flush() для принудительной немедленной записи буферизованного контента.

...