WCF客户端正在流式传输模式下进行缓冲

本文关键字:模式 缓冲 传输 客户端 WCF | 更新日期: 2023-09-27 18:16:30

我的最终目标是能够上传大型视频文件和流到配置为流式传输模式的WCF服务。我遇到的问题是,我的WCF客户端只在流被读取到末尾之后才向服务发出请求。

一个主要的用例是将没有预定义终点的实时流中继到服务,因此在发送任何数据之前完全读取这些流是不实际的。为了测试这个功能,我创建了一个'infinite'流:

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
}

与我发现的例子一致,用于接收流上传的messagcontract:

[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方法。对于非"无限"流,该过程可以工作,但是当客户端似乎缓冲所有流内容时,会有相当大的延迟。

WCF客户端正在流式传输模式下进行缓冲

似乎Fiddler已经引入了自己的缓冲区。当Fiddler关闭时,流请求被正确地传递给WCF。

在一个相关的说明中,似乎在。net 4.0及更低版本中,托管在IIS中的流WCF服务的服务器端缓冲是不可避免的。ASP。. NET层有自己的缓冲机制,它等待消息被完全接收后再将其传递给WCF。