WCF Stream.Read 在客户端总是返回 0

Mar*_*cus 1 c# streaming wcf wcf-streaming

我花了一天的大部分时间试图弄清楚为什么这不起作用。我有一个 WCF 服务,它将对象流式传输到客户端。然后客户端应该将文件写入其磁盘。但是当我调用stream.Read(buffer, 0, bufferLength)它时总是返回 0。这是我的代码:

namespace StreamServiceNS
{
    [ServiceContract]
    public interface IStreamService
    {
        [OperationContract]
        Stream downloadStreamFile();
    }
}
class StreamService : IStreamService
{
    public Stream downloadStreamFile()
    {
        ISSSteamFile sFile = getStreamFile();
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream stream = new MemoryStream();
        bf.Serialize(stream, sFile);
        return stream;
    }
}
Run Code Online (Sandbox Code Playgroud)

服务配置文件:

<system.serviceModel>
<services>
  <service name="StreamServiceNS.StreamService">
    <endpoint address="stream" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IStreamService"
              name="BasicHttpEndpoint_IStreamService" contract="SWUpdaterService.ISWUService" />
  </service>
</services>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_IStreamService" transferMode="StreamedResponse" 
             maxReceivedMessageSize="209715200"></binding>
  </basicHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceThrottling maxConcurrentCalls ="100" maxConcurrentSessions="400"/>
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

客户:

TestApp.StreamServiceRef.StreamServiceClient client = new StreamServiceRef.StreamServiceClient();
        try
        {
            Stream stream = client.downloadStreamFile();
            int bufferLength = 8 * 1024;
            byte[] buffer = new byte[bufferLength];

            FileStream fs = new FileStream(@"C:\test\testFile.exe", FileMode.Create, FileAccess.Write);
            int bytesRead;
            while ((bytesRead = stream.Read(buffer, 0, bufferLength)) > 0)
            {
                fs.Write(buffer, 0, bytesRead);
            }
            stream.Close();
            fs.Close();
        }
        catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
Run Code Online (Sandbox Code Playgroud)

客户端 app.config:

    <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpEndpoint_IStreamService" maxReceivedMessageSize="209715200" transferMode="StreamedResponse">
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://[server]/StreamServices/streamservice.svc/stream"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpoint_IStreamService"
            contract="StreamServiceRef.IStreamService" name="BasicHttpEndpoint_IStreamService" />
    </client>
    </system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

(为简洁起见,剪掉了一些代码)

我已经阅读了关于制作 WCF 流服务的所有内容,我的代码看起来与他们的没有什么不同。我可以用缓冲替换流并以这种方式发送一个对象,但是当我尝试流时,客户端总是将流视为“空”。已testFile.exe创建,但其大小为 0KB。

我错过了什么?


更新
人力资源。好吧,我无法调试它,因为当我尝试时它告诉我 WCF 测试客户端不支持流。但是,我知道有些东西正在流中,因为如果我不放置 while 循环,而只有一个 fs.Write(...),一旦流关闭,它将写入 8KB。所以有些事情正在发生。

我看了你的帖子并补充说:

[MessageContract]
public class FileDownloadMessage
{
    [MessageBodyMember(Order = 1)]
    public MemoryStream FileByteStream;
}
Run Code Online (Sandbox Code Playgroud)

到我的 IStreamService。而downloadStreamFile()现在返回一个FileDownloadMessage对象。

但是在我的客户端更新服务引用后,它认为downloadStreamFile()返回一个TestApp.StreamServiceRef.MemoryStream对象。
它还创建了一个downloadStreamFileRequest()类,我没有创建,也不知道它来自哪里。

小智 6

我也遇到了这个问题,对我有用的是将流的位置设置为 0,然后再将其发送回客户端。