Utilisateur:Alexandre Desbos

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

Etude du protocole gRPC

Etudiant : Alexandre Desbos

Tuteur : David Télisson

Introduction

Les technologies du protocole gRPC

RPC

Le RPC[1], Remote Procedure Call est un protocole réseaux qui permet de faire des appels de fonctions à distance, une machine peut dire à une autre machine d’effectuer une action, au lieu d’appeler une fonction locale dans une bibliothèque.

Protocol buffer

Le protocol buffers est un outil de sérialisation et désérialisation de données developpé par google. 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[2] et le multiplexage.

Comparaison de gRPC et REST

Application

Objectif

Dans cette partie, nous allons implémenter un PoC[3] qui montre le fonctionnement du protocole gPRC entre un serveur et un client développées dans des langages différents.

Installation

Dans une invite de commande executé les commandes suivantes pour installer les outils de gRPC.

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

écrire le fichier proto

La première chose pour une application en gRPC est de crée un fichier .proto

//version de la syntaxe
syntax = "proto3";    
 
//On définit un service
service IceCream {
  rpc OrderIceCream(IceCreamRequest) returns (IceCreamResponse);
}
 
//On définit les types de message
 
//La requête attend un entier et une chaine de caractère
message IceCreamRequest {
  int32 scoops = 1;
  string flavor = 2;
}
 
//La réponse sera une chaine de caractère
message IceCreamResponse {
  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=../server --grpc_python_out=../server ice_cream.proto\n $protoc --js_out=import_style=commonjs,binary:. ice_cream.proto\n $protoc-gen-grpc --grpc_out=. --proto_path=. ice_cream.proto

création du serveur

On implemente maintenant un serveur en python.

import grpc
import concurrent
from concurrent import futures
 
#On importe les fichiers généré par le compilateur protoc
import ice_cream_pb2
import ice_cream_pb2_grpc
 
 
#On définit la fonction réponse du serveur
class IceCreamServicer(ice_cream_pb2_grpc.IceCreamServicer):
  def OrderIceCream(self, request, context):
    print('we got something!!')
    response = ice_cream_pb2.IceCreamResponse()
    response.message = f"here is your {request.scoops} scoop {request.flavor} ice cream!"
    return response
 
#On créer un serveur en local connecter sur le port 50051
def main():
  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
  ice_cream_pb2_grpc.add_IceCreamServicer_to_server(IceCreamServicer(),  server)
  print('Server Started. Listening on 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.

const grpc = require('grpc');
//On imoporte les fichiers javascript géneré par le compilateur 
const messages = require('./ice_cream_pb');
const services = require('./ice_cream_grpc_pb');
 
//Le client se connecte sur le port 50051
function main() {
  const client = new services.IceCreamClient(
    'localhost:50051', grpc.credentials.createInsecure()
  );
 
//On définit les variables que l'on va envoyer au serveur
  const iceCreamRequest = new messages.IceCreamRequest();
  iceCreamRequest.setScoops(3);
  iceCreamRequest.setFlavor('strawberry');
 
//On envoie une requete au serveur
  client.orderIceCream(iceCreamRequest, function (err, response) {
    if (err) {
      console.log('this thing broke!', err);
    } else {
      console.log('response from python:', response.getMessage());
    }
  })
}
 
main();

Sources

https://grpc.io/ https://developers.google.com/protocol-buffers