Я провел большую часть своего дня, пытаясь понять, почему это не работает.У меня есть служба 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;
}
}
Файл конфигурации службы:
<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>
(некоторый код для краткости обрезан)
Я прочитал все, что могу найти при создании потоковых сервисов WCF, и мой код не отличается от их.Я могу заменить потоковую передачу буферизацией и отправить объект таким образом, но когда я пытаюсь выполнить потоковую передачу, клиент всегда видит поток как «пустой».testFile.exe
создается, но его размер составляет 0 КБ.
Чего мне не хватает?
ОБНОВЛЕНИЕ
Хм.Ну, я не могу отладить его, потому что при попытке сказать мне, что тестовый клиент WCF не поддерживает потоки.Но я знаю, что что-то делает это в потоке, потому что, если я не помещу цикл while, а просто имею один fs.Write (...), он закроет 8KB, как только поток закроется.Итак, что-то пересекается.
Я посмотрел ваш пост и добавил:
[MessageContract]
public class FileDownloadMessage
{
[MessageBodyMember(Order = 1)]
public MemoryStream FileByteStream;
}
в мой IStreamService.И downloadStreamFile()
теперь возвращает FileDownloadMessage
объект.
Но после обновления ссылки на службу на моем клиенте он думает, что downloadStreamFile()
возвращает TestApp.StreamServiceRef.MemoryStream
объект.
Он также создал downloadStreamFileRequest()
класс, который я не сделал и понятия не имею, откуда он.