Потоковое webHttpBinding не передается - PullRequest
2 голосов
/ 20 июня 2011

Мне нужно создать службу WCF REST для загрузки больших файлов. Я сделал конечную точку в виде потокового webHttpBinding, но он не стал потоковым.

Пример обслуживания:

[ServiceContract]
public interface IFiles
{
    [OperationContract]
    void UploadFile(Stream stream);
}

public class Files : IFiles
{
    public void UploadFile(Stream stream)
    {
        const int BUFFER_SIZE = 64 * 1024;
        byte[] buffer = new byte[BUFFER_SIZE];

        using (TextWriter logWriter = new StreamWriter("d:\\UploadedFile.log"))
        using (Stream fileStream = new FileStream("d:\\UploadedFile", System.IO.FileMode.Create, System.IO.FileAccess.Write))
        {
            int readBytes = 0;
            while (0 < (readBytes = stream.Read(buffer, 0, BUFFER_SIZE)))
            {
                fileStream.Write(buffer, 0, readBytes);
                logWriter.WriteLine("{0}: {1} bytes saved", DateTime.Now, readBytes);
            }
        }
    }
}

Web.config:

<?xml version="1.0"?>
<configuration>

  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="WebHttpBinding" maxBufferSize="65536" maxBufferPoolSize="524288"
          maxReceivedMessageSize="1073741824" transferMode="Streamed" />
      </webHttpBinding>
    </bindings>
    <services>
      <service name="WcfService2.Files">
        <endpoint behaviorConfiguration="WebHttpBehavior" binding="webHttpBinding"
          bindingConfiguration="WebHttpBinding" name="Files" contract="WcfService2.IFiles" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="WebHttpBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="MyServiceBehavior">
          <serviceMetadata />
          <serviceDebug />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <httpRuntime maxRequestLength="500000" />
  </system.web>

</configuration>

Код клиента:

using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlString);
    request.Method = "POST";
    request.ContentType = "application/octet-stream";
    //request.ContentLength = fileStream.Length;
    //request.AllowWriteStreamBuffering = false;
    request.SendChunked = true;
    Stream requestStream = request.GetRequestStream();

    const int BUFFER_SIZE = 32 * 1024;
    byte[] buffer = new byte[BUFFER_SIZE];
    int readBytes = 0;
    while (0 < (readBytes = fileStream.Read(buffer, 0, BUFFER_SIZE)))
    {
        requestStream.Write(buffer, 0, readBytes);
        Console.WriteLine("{0}: {1} bytes sent", DateTime.Now, readBytes);
        System.Threading.Thread.Sleep(200);
    }
    requestStream.Close();

    WebResponse response = request.GetResponse();
}

Код метода UploadFile вызывается только после вызова requestStream.Close (). Почему?

1 Ответ

0 голосов
/ 01 ноября 2011

Если вы хотите отправить его по частям, вы должны добавить очистку в цикле while после requestStream.Write ()

requestStream.Flush();

Это потому, что потоки могут кэшировать выходные данные до тех пор, пока они не станут необходимыми для отправки.Смотри http://msdn.microsoft.com/en-us/library/system.io.stream.flush.aspx

...