Streaming z WCF i MTOM
Używam powiązań WCF z trybem przesyłania strumieniowego, zarówno do przesyłania, jak i pobierania treści binarnych do / z usługi. Udało mi się to uruchomić. Będę zawierał konfigurację, umowy itp. W celach informacyjnych.
Przeprowadziłem kilka testów porównujących różne wiązania i kodowania. Przesyłanie wyników wydaje się w porządku. NetTcp jest najszybszy, następnie BasicHttp-MTOM, a następnie BasicHttp-Text. To, co mnie zaskakuje, to to, że podczas pobierania dużych plików MTOM jest bardzo powolny, w przeciwieństwie do kodowania tekstu z kodowaniem BasicHttp i Binary za pomocą NetTcp.
Czy czegoś mi brakuje? Dlaczego BasicHttp-MTOM działa wolniej niż inne wiązania podczas przesyłania? Oprócz tego zaimplementowałem podwójne buforowanie do pobierania. Działa to również dobrze ze wszystkimi powiązaniami z wyjątkiem BasicHttp z kodowaniem MTOM. Dlaczego podwójne buforowanie nie pomaga w przypadku korzystania z MTOM?
Dziękujemy za przeczytanie, porady i pomysły na ten temat.
Wyniki testów:
Przesyłanie 150 MB danych binarnych do serwisu. Klient tworzy strumień plików z pliku 150 MB i przekazuje go do serwera. Serwer odczytuje strumień do strumienia pamięci. Nie ma jeszcze podwójnego bufora. Wyniki wydają się szybkie, ponieważ nie zapisuje się danych w systemie plików. I wiązania działają zgodnie z oczekiwaniami.
Pobieranie 100 MB danych binarnych z usługi. Usługa tworzy strumień pamięci i przekazuje go do klienta. Klient zapisuje do systemu plików. Oto wyniki z pojedynczym i podwójnym buforem. Jak widać, MTOM wydaje się bardzo powolny i nie reaguje również na podwójne buforowanie.
Konfiguracja serwera (dla uproszczenia pominięto niektóre części):
<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>
Konfiguracja klienta (dla uproszczenia pominięto niektóre części):
<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>
Umowa o świadczenie usług:
[ServiceContract]
public interface IFileService
{
[OperationContract]
void UploadFile(DocumentData document);
[OperationContract]
DocumentData DownloadFile();
}
Kontrakt wiadomości:
[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; }
}
Edytuj: Okazało się, że jest to problem z moją konfiguracją środowiska programistycznego w pracy. Kiedy przeprowadzałem te same testy w domu, wyniki były zgodne z oczekiwaniami.