Chúng tôi đang phát triển một dịch vụ WCF để truyền trực tuyến một lượng lớn dữ liệu, do đó chúng tôi đã chọn sử dụng chức năng WCF Streaming kết hợp với chuỗi tuần tự protobuf-net.Nối tiếp đối tượng Lười biếng, luồng với protobuf-net
Bối cảnh:
chung một ý tưởng là để serialize đối tượng trong dịch vụ, hãy viết chúng thành một dòng suối và gửi. Ở đầu kia người gọi sẽ nhận được một đối tượng Stream và nó có thể đọc tất cả dữ liệu.
Vì vậy, hiện nay các phương pháp mã dịch vụ trông hơi như thế này:
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};
}
Đối tượng BusinessResponse là serialized đến một MemoryStream và được trả về từ một phương pháp. Về phía khách hàng mã gọi trông như thế:
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;
Vì vậy, khi serializer.Deserialize()
được gọi là nó đọc từ một dòng methodResult.ResultBody
, trong cùng thời gian trên WCF bên dịch vụ đang đọc một MemoryStream, đã được trở về từ a TestMethod
.
Vấn đề:
gì chúng tôi muốn đạt được là để thoát khỏi một MemoryStream
và ban đầu serialization của toàn bộ đối tượng ở phía bên dịch vụ cùng một lúc. Vì chúng tôi sử dụng phát trực tuyến, chúng tôi muốn tránh việc giữ một đối tượng được tuần tự hóa trong bộ nhớ trước khi gửi.
Idea:
Các giải pháp hoàn hảo sẽ trở lại một, đối tượng Suối custom-made rỗng (từ TestMethod()
) với một tham chiếu đến một đối tượng mà là để được tuần tự (object 'BusinessResponse' trong ví dụ của tôi). Vì vậy, khi WCF gọi phương thức luồng của tôi, tôi nội bộ tuần tự hóa một phần của đối tượng bằng cách sử dụng protobuf-net và trả lại cho người gọi mà không lưu trữ nó trong bộ nhớ.
Và bây giờ có một vấn đề, bởi vì những gì chúng tôi thực sự cần là khả năng sắp xếp từng phần một đối tượng vào thời điểm luồng được đọc. Tôi hiểu rằng đây là cách hoàn toàn khác nhau của serialization - thay vì đẩy một đối tượng vào serializer, tôi muốn yêu cầu một đoạn nội dung nối tiếp từng mảnh.
Loại serialization đó có thể sử dụng protobuf-net không?
Đây có phải là một đối tượng không? Hoặc một loạt các đối tượng (một bộ sưu tập)? Cho dù nó là giá trị nhìn vào điều này thực sự phụ thuộc vào cấu hình WCF của bạn - trong hầu hết các cấu hình nó sẽ luôn luôn đệm toàn bộ tin nhắn trong bộ nhớ * anyway * - vì vậy nó có thể dễ dàng để không thay đổi bất cứ điều gì. –
Xin chào Marc, WCF được định cấu hình để không sử dụng tính năng đệm - đó là điểm phát trực tiếp - Tôi muốn giảm dung lượng bộ nhớ trên phía máy chủ. Ngoài ra, nếu tôi muốn sắp xếp từng bộ sưu tập các đối tượng, tôi sẽ sử dụng 'SerializeWithLengthPrefix()' mỗi khi Client gọi 'Read()' và bộ đệm cơ bản của tôi nhỏ hơn số lượng dữ liệu yêu cầu. Vấn đề ở đây là tôi muốn có thể phân chia một chuỗi tuần tự hóa đối tượng. –
câu hỏi thú vị. I * nghĩ * điều này có thể được khái quát hóa, về cơ bản là một luồng giả mạo làm cho công việc Đọc và Viết là các đồng tác vụ. Nếu bạn không nhớ có thêm một Thread, nó có thể được thực hiện với một cổng đơn giản, tuy nhiên iirc Jon đã có một số ý tưởng thú vị. Tôi sẽ phải xem xét và lấy lại cho bạn. Tuy nhiên, tôi có thể nói mà không có nghi ngờ rằng tôi không có ý định hack cốt lõi của protobuf-net cho mục đích :) –