We are developing a WCF service for streaming a large amount of data, therefore we have chosen to use WCF Streaming functionality combined with a protobuf-net serialization.
Context:
Generally an idea is to serialize objects in the service, write them into a stream and send. On the other end the caller will receive a Stream object and it can read all data.
So currently the service method code looks somewhat like this:
public Result TestMethod(Parameter parameter)
{
// Create response
var responseObject = new BusinessResponse { Value = "some very large data"};
// The resposne have to be serialized in advance to intermediate MemoryStream
var stream = new MemoryStream();
serializer.Serialize(stream, responseObject);
stream.Position = 0;
// ResultBody is a stream, Result is a MessageContract
return new Result {ResultBody = stream};
}
The BusinessResponse object is serialized to a MemoryStream and that is returned from a method. On the client side the calling code looks like that:
var parameter = new Parameter();
// Call the service method
var methodResult = channel.TestMethod(parameter);
// protobuf-net deserializer reads from a stream received from a service.
// while reading is performed by protobuf-net,
// on the service side WCF is actually reading from a
// memory stream where serialized message is stored
var result = serializer.Deserialize<BusinessResponse>(methodResult.ResultBody);
return result;
So when serializer.Deserialize() is called it reads from a stream methodResult.ResultBody, on the same time on the service side WCF is reading a MemoryStream, that has been returned from a TestMethod.
Problem:
What we would like to achieve is to get rid of a MemoryStream and initial serialization of the whole object on the service side at once.
Since we use streaming we would like to avoid keeping a serialized object in memory before sending.
Idea:
The perfect solution would be to return an empty, custom-made Stream object (from TestMethod()) with a reference to an object that is to be serialized ('BusinessResponse' object in my example).
So when WCF calls a Read() method of my stream, I internally serialize a piece of an object using protobuf-net and return it to the caller without storing it in the memory.
And now there is a problem, because what we actually need is a possibility to serialize an object piece by piece in the moment when stream is read. I understand that this is totally different way of serialization - instead of pushing an object to a serializer, I'd like to request a serialized content piece by piece.
Is that kind of serialization is somehow possible using protobuf-net?
SerializeWithLengthPrefix()each time the Client callsRead()and my underlying buffer is smaller than requested data amount. The issue here is that I'd like to be able to split single object serialization. - Hubert R. Skrzypek