WCF: возможно ли использовать потоковый режим в дуплексном канале? - PullRequest
4 голосов
/ 07 января 2009

В WCF контракты можно переключать в потоковый режим для передачи больших сообщений.

После прочтения и тестирования мне кажется, что потоковый режим нельзя использовать с дуплексными каналами (каналами с OneWay-вызовами и интерфейсом обратного вызова).

Это так? Разве дуплекс и потоковая передача не могут использоваться друг с другом? Или есть способ?

(я пытаюсь загрузить большой файл в службу и использовать функцию обратного вызова, чтобы сообщить об этом)

Ответы [ 2 ]

5 голосов
/ 23 ноября 2013

для загрузки файла с клиента на сервер вы можете использовать следующий код: service

 [ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IFreeBoxServiceCallBack))]
    public interface IFreeBoxService
    {
        [OperationContract(IsOneWay = true)]
        void sendFile(byte[] bytes, int offset, int count);

        [OperationContract(IsOneWay = true)]
        void sendFileName(string fileName);
    }

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
    public class FreeBoxService:IFreeBoxService
    {
        string path = "D:\\repository\\";
        string fileName = "";
        IFreeBoxServiceCallBack callBack = null;

        public FreeBoxService()
        {
            callBack = OperationContext.Current.GetCallbackChannel<IFreeBoxServiceCallBack>();
        }

        public void sendFileName(string fileName)
        {
            this.fileName = fileName;
        }

        public void sendFile(byte[] bytes, int offset, int count)
        {
            using (FileStream fileStream = new FileStream(path + fileName, FileMode.Append, FileAccess.Write))
            {
                fileStream.Write(bytes, offset, count);
                fileStream.Close();
                fileStream.Dispose();
            }
        }}

клиент:

private void sendFileToServer()
        {
            FileStream fs = new FileStream(fullName,FileMode.Open,FileAccess.Read);
            int bytesRead = 0;
            bytes = new byte[15000];

            proxy.sendFileName("someFile.xml");

            while ((bytesRead = fs.Read(bytes, 0, 15000))>0)
            {
                proxy.sendFile(bytes, 0, bytesRead);
            }
            fs.Close();
            fs.Dispose();
        }

.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="FreeBoxServiceLib.FreeBoxService" behaviorConfiguration="MyServiceBehevior">
        <endpoint address="" contract="FreeBoxServiceLib.IFreeBoxService"
                  binding="netTcpBinding">
        </endpoint>
        <endpoint address="MEX" binding="mexTcpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8080/FreeBoxService/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceBehevior">
          <serviceMetadata />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

всегда лучше передать массив байтов. Я думаю, не нужно описывать функции обратного вызова?

2 голосов
/ 17 января 2009

Из любопытства я собирался начать тестирование вашего вопроса, но затем Google показал мне два примера, которые могли бы ответить на ваш вопрос лучше.

В этом примере CodeProject показана передача потоковых файлов с индикатором выполнения без использования дуплексных каналов.

Этот образец показывает больше того же самого, но с некоторым другим расположением потока.

Кроме того, действительно хорошим ресурсом для всего, что связано с WCF, является iDesgin.net . Главный парень там - Юваль Лоуи, который написал одни из лучших книг о WCF. У них есть десятки отличных примеров WCF, которые вы можете скачать (хотя они досадно спрашивают у вас ваш адрес электронной почты для каждого из них). Что еще более важно, они также написали класс ServiceProcessEx, который значительно расширяет возможности ServiceProcess, особенно в отношении дуплексных каналов. (Я не уверен, что он имеет дело с потоковой передачей, хотя ... это еще не то, что я сделал).

Надеюсь, что это вам пригодится.

...