Потоковая передача неопределенного количества объектов через WCF

#c# #wcf #streaming

#c# #wcf #потоковая передача

Вопрос:

У меня есть служба WCF, которой необходимо считывать большое (от 10 до 20 миллионов) количество объектов из базы данных.

Что я хотел бы сделать, так это заставить клиента открыть поток и заставить сервер передавать данные из базы данных по мере чтения.

Таким образом, клиент мог бы просто сидеть в цикле десериализации сообщений, пока не получит сообщение EOF от сервера, в стиле потокового API Twitter, но с конечным набором. Проблема, с которой я сталкиваюсь, заключается в том, как вернуть поток, а затем продолжить запись в него. Возможно ли это с помощью WCF?

Ответ №1:

Как насчет того, чтобы вместо настройки службы потоковой передачи / блокировки использовать что-то вроде WS Dual Http. С его помощью у вас есть асинхронный двунаправленный канал обратного вызова, который позволяет вам запрашивать / отвечать на информацию взад и вперед между сервером и клиентом. Проблемы, с которыми вы можете столкнуться, если хотите передать весь набор в потоковом режиме, обычным образом заключаются в том, что некоторые ресурсы могут блокировать другие запросы (или тайм-аут), пока другие пользователи пытаются получить доступ к сервису.

Комментарии:

1. WS Dual Http вообще не разрешает потоковую передачу. Но в целом вы правы. Вероятно, единственный способ имитировать такую связь в WCF — это открыть сеть с двунаправленной потоковой передачей. TCP-соединение (не уверен, возможна ли такая комбинация). Вместо возврата одного потока используйте обратный вызов клиента для отправки набора данных.

2. Я не говорил, что это разрешает потоковую передачу. Я пытаюсь сказать, что это, вероятно, лучший вариант, чем потоковая передача. Вы можете выполнять потоковую передачу в WCF, но это заблокирует ввод-вывод для других входящих запросов. Это не лучший выбор, когда дело доходит до масштабирования. Кроме того, большинство встроенных сериализаторов захотят загрузить все сообщение до того, как они начнут десериализовывать содержимое.

3. Было бы мне лучше просто использовать HttpHandler и записывать в поток таким образом? Мне нужно перейти по HTTP, поскольку это внешний веб-сервис. Взглянул на ваше решение, Мэтт, и оно выглядит неплохо, но я забыл упомянуть, что у нас могут быть люди, использующие это извне WCF, поэтому я предполагаю, что мне придется пойти по маршруту HttpHandler? Я не обязательно привязан к WCF, просто интересно, возможно ли это, поэтому, если есть другие варианты получше, я, безусловно, открыт для них. Кстати, спасибо, что нашли время ответить на мой вопрос.

4. Можете ли вы подробнее описать, как WCF блокирует ввод-вывод при использовании потоковой передачи? У вас есть какая-нибудь ссылка, где я мог бы подробнее прочитать об этом поведении?

Ответ №2:

Проблема в том, что WCF не предоставляет поток ответов на операцию. Поток, возвращаемый из операции, является просто «содержимым» некоторого сообщения. Я попытался обмануть WCF с помощью некоторых сценариев обработки потоков, где я возвращал MemoryStream и пытался заполнить его из другого потока, но, как и ожидалось, это не сработало.

Упомянутый HttpHandler — единственный возможный путь.

Ответ №3:

Возможно, вам захочется взглянуть на привязку PollingDuplexHttpBinding (идентификатор уведомления сделал, возможно, мог :-)).

Некоторым не очень нравится эта привязка, но у меня не было особых проблем с этим после первоначального препятствия с правильной настройкой.

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

HTH.