我正在尝试编写一个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,但这不会改变任何内容。
答案 0 :(得分:0)
您在CopyTo函数中将缓冲区大小设置得太大。通过不传递缓冲区大小将其设置为小的或保持默认值(4096)。你基本上是在告诉它一次传输64MB。这意味着它将读取64MB,发送,读取64MB,发送等等。
此外,您不需要使用'Chunked'。这是您不需要的HTTP的特殊功能。
除此之外,请确保Fiddler仅在完成后才显示响应。它可能在骗你。
答案 1 :(得分:0)
在您的示例中,您仍然只有一个POST来读取传入的流并最多发送64MB。
如果视频共享网站可以获取部分数据,那么您(可能)想要做的是让您的服务循环传入数据,将其(通过单个POST)以小块的形式发送到最终服务?它是哪种服务?