2013-06-03 2 views
3

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

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

public class InfiniteStream : Stream 
{ 
    private Random _random; 

    public InfiniteStream() 
    { 
     _random = new Random(1); 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     _random.NextBytes(buffer); 
     Position += count; 
     return count; 
    } 

    // other unimportant methods 
} 

И в соответствии с примерами, я нашел, а MessageContract для получения поточных загрузок:

[MessageContract] 
public class ClipUpload : IDisposable 
{ 
    [MessageHeader(MustUnderstand = true)] 
    public long MediaId; 

    [MessageBodyMember(Order=1)] 
    public System.IO.Stream MediaStream; 

    // disposable implementaton 
} 

Теперь, насколько Я могу сказать, что моя служба настроена правильно для потоковых передач, и поток может быть прочитан на серверной стороне без проблем. Сервер конфигурация интереса:

<basicHttpsBinding> 
    <binding name="A" transferMode="Streamed" maxReceivedMessageSize="4294967296" maxBufferSize="65536"> 
     <security mode="TransportWithMessageCredential"> 
      <message clientCredentialType="UserName" /> 
     </security> 
    </binding> 
</basicHttpsBinding> 

клиента конфигурация интереса:

<basicHttpsBinding> 
    <binding name="A" transferMode="Streamed" maxBufferSize="65536"> 
     <security mode="TransportWithMessageCredential" /> 
    </binding> 
</basicHttpsBinding> 

Серверная операция очень проста. В моем интерфейсе сервиса ::

[OperationContract(IsOneWay=true)] 
void UploadClip(ClipUpload upload); 

Реализация:

public void UploadClip(ClipUpload upload) 
{ 
    using (var stream = new FileStream(@"C:\Temp\temp.mp4", FileMode.Create, FileAccess.Write)) 
    { 
     upload.MediaStream.CopyTo(stream); 
    } 

Клиент также использует простой вызов:

using(var stream = new InfiniteStream()) 
{ 
    _service.UploadClip(1, stream); 
} 

Опять же, проблема в том, что клиент не передает какой-либо данных потока до тех пор, пока поток не будет полностью прочитан, что, конечно же, никогда не будет иметь значение для InfiniteStream. Таким образом, поток никогда не достигает метода UploadClip сервера. Для не-бесконечных потоков процесс работает, но существует значительная задержка, в то время как клиент, по-видимому, буферизует все содержимое потока.

ответ

0

Кажется, что Fiddler, возможно, представлял свой собственный буфер. Когда Fiddler закрылся, потоковые запросы были надлежащим образом переданы WCF.

Относительно примечания, по-видимому, на .NET 4.0 и ниже серверная буферизация для потоковых служб WCF, размещенных в IIS, неизбежна. Уровень ASP.NET имеет свой собственный механизм буферизации, который ожидает, пока сообщение будет полностью получено, прежде чем передать его в WCF. Подробнее here.

Смежные вопросы