Etude du protocole gRPC

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche

Etudiant : Alexandre Desbos

Tuteur : David Télisson

Introduction

gRPC est une technologie open source développée par google en 2015. Il s’agit d’un framework RPC Remote Procedure Call qui permet de faire des appels de fonctions à distance. Il est basé sur deux technologies qui sont HTTP/2 et protocol Buffers. Cette technologie est utilisé notamment pour la création d'API

ShemagRPC.png

Les technologies du protocole gRPC

gRPC repose principalement sur deux technologies qui le rende efficace, le protocol Buffers et HTTP/2.

Protocol buffer

Le protocol buffers est un outil de sérialisation et désérialisation de données developpé par google. Cet outil repose sur les fichiers .proto, des fichiers dans lesquels on peut definir des services. Protocol Buffers permet alors de génerer du code dans de nombreux languages pour décrire les services. Il utilise un encodage binaire ce qui permet d’avoir un bon typage des messages mais aussi une transmission de données rapide.

HTTP/2

HTTP/2 est la mise à niveau du protocole de transfert hypertexte HTTP/1. C'est un protocole de communication client-serveur, son objectif est d'améliorer les performances des sites Web. HTTP/2 est conçu pour résoudre de nombreux problèmes de performances inhérents à HTTP/1.1. Les principaux avantages sont le mode server push et le multiplexage.

Comparaison de gRPC et REST

Dans la programmation web, les API REST sont aujourd'hui utilisées par la majorité des developpeurs. Malgré cela, depuis quelques temps, le gRPC devient une alternative très interresante à REST et pourrait potentiellement le remplacer. On voit sur le tableaux ci-dessous les différences principales entre ces deux technologies.

Protobuf.png

Application

Dans cette partie, nous allons implémenter un PoC qui montre le fonctionnement du protocole gPRC entre un serveur et un client développées dans des langages différents. Le code est accesible sur github

Installation

Il faut commencer par installer la dernière version stable de python et de nodejs.
Les commandes suivantes permette d'installer les outils de nécessaire pour faire du gRPC.

$pip install grpcio
$pip install grpc-tools
$npm install -g request
$npm config set unsafe-perm true
$npm install protoc-gen-grpc -g
$npm install grpc
$npm install google-protobuf

écrire le fichier proto

La mise en œuvre de gRPC commence toujours par la rédaction d’un fichier proto dans lequel on définit les services que l'on veut. Dans notre application, on crée un service inscription USMB et ont défini ensuite le type de la requète et le type de la réponse.

//USMB.proto

//version de la syntaxe
syntax = "proto3";    
 
//On définit un service
service Inscription {
  rpc InscriptionUSMB(InscriptionRequest) returns (InscriptionResponse);  
}
 
//On définit les types de message
 
//La requète attend un entier et une chaine de caractère
message InscriptionRequest {
  int32 annee = 1;   
  string nom = 2; 
}
 
//La reponse sera une chaine de caractère
message InscriptionResponse {
  string message = 1;
}

géneration du code

Pour génerer le code avec le compilateur protoc, rentrer les commande suivante dans un terminal de commande:

$python -m grpc_tools.protoc --proto_path=. --python_out=. --grpc_python_out=. USMB.proto
$protoc --js_out=import_style=commonjs,binary:. USMB.proto
$protoc-gen-grpc --grpc_out=. --proto_path=. USMB.proto

Deux fichiers javascript et deux fichiers python ont été crée dans le dossier, ces fichiers ne doivent pas être édité !

création du serveur

On implemente maintenant un serveur en python.

#server.py

import grpc
import concurrent
from concurrent import futures

#On importe les fichiers généré par le compilateur protoc
import USMB_pb2
import USMB_pb2_grpc


#On définit la fonction réponse du serveur
class InscriptionServicer(USMB_pb2_grpc.InscriptionServicer):
  def InscriptionUSMB(self, request, context):
    print('requête reçu')
    response = USMB_pb2.InscriptionResponse()
    response.message = f"Bonjour {request.nom}, vous êtes inscrit en {request.annee}ème année à l'univesité de Savoie"
    return response


#On définit un serveur sur le port 50051
def main():
  server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
  USMB_pb2_grpc.add_InscriptionServicer_to_server(InscriptionServicer(), server)
  print('Serveur lancé. En écoute sur le port 50051')
  server.add_insecure_port('[::]:50051')
  server.start()
  server.wait_for_termination()

main()

création du client

On implémente un client en javascript.

//client.js

const grpc = require('grpc');
//On imoporte les fichiers javascript géneré par le compilateur 
const messages = require('./USMB_pb');
const services = require('./USMB_grpc_pb');

//On se connecte au serveur 
function main() {
  const client = new services.InscriptionClient(
    'localhost:50051', grpc.credentials.createInsecure()
  );

  //On rentre nos valeurs d'entrées
  const InscriptionRequest = new messages.InscriptionRequest();
  InscriptionRequest.setAnnee(3);
  InscriptionRequest.setNom('Alexandre Desbos');

  //On regarde si il y a une erreur
  client.inscriptionUSMB(InscriptionRequest, function (err, response) {
    if (err) {
      console.log('Il y a une erreur', err);
    } else {
      console.log('réponse de python:', response.getMessage());
    }
  })
}

main();

Résultat

Maintenant que tout est prêt, on peur réaliser la connection entre le serveur et le client. Dans un terminal de commande, on execute le fichier python:

$python serveur.py

Puis dans un autre terminal, on execute le fichier javascript pour envoyé une requète au serveur:

$node client.js

Le client reçoit une réponse du serveur !

Liens utiles

https://grpc.io/
https://developers.google.com/protocol-buffers
https://developers.google.com/web/fundamentals/performance/http2
https://github.com/uw-labs/bloomrpc