2012-08-30 18 views
6

trong ngắn hạn, có cách nào để xác định một thông điệp protobuf có chứa một thông điệp kiểu tùy ý khác không? Một cái gì đó như:Protobuf: Làm tổ một thông báo về kiểu tùy ý

message OuterMsg { 
    required int32 type = 1; 
    required Message nestedMsg = 2; //Any sort of message can go here 
} 

Tôi nghi ngờ rằng có một cách để làm điều này bởi vì trong protobuf-triển khai khác nhau, các thông điệp biên soạn kéo dài từ một lớp học phổ biến Message cơ sở.

Nếu tôi đoán tôi phải tạo một tin nhắn cơ sở chung cho tất cả các loại thông điệp như thế này:

message BaseNestedMessage { 
    extensions 1 to max; 
} 

và sau đó làm

message OuterMessage { 
    required int32 type = 1; 
    required BaseNestedMessage nestedMsg = 2; 
} 

Đây có phải là cách duy nhất để đạt được điều này?

Trả lời

6

Không trực tiếp, về cơ bản; bộ đệm giao thức rất muốn biết cấu trúc trước và loại loại của thư không được bao gồm trên dây. Lớp cơ sở chung Message là một chi tiết triển khai để cung cấp mã thông thường của hệ thống ống nước - đặc tả bộ đệm giao thức không bao gồm thừa kế.

Có, do đó, hạn chế lựa chọn:

  • sử dụng khác nhau trường số cho mỗi tin nhắn kiểu
  • serialize thông điệp riêng biệt, và bao gồm nó như là một loại bytes, và truyền đạt "những gì là thế này ? " thông tin riêng biệt (có lẽ là một phân biệt đối xử/điều tra)

Tôi cũng cần lưu ý rằng một số triển khai có thể cung cấp hỗ trợ thêm cho việc này; protobuf-net (C#/.NET) hỗ trợ (riêng) cả kiểu thừa kế và thông báo động (tức là những gì bạn có ở trên), nhưng chủ yếu chỉ được sử dụng từ thư viện đó đến thư viện đó. Vì đây là tất cả ngoài đặc điểm kỹ thuật (còn lại 100% hợp lệ theo định dạng dây), có thể không cần thiết để giải thích dữ liệu đó từ các triển khai khác.

+0

Vì tôi không thể biết trước tất cả các thông báo có thể, tôi sẽ tìm giải pháp tuần tự riêng biệt, sử dụng trường 'byte', cảm ơn bạn – DeX3

8

Cách phổ biến nhất để làm là làm cho các lĩnh vực bắt buộc đối với từng loại thông điệp:

message UnionMessage 
{ 
    optional MsgType1 msg1 = 1; 
    optional MsgType2 msg2 = 2; 
    optional MsgType3 msg3 = 3; 
} 

Kỹ thuật này cũng được mô tả trong tài liệu chính thức của Google, và được hỗ trợ tốt trên triển khai: https://developers.google.com/protocol-buffers/docs/techniques#union

1

Hoặc để nhiều trường optional, từ khóa oneof có thể được sử dụng kể từ v2.6 của Protocol Buffers.

message UnionMessage { 
    oneof data { 
    string a = 1; 
    bytes b = 2; 
    int32 c = 3; 
    } 
} 
Các vấn đề liên quan