Introduction
Nous allons ici entrée dans le vif du sujet avec un exemple d’utilisation de gRPC et en utilisant dans un premier temps le langage GO, donc je commence l’étude et que vous pouvez retrouver dans des billets dédiés à l’étude de ce langage de Google puissant et agréable.
Prérequis
Nous allons ici entrée dans le vif du sujet avec un exemple d’utilisation de gRPC et en utilisant dans un premier temps le langage GO, donc je commence l’étude et que vous pouvez retrouver dans des billets dédiés à l’étude de ce langage de Google puissant et agréable.
Environnement de développement
Pour ma part, j’utilise le plus simplement du monde les outils suivants :
Pour la compilation des proto en GO puis en gRPC pour GO, il faudra aussi installer :
Démo
Cette démo basique va permettre d’introduire les différents concept suivant :
Le but fonctionnel de la démo n’a pas vraiment d’intérêt c’est surtout l’implémentation, la consommation de celui-ci. Donc pour faire simple je suis partie sur un service mettant à disposition un ensemble d’opérations de calcul basique, tels que : l’addition, soustraction et retourner une table de multiplication quelque conque.
Définition de notre “Protocol buffers”
Description
Ici, nous allons écrire l’ensemble des descriptions des messages et des opérations de notre service à l’aide de se langage de description. Il va nous permettre de générer le code servant côté serveur mais aussi le code servant côté client que l’on peut appeler le contrat de service.
Code
syntax = "proto3"; option go_package = "fredericschmidt.fr/GoDemo01/calculatrice"; package Calculator; service CalculatorService { rpc AddOperation (ValuesCalculatorRequest) returns (ResultCalculatorResponse); rpc SubOperation (ValuesCalculatorRequest) returns (ResultCalculatorResponse); rpc TableOperation (TableCalculatorRequest) returns (TableCalculatorResponse); } message ResultCalculatorResponse { int32 Result = 1; } message ValuesCalculatorRequest { int32 TermX = 1; int32 TermY = 2; } message TableCalculatorRequest { int32 Multiplicand = 1; int32 Multiplier = 2; } message TableCalculatorResponse { repeated OneLineInTableResponse LineOfTable = 1; } message OneLineInTableResponse { int32 Multiplicand = 1; int32 Multiplier = 2; int32 Product = 3; }
Génération
1ere Etape
Après, il faut générer le code en Langage GO dans notre cas et pour ce faire nous allons exécuter la commande suivante :
protoc --go_out="D:\TempDev\Lab\gRpc\goroot\src" .\Calculatrice.proto
Alors la commande protoc doit si l’installation a bien été effectuée dans le répertoire de la variable GOBIN.
A ce même titre on devrait retrouver aussi les commandes protoc-gen-go.exe et protoc-gen-go-grpc.exe. Quand la génération a bien été effectuée à l’aide de la commande protoc, qui prend deux paramètres qui se trouvent être :
2nde Etape
Après, il nous faut générer à partir de l’étape précédence le fichier en langage GO spécifique à gRPC et pour ce faire nous allons utiliser la commande suivante :
protoc --go-grpc_out="D:\TempDev\Lab\gRpc\goroot\src" .\Calculatrice.proto
avec pour paramètres :
Nous obtenons à l’issue de ces deux étapes deux fichiers en GO :
Nous reviendrons plus en détails sur le contenu de ces deux fichiers ultérieurement.
Résumé
Pour pouvoir utiliser le code généré auparavant il nous faut développer deux parties distinctes :
Le Serveur
Explication de code
Dans notre démonstration, la partie serveur va implémenter les méthodes suivantes :
type CalculatorServiceServer interface { AddOperation(context.Context, *ValuesCalculatorRequest) (*ResultCalculatorResponse, error) SubOperation(context.Context, *ValuesCalculatorRequest) (*ResultCalculatorResponse, error) TableOperation(context.Context, *TableCalculatorRequest) (*TableCalculatorResponse, error) mustEmbedUnimplementedCalculatorServiceServer() }
L’étape suivante de démarrer et mettre en écoute le serveur gRPC et pour cela nous allons utiliser le package GO
concernant le gRPC.
Nous allons donc l’installer à l’aide de la commande GO suivante :
go get google.golang.org/grpc
Voici le code de la partie serveur :
fmt.Println("Starting Calculator Server gRPC") lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("ERROR : failed to listen on port %d : %v", port, err) } srv := grpc.NewServer() myPb.RegisterCalculatorServiceServer(srv, &CalculatorServer{}) if err := srv.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) }
Quelques explications sur certaines lignes du code.
lis, err := net.Listen("tcp", port)
Permet de mettre sur écoute toutes les adresses disponibles sur la machine (car nous n’avons pas précisé d’adresse)
locale sur un port précis dans un protocole défini et d’attendre les demandes.
srv := grpc.NewServer()
Demande à gRPC de créer un serveur ou plutôt une coquille vide, car il n’y aura pas encore de service défini et il ne
sera pas démarrer. Et donc ne pourra pas encore accepter des demandes et les traiter.
myPb.RegisterCalculatorServiceServer(srv, &CalculatorServer{})
Si l’on regarde le code généré à partir de l’IDL, on voit quelle fait appel à la ligne de suivante :
s.RegisterService(&_CalculatorService_serviceDesc, srv)
Elle permet de déclarer et d’enregistrer pour notre coquille vide de serveur le contrat de service et son implémentation tout ceci étant contenu dans le code généré à partir de l’IDL. C’est indispensable de faire cela avant toutes choses.
La dernière étape est le démarrage du serveur pour qu’il puisse traiter les demandes. Voici la partie de code avec une écriture spécifique à GO dans la condition :
if err := srv.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
L’instruction qui nous intéresse est la suivante :
err := srv.Serve(lis);
Elle va simplement se mettre à l’écoute sur notre listener et traiter les demandes entrantes. Chaque demande (Transport et service) sera traitée dans une Go Routine (voir le billet sur le langage GO). Si une erreur fatal survient lors d’une demande alors le serveur sera fermé et une fatale error sera remontée.
Pour notre démonstration, pour stopper le serveur il faudra tout simplement effectuer un <CTRL>+<C>.
Le client
Explication de code
Je ne vais m’arrêter que sur les parties de code propre à gRPC, le reste étant plus à lire dans les billets qui sont sur le langage GO et ses spécificités. En particulier, sur l’utilisation du package flag pour le traitement des arguments en ligne de commande.
cnx, err := grpc.Dial(uri, grpc.WithInsecure(), grpc.WithBlock())
Etablie une connexion vers un serveur se trouvant à l’adresse uri, dans notre cas se sera localhost:666 et avec les options suivantes :
c := pb.NewCalculatorServiceClient(cnx)
On instancie un client on pourrait aussi parler de proxy dans d’autres langages, vers notre serveur puisque l’on a établie une connexion cnx.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Permet de mettre en place un Timeout si notre traitement dans notre contexte principal, dans notre cas, notre func main passe la seconde. Si cela dépasse une erreur de type DeadlineExceed interrompra l’appel en cours. Vous pouvez simplement le vérifier en mettant time.Microsecond en lieu et place de time.Second.
defer cnx.Close()
Fermeture de la connexion après la fin du traitement. On utilise ici un mot clé du langage GO defer qui permet de prévoir les instructions à effectuer lorsque l’on sortira de la func et c’est GO qui prendra en charge la ou les instructions.
Utilisation du client
.\ClientGoDemo01.exe -action TABLE -Multiplicand 5 -Multiplier 10
Cette commande, après avoir compiler les deux parties client et serveur. Après avoir démarrer la partie serveur et quelle soit en écoute, qui est exécutée en ligne de commande quelque conque. Permet de demander au serveur de nous retourner la table de multiplication des 5, de 0 à 10 (toute notre enfance les tables de multiplications !!). Le résultat en sortie donnera ceci :
Client started Table de multiplation de 5 X 10. 5 X 0 = 0 5 X 1 = 5 5 X 2 = 10 5 X 3 = 15 5 X 4 = 20 5 X 5 = 25 5 X 6 = 30 5 X 7 = 35 5 X 8 = 40 5 X 9 = 45 5 X 10 = 50 Client ended.
Si vous avez besoin de l’aide en ligne de la commande il suffit de taper la commande suivante :
.\ClientGoDemo01.exe --help
En résumé
Ici nous venons de voir :
Conclusion
Voilà, un exemple basique de mise en place d’un serveur gRPC et de sa consommation au travers d’un client En utilisant l’IDL pour le protocole de buffers pour générer le service, les messages, le contrat de service.

Références
Source du projet sur GitHub
Voici quelques références sur le sujet gRPC et Protocol Buffers de Google.
Site Officiel du Protocol Buffers
GitHub de l’extension de Google pour transpiler en langage GO
Ajouer un commentaire