Как передать большой объем данных с помощью WCF? - PullRequest
4 голосов
/ 03 мая 2010

В настоящее время мы пытаемся переместить большие объемы данных на клиент Silverlight 3, используя WCF с PollingDuplex. Я читал о MultiplerMessagesPerPoll в Silverlight 4, и он выглядит немного быстрее. Есть ли примеры, на которые я могу ссылаться (используя MultipleMessagesPerPoll)? Или, может быть, есть хорошие рекомендации по использованию Net.TCP? Может быть, мне следует использовать совершенно другой подход? Любые идеи или предложения будут с благодарностью.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 05 мая 2010

Потоковые сериализованные ответные блоки работают хорошо:

Ваша конфигурация привязки WCF будет выглядеть следующим образом:

<binding name="myCustomBinding">
   <binaryMessageEncoding />
   <httpTransport transferMode="StreamedResponse" 
                  maxBufferSize="2147483647" 
                  maxBufferPoolSize="2147483647" 
                  maxReceivedMessageSize="2147483647" />
</binding>

Ваш метод обслуживания будет выглядеть примерно так:

[OperationContract]
public Stream GetDataStream(string objectId)
{
   Stream stream = new MemoryStream();

   MyObject obj = Manager.GetObject(objectId);

   DataContractSerializer serilizer = new DataContractSerializer(typeof(MyObject));

   serilizer.WriteObject(stream, obj);

   stream.Position = 0;

   return stream;
}

И ваш завершенный метод на стороне клиента будет делать что-то вроде:

static void client_GetDataStreamCompleted(object sender, GetDataStreamCompletedEventArgs e)
{
   if (e.Error == null)
   {
      DataContractSerializer serializer = new DataContractSerializer(typeof(MyObject));

      MyObject obj = serializer.ReadObject(new MemoryStream(e.Result)) as MyObject;
   }
}
1 голос
/ 07 мая 2010

Я реализовал предложенное решение выше. После реализации я нашел эту ссылку:

http://msdn.microsoft.com/en-us/library/ms752244.aspx

Затем я реализовал двоичный модуль записи, как показано ниже.

Метод обслуживания:

[OperationContract]
    public Stream GetAllLocationsDataStream(string customerId)
    {
        Stream stream = new MemoryStream();
        try
        {
            Customer customer = ServiceEquipmentManager.GetCustomerAllLocations(customerId);
            DataContractSerializer serializer = new DataContractSerializer(typeof(Customer));
            XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(stream);
            serializer.WriteObject(binaryDictionaryWriter, customer);
            binaryDictionaryWriter.Flush();
        }
        catch (Exception ex)
        {
            string timestamp;
            ExceptionHelper.HandleExceptionWrapper(ex, "Log Only", out timestamp);
        }

        stream.Position = 0;
        return stream;
    }

Завершенное событие на стороне клиента:

XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateBinaryReader(new MemoryStream(e.Argument as byte[]), XmlDictionaryReaderQuotas.Max);

        Customer customer = serializer.ReadObject(binaryDictionaryReader) as Customer;

Я проверил разницу моего объекта, как показано в ссылке выше, мои результаты показаны ниже:


Текст = 68 866 216 байт


Двоичный = 49 207 475 байт (на 28,5% меньше, чем текст)

0 голосов
/ 11 мая 2010

Я основываюсь на вашем ответе и акценте на размере данных, которые вы передаете. Если вы сохраняете блоки данных, переданные под 4 ГБ, вы можете использовать класс GZipStream в пространстве имен System.IO.Compression. По моему опыту, используя его с простым текстом, он сократил поток данных примерно до 17-20% от его первоначального размера.

...