views:

458

answers:

3

We are currently trying to move large amounts of data to a Silverlight 3 client using WCF with PollingDuplex. I have read about the MultiplerMessagesPerPoll in Silverlight 4 and it appears to be quite a bit faster. Are there any examples out there for me to reference (using MultipleMessagesPerPoll)? Or maybe some good references on using Net.TCP? Maybe I should be taking a completely different approach? Any ideas or suggestions would be greatly appreciated.

Thanks!

+1  A: 

Streaming serialized response chunks works well:

Your WCF binding configuration would resemble the following:

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

Your Service method would look something like:

[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;
}

And your client-side completed method would do something like:

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;
   }
}
KodeKreachor
A: 

I implemented the suggested solution above. After implementation, I found this link:

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

I then implemented the Binary writer, as shown below.

Service Method:

[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;
    }

Client-side Completed Event:

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

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

I checked the difference of my object as shown in the link above, my results are shown below:


Text = 68,866,216 bytes


Binary = 49,207,475 bytes (28.5% less than Text)

JSprang
A: 

I'm basing this on your answer and its emphasis on the size of the data you're transferring. If you're keeping the blocks of data transferred under 4GB, you can make use of the GZipStream class in the System.IO.Compression namespace. In my experience using it with plain text, it reduced the data stream to about 17-20% of its original size.

Austin Salonen
Thanks Austin! I'll definately take a look at this!
JSprang