1

我正在尝试编写一个 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>

该服务将 aStream作为其唯一参数:

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,但这并没有改变任何东西。

4

2 回答 2

0

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

此外,您不需要为此使用“分块”。这是您不需要的 HTTP 的一个特殊功能。

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

于 2012-08-21T21:33:30.813 回答
0

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

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

于 2012-08-21T21:38:13.933 回答