【问题标题】:WCF Client is Buffering with Streamed Transfer ModeWCF 客户端正在使用流传输模式进行缓冲
【发布时间】:2013-06-03 13:46:20
【问题描述】:

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

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

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 方法。对于非“无限”流,该过程有效,但在客户端似乎正在缓冲所有流内容时存在相当大的延迟。

【问题讨论】:

    标签: c# wcf streaming


    【解决方案1】:

    似乎 Fiddler 可能已经引入了自己的缓冲区。关闭 Fiddler 后,流式请求已正确移交给 WCF。

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

    【讨论】:

      猜你喜欢
      • 2011-05-01
      • 2013-08-06
      • 1970-01-01
      • 2012-11-11
      • 2018-10-21
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      • 2017-07-13
      相关资源
      最近更新 更多