Techniken

Beschreibt einige häufig verwendete Entwurfsmuster für den Umgang mit Protocol Buffers.

Sie können auch Design- und Nutzungsfragen an die Protocol Buffers Diskussionsgruppe senden.

Häufige Dateinamenserweiterungen

Es ist ziemlich üblich, Nachrichten in mehreren verschiedenen Formaten in Dateien zu schreiben. Wir empfehlen die Verwendung der folgenden Dateierweiterungen für diese Dateien.

InhaltErweiterung
Textformat.txtpb
Wire-Format.binpb
JSON-Format.json

Speziell für das Textformat ist .textproto ebenfalls recht verbreitet, wir empfehlen jedoch .txtpb wegen seiner Kürze.

Mehrere Nachrichten streamen

Wenn Sie mehrere Nachrichten in eine einzelne Datei oder einen Stream schreiben möchten, liegt es an Ihnen, den Überblick zu behalten, wo eine Nachricht endet und die nächste beginnt. Das Protocol Buffer Wire-Format ist nicht selbst-abgrenzend, daher können Protocol Buffer-Parser eine Nachricht nicht von selbst erkennen. Der einfachste Weg, dieses Problem zu lösen, besteht darin, die Größe jeder Nachricht zu schreiben, bevor Sie die Nachricht selbst schreiben. Wenn Sie die Nachrichten wieder einlesen, lesen Sie die Größe, dann lesen Sie die Bytes in einen separaten Puffer und parsen dann aus diesem Puffer. (Wenn Sie das Kopieren von Bytes in einen separaten Puffer vermeiden möchten, werfen Sie einen Blick auf die Klasse CodedInputStream (sowohl in C++ als auch in Java), der gesagt werden kann, dass das Lesen auf eine bestimmte Anzahl von Bytes beschränkt wird.)

Große Datensätze

Protocol Buffers sind nicht für die Handhabung großer Nachrichten konzipiert. Als Faustregel gilt: Wenn Sie mit einzelnen Nachrichten von mehr als einem Megabyte zu tun haben, ist es möglicherweise an der Zeit, eine alternative Strategie in Betracht zu ziehen.

Das heißt, Protocol Buffers eignen sich hervorragend für die Handhabung einzelner Nachrichten *innerhalb* eines großen Datensatzes. Normalerweise besteht ein großer Datensatz aus einer Sammlung kleiner Teile, wobei jedes kleine Teil strukturierte Daten sind. Auch wenn Protocol Buffers nicht den gesamten Datensatz auf einmal verarbeiten können, vereinfacht die Verwendung von Protocol Buffers zur Kodierung jedes Teils Ihr Problem erheblich: Nun müssen Sie nur noch eine Sammlung von Byte-Strings anstelle einer Sammlung von Strukturen verwalten.

Protocol Buffers enthalten keine integrierte Unterstützung für große Datensätze, da unterschiedliche Situationen unterschiedliche Lösungen erfordern. Manchmal genügt eine einfache Liste von Datensätzen, während Sie manchmal etwas benötigen, das eher einer Datenbank ähnelt. Jede Lösung sollte als separate Bibliothek entwickelt werden, damit nur diejenigen, die sie benötigen, die Kosten tragen.

Selbstbeschreibende Nachrichten

Protocol Buffers enthalten keine Beschreibungen ihrer eigenen Typen. Daher ist es schwierig, nützliche Daten zu extrahieren, wenn nur eine rohe Nachricht ohne die entsprechende .proto-Datei vorliegt, die ihren Typ definiert.

Der Inhalt einer .proto-Datei kann jedoch selbst mit Protocol Buffers dargestellt werden. Die Datei src/google/protobuf/descriptor.proto im Quellcode-Paket definiert die beteiligten Nachrichtentypen. protoc kann mit der Option --descriptor_set_out eine FileDescriptorSet – die eine Menge von .proto-Dateien darstellt – ausgeben. Damit können Sie eine selbstbeschreibende Protokollnachricht wie folgt definieren

syntax = "proto3";

import "google/protobuf/any.proto";
import "google/protobuf/descriptor.proto";

message SelfDescribingMessage {
  // Set of FileDescriptorProtos which describe the type and its dependencies.
  google.protobuf.FileDescriptorSet descriptor_set = 1;

  // The message and its type, encoded as an Any message.
  google.protobuf.Any message = 2;
}

Durch die Verwendung von Klassen wie DynamicMessage (verfügbar in C++ und Java) können Sie dann Werkzeuge schreiben, die SelfDescribingMessages manipulieren können.

All dies gesagt, der Grund, warum diese Funktionalität nicht in der Protocol Buffer-Bibliothek enthalten ist, ist, dass wir sie innerhalb von Google nie benötigt haben.

Diese Technik erfordert Unterstützung für dynamische Nachrichten mittels Deskriptoren. Überprüfen Sie, ob Ihre Plattformen diese Funktion unterstützen, bevor Sie selbstbeschreibende Nachrichten verwenden.