나는 왜 이것이 작동하지 않는지 알아 내려고 노력하면서 대부분의 시간을 보냈습니다. 개체를 클라이언트에 스트리밍하는 WCF 서비스가 있습니다. 클라이언트는 파일을 디스크에 기록합니다.WCF Stream.Read는 항상 클라이언트에서 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;
}
}
서비스 설정 파일 :
<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>
클라이언트 :
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); }
클라이언트의 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>
내가
stream.Read(buffer, 0, bufferLength)
전화는 항상 여기에 0을 반환하지만 내 코드입니다
(간결하게하기 위해 일부 코드 잘림)
나는 WCF 스트리밍 서비스를 만들 때 찾을 수있는 모든 것을 읽었으며 내 코드는 그 코드와 다르지 않습니다. 스트리밍을 버퍼링으로 대체하고 객체를 전송할 수 있지만 스트리밍하려고하면 클라이언트는 항상 스트림을 "비어있는"것으로 간주합니다. testFile.exe
이 생성되지만 크기는 0KB입니다.
무엇이 누락 되었습니까?
UPDATE
흠 .... WCF 테스트 클라이언트가 스트림을 지원하지 않는다고 알려주기 때문에 디버깅 할 수 없습니다. 그러나 while 루프를 넣지 않고 fs.Write (...)가 하나만 있으면 스트림이 닫히면 8KB를 쓸 것이므로 스트림에서 스트림을 가로 지르는 무언가가 있다는 것을 알고 있습니다. 그래서 무언가가 가로 질러 가고 있습니다.
[MessageContract]
public class FileDownloadMessage
{
[MessageBodyMember(Order = 1)]
public MemoryStream FileByteStream;
}
을 내 IStreamService에. downloadStreamFile()
은 이제 FileDownloadMessage
개체를 반환합니다.
그러나 내 클라이언트에서 서비스 참조를 업데이트 한 후 downloadStreamFile()
은 TestApp.StreamServiceRef.MemoryStream
개체를 반환한다고 생각합니다.
downloadStreamFileRequest()
클래스도 만들었지 만, 그 클래스는 어디서 왔는지 모릅니다.
위의 업데이트를 확인하십시오. – Marcus
나는 서비스 레퍼런스를 사용하지 않을 것이다. "cmd"프롬프트에서 "svcutil.exe [mex url]"을 실행하면 서비스 참조에서 얻은 것보다 더 정확한 config 파일과 .cs 파일을 얻을 수 있습니다. 내 프로젝트에 서비스 참조가 없기 때문에 잘 작동합니다. 생성 된 .cs 파일을 프로젝트에 추가하고 이에 대한 'using'문을 추가하십시오. 수정 : 또한 클라이언트의 앱 또는 웹 설정 파일에 환경 설정을 추가 할 수 있습니다. 생성 된 2 개의 파일은 svcutil 명령을 실행하는 디렉토리에 만들어집니다. – norepro
감사합니다. svcutil을 사용하여 "참조"를 만들고 코드에서 모든 설정 내용을 수행했습니다. 나는 또한 스트림을 memorystream이 아닌 파일 스트림으로 보내는 것을 끝내었고 어떤 이유로 도움이되는 것처럼 보였다. – Marcus