将数据从REST WCF服务流式传输到外部Web服务

时间:2012-08-21 18:53:26

标签: c# .net wcf rest

我正在尝试编写一个WCF Web服务,它本质上归结为一个不受我控制的外部Web服务的代理(特别是一个主要的视频共享站点)。我需要能够将~10-100 MB的数据从客户端发送到我的Web服务,然后将这些数据发送到外部服务。

我可以做到这一点,但为了能够扩展,我希望它尽可能地流式传输,而不是将整个请求主体读入内存,然后将其全部邮寄到外部服务中。

我的配置中bindingConfiguration设置为transferMode="Streamed"

<bindings>
  <webHttpBinding>
    <binding name="WebHttpBindingConfig" maxReceivedMessageSize="104857600"
             transferMode="Streamed"
             maxBufferSize="104857600"
             maxBufferPoolSize="104857600">
    </binding>
  </webHttpBinding>
</bindings>

该服务将Stream作为唯一参数:

public abstract class Upload<NetworkID> : IUpload
{
    protected abstract string DatabaseConnection { get; }

    public Stream UploadVideo(Stream stream)
    {
        LogManager.GetLogger("Logger").Trace("Upload starting:");
        try
        {
            HttpWebRequest request;
            request = (HttpWebRequest)WebRequest.Create("http://faketestservice:8800/upload");
            request.Method = "POST";
            request.ContentType = "application/octet-stream";

            request.ContentLength = WebOperationContext.Current.IncomingRequest.ContentLength;
            stream.CopyTo(request.GetRequestStream(), 64 * 1024 * 1024);
        }
        catch (Exception ex)
        {
            LogManager.GetLogger("Logger").Trace("caught: " + ex.ToString());
        }

        return new MemoryStream(Encoding.UTF8.GetBytes("hello upload"));
    }
}

该服务只需获取传入请求流并将其复制到传出请求流,一次64K。

但是,当我尝试通过Fiddler向服务发送一些数据(在我的示例中约为16MB)时,监视发送到外部服务的内容(在此示例中,在我的家庭计算机上运行假的侦听器),没有发送数据直到收到所有数据。

我已尝试将传出请求的SendChunked属性设置为true,但这不会改变任何内容。

2 个答案:

答案 0 :(得分:0)

您在CopyTo函数中将缓冲区大小设置得太大。通过不传递缓冲区大小将其设置为小的或保持默认值(4096)。你基本上是在告诉它一次传输64MB。这意味着它将读取64MB,发送,读取64MB,发送等等。

此外,您不需要使用'Chunked'。这是您不需要的HTTP的特殊功能。

除此之外,请确保Fiddler仅在完成后才显示响应。它可能在骗你。

答案 1 :(得分:0)

在您的示例中,您仍然只有一个POST来读取传入的流并最多发送64MB。

如果视频共享网站可以获取部分数据,那么您(可能)想要做的是让您的服务循环传入数据,将其(通过单个POST)以小块的形式发送到最终服务?它是哪种服务?