prog:protobuf
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
prog:protobuf [2018/08/18 14:21] – Création avec "Protocol Buffers" root | prog:protobuf [2018/09/22 22:59] (Version actuelle) – [Protocol Buffers] : ajout de "Emplacement du .pb.* généré" root | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ====Protocol Buffers==== | + | =====Protocol Buffers===== |
- | Le format de base est simple. [[https:// | + | ====Cas simple==== |
+ | Le format de base est simple. [[https:// | ||
Ici, on crée deux messages '' | Ici, on crée deux messages '' | ||
- | |||
- | <note tip>Les identifiants entre 1 et 15 occupent un bit de moins que les autres. Ils sont à privilégier pour les champs répétées.</ | ||
< | < | ||
Ligne 22: | Ligne 21: | ||
</ | </ | ||
+ | ====Import==== | ||
Il est possible de créer des structures plus complexes avec des sous niveaux et d' | Il est possible de créer des structures plus complexes avec des sous niveaux et d' | ||
Ligne 51: | Ligne 51: | ||
</ | </ | ||
- | <note important> | + | ====Subtilités==== |
+ | ===Emplacement du .pb.* généré=== | ||
+ | Si le fichier '' | ||
+ | |||
+ | Généré dans le dossier '' | ||
+ | / | ||
+ | |||
+ | Généré dans '' | ||
+ | / | ||
+ | |||
+ | ====Évolutions==== | ||
+ | * proto2 : | ||
+ | * Il faut toujours mettre '' | ||
+ | * Mettre '' | ||
+ | * proto3 : | ||
+ | * Si un champ devient déprécié mais est encore supporté, ajouter '' | ||
+ | * Si un champ n'est définitivement plus utilisé, remplacer la ligne avec son identifiant par '' | ||
+ | * Les identifiants entre 1 et 15 occupent un octet. Ils sont à privilégier pour les champs répétées. Ceux entre 16 et 2047 sont sur deux octets. | ||
+ | |||
+ | ====gRPC==== | ||
+ | ===Cas simple=== | ||
+ | Le protocole se déclare dans un fichier '' | ||
+ | |||
+ | Soit une classe Greeter avec une procédure RPC '' | ||
+ | |||
+ | <code> | ||
+ | service Greeter { | ||
+ | rpc Talk (stream Rpc) returns (stream Rpc) {} | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Soit l' | ||
+ | < | ||
+ | syntax = " | ||
+ | |||
+ | import " | ||
+ | |||
+ | package llgc.protobuf.test; | ||
+ | |||
+ | service Greeter { | ||
+ | rpc Talk (stream Rpc) returns (stream Rpc) {} | ||
+ | } | ||
+ | |||
+ | message Rpc | ||
+ | { | ||
+ | message Msg | ||
+ | { | ||
+ | message Test | ||
+ | { | ||
+ | } | ||
+ | |||
+ | oneof data | ||
+ | { | ||
+ | optional llgc.protobuf.pattern.publisher.AddSubscriber add_subscriber = 1; | ||
+ | optional llgc.protobuf.pattern.publisher.RemoveSubscriber remove_subscriber = 2; | ||
+ | optional Test test = 3; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | repeated Msg msg = 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===Serveur=== | ||
+ | Il faut implémenter | ||
+ | |||
+ | <code cpp> | ||
+ | class GreeterImpl | ||
+ | { | ||
+ | // La méthode par défaut renvoie UNIMPLEMENTED. | ||
+ | // À chaque fois qu'un client appelle cette méthode, | ||
+ | // le serveur lance un thread pour exécuter la fonction Talk. | ||
+ | // Il peut y avoir en simultanée autant de threads que de clients. | ||
+ | // Tant que cette méthode n'est pas terminée, la connexion avec le | ||
+ | // client reste active. | ||
+ | // Tous les threads travaillent sur la même instance de la classe. | ||
+ | :: | ||
+ | :: | ||
+ | :: | ||
+ | { | ||
+ | :: | ||
+ | // Tant que le client n'a pas fermé la connexion, on reste dans | ||
+ | // l'attente de ces messages. | ||
+ | while (stream-> | ||
+ | { | ||
+ | // Ici, on répond au message. | ||
+ | stream-> | ||
+ | |||
+ | // La réponse est facultative. Ça dépend de ce que la | ||
+ | // fonction doit faire. | ||
+ | } | ||
+ | |||
+ | // Fermeture de la connexion à l' | ||
+ | // Dans notre cas précis, le client a déjà terminé puisque | ||
+ | // stream-> | ||
+ | return grpc:: | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Pour instancier le serveur | ||
+ | GreeterImpl service; | ||
+ | // Le builder n'a besoin | ||
+ | ServerBuilder builder; | ||
+ | builder.AddListeningPort(" | ||
+ | builder.RegisterService(& | ||
+ | // La variable service doit exister tant que l' | ||
+ | std:: | ||
+ | // Lancement du serveur. Fonction bloquante. | ||
+ | // Peut être lancée dans un thread. | ||
+ | server-> | ||
+ | // Pour arrêter le serveur (depuis un autre thread que celui | ||
+ | // ayant lancé la méthode Wait). | ||
+ | server-> | ||
+ | </ | ||
+ | |||
+ | ===Client=== | ||
+ | <code cpp> | ||
+ | // Création du client. | ||
+ | std:: | ||
+ | grpc:: | ||
+ | grpc:: | ||
+ | std:: | ||
+ | llgc:: | ||
+ | grpc:: | ||
+ | std:: | ||
+ | :: | ||
+ | |||
+ | // Communication avec le serveur. | ||
+ | :: | ||
+ | // Envoie un message au serveur. | ||
+ | stream-> | ||
+ | // Ferme la communication avec le serveur dans le sens client vers serveur. | ||
+ | stream-> | ||
+ | // Attente de la réponse de façon bloquante. | ||
+ | stream-> | ||
+ | // Pour arrêter un Read bloquant, il faut lancer depuis un autre thread | ||
+ | context.TryCancel(); | ||
+ | // Ferme la communication. | ||
+ | // L' | ||
+ | // va échouer mais ne sera plus bloquante. | ||
+ | if (!stream-> | ||
+ | std::cout << " | ||
+ | </code> |
prog/protobuf.1534594917.txt.gz · Dernière modification : 2018/08/18 14:21 de root