Leniwa, sterowana strumieniowo serializacja obiektów za pomocą protobuf-net
Opracowujemy usługę WCF do przesyłania strumieniowego dużej ilości danych, dlatego zdecydowaliśmy się na korzystaniePrzesyłanie strumieniowe WCF funkcjonalność połączona z aprotobuf-net serializacja.
Kontekst:
Generalnie pomysł polega na serializowaniu obiektów w usłudze, zapisywaniu ich w strumieniu i wysyłaniu. Na drugim końcu rozmówca otrzyma obiekt Stream i może odczytać wszystkie dane.
Obecnie kod metody serwisowej wygląda trochę tak:
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};
}
Obiekt BusinessResponse jest serializowany do pamięci MemoryStream i jest zwracany z metody. Po stronie klienta kod wywołujący wygląda tak:
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;
Więc kiedyserializer.Deserialize()
nazywa się to czyta ze strumieniamethodResult.ResultBody
W tym samym czasie po stronie usługi WCF odczytuje MemoryStream, który został zwrócony z aTestMethod
.
Problem:
To, co chcielibyśmy osiągnąć, to pozbyć się aMemoryStream
i początkowa serializacja całego obiektu po stronie usługi naraz. Ponieważ korzystamy z transmisji strumieniowej, chcielibyśmy uniknąć przechowywania seryjnego obiektu w pamięci przed wysłaniem.
Pomysł:
Idealnym rozwiązaniem byłoby zwrócenie pustego, wykonanego na zamówienie obiektu Stream (zTestMethod()
) z odwołaniem do obiektu, który ma być serializowany (w moim przykładzie obiekt „BusinessResponse”). Więc kiedy WCF wywołujeRead()
Metoda mojego strumienia, wewnętrznie serializuję kawałek obiektu za pomocą protobuf-net i zwracam go do dzwoniącego bez zapisywania go w pamięci.
A teraz jest problem, ponieważ to, czego potrzebujemy, to możliwość serializowania obiektu kawałek po kawałku w momencie odczytywania strumienia. Rozumiem, że jest to zupełnie inny sposób serializacji - zamiast przesuwać obiekt do serializatora, chciałbym poprosić o treść serializowaną kawałek po kawałku.
Czy ten rodzaj serializacji jest w jakiś sposób możliwy przy użyciu protobuf-net?