Потоковое с WCF и MTOM
Я использую привязки WCF с потоковым режимом передачи как для загрузки, так и для загрузки двоичного содержимого в / из службы. Мне удалось заставить его работать. Я включу конфигурацию, контракты и т. Д. Для справки.
Я провел несколько тестов для сравнения различных привязок и кодировок. Загрузка результатов выглядит нормально. NETTcp - самый быстрый, затем BasicHttp-MTOM, а затем BasicHttp-Text. Что меня удивляет, так это то, что при загрузке больших файлов MTOM работает очень медленно, в отличие от кодирования текста с BasicHttp и двоичного кодирования с NetTcp.
Я что-то пропустил? Почему BasicHttp-MTOM работает намного медленнее, чем другие привязки при загрузке? Кроме того, я реализовал двойную буферизацию для загрузок. Это также хорошо работает со всеми привязками, кроме BasicHttp с кодировкой MTOM. Почему двойная буферизация не помогает при использовании MTOM?
Спасибо за чтение, ваши советы и идеи по этому поводу.
Результаты теста:
Загрузка 150 МБ двоичных данных в сервис. Клиент создает файловый поток из файла размером 150 МБ и передает его на сервер. Сервер читает поток в поток памяти. Двойного буфера пока нет. Результаты кажутся быстрыми, поскольку нет записи данных в файловую систему. И привязки работают как ожидалось.
Загрузка 100 МБ двоичных данных из сервиса. Сервис создает поток памяти и передает клиенту. Клиент пишет в файловую систему. Вот результаты с одинарным и двойным буфером. Как вы можете видеть, MTOM кажется очень медленным и не реагирует на двойную буферизацию.
Конфигурация сервера (опущены некоторые части для простоты):
<configuration>
<system.web>
<httpRuntime maxRequestLength="2147483647"/>
</system.web>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="StreamedNetTcpBinding"
transferMode="Streamed"
maxReceivedMessageSize="1099511627776">
</binding>
</netTcpBinding>
<basicHttpBinding>
<binding name="StreamedBasicHttpBindingWithMtom"
messageEncoding="Mtom" transferMode="Streamed"
maxReceivedMessageSize="1099511627776">
</binding>
<binding name="StreamedBasicHttpBinding"
transferMode="Streamed"
maxReceivedMessageSize="1099511627776">
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
Конфигурация клиента (опущены некоторые части для простоты):
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="StreamedBasicHttpBindingWithMtom"
maxReceivedMessageSize="1099511627776"
messageEncoding="Mtom" transferMode="Streamed">
</binding>
<binding name="StreamedBasicHttpBinding"
maxReceivedMessageSize="1099511627776"
transferMode="Streamed">
</binding>
</basicHttpBinding>
<netTcpBinding>
<binding name="StreamedNetTcpBinding" transferMode="Streamed"
maxReceivedMessageSize="1099511627776">
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
Контракт на обслуживание:
[ServiceContract]
public interface IFileService
{
[OperationContract]
void UploadFile(DocumentData document);
[OperationContract]
DocumentData DownloadFile();
}
Сообщение Контракт:
[MessageContract]
public class DocumentData
{
[MessageHeader(MustUnderstand = true)]
public string DocumentName { get; set; }
[MessageHeader(MustUnderstand = true)]
public int FileLength { get; set; }
[MessageBodyMember(Order = 1)]
public Stream Data { get; set; }
}
Изменить: Это оказалось проблемой с моей настройкой среды разработки на работе. Когда я проводил те же тесты дома, результаты были такими, как ожидалось.
1 ответ
Я добавлю ссылки, которые я использовал для реализации потоковой передачи, и приму это как ответ.
Индикация прогресса при загрузке / загрузке файлов с использованием WCF Димитрис Пападимитриу
Реализация двойной буферизации при чтении / записи из / в поток. (См. Ответ Томаса Левеска)
Еще одна реализация для двойной буферизации, которая делает то же самое. (См. Ответ Николая Кэри)
Возврат потока из службы WCF с использованием SqlFileStream