« Utilisateur:Alexandre Desbos » : différence entre les versions

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche
 
(10 versions intermédiaires par le même utilisateur non affichées)
Ligne 6 : Ligne 6 :


==Introduction ==
==Introduction ==

gRPC est une technologie open source développée par google en 2015. Il s’agit d’un framework RPC[https://fr.wikipedia.org/wiki/Remote_procedure_call#:~:text=En%20informatique%20et%20en%20t%C3%A9l%C3%A9communication,'un%20serveur%20d'applications.] basé sur deux technologie qui sont HTTP/2 et protocol Buffers.
Cette technologie est utilisé notamment pour la création d’API[https://fr.wikipedia.org/wiki/Interface_de_programmation].


== Les technologies du protocole gRPC ==
== Les technologies du protocole gRPC ==
Ligne 11 : Ligne 14 :
=== RPC ===
=== RPC ===


Le RPC[https://fr.wikipedia.org/wiki/Remote_procedure_call#:~:text=En%20informatique%20et%20en%20t%C3%A9l%C3%A9communication,'un%20serveur%20d'applications.], 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.
Le RPC[https://fr.wikipedia.org/wiki/Remote_procedure_call#:~:text=En%20informatique%20et%20en%20t%C3%A9l%C3%A9communication,'un%20serveur%20d'applications.], Remote Procedure Call est un protocole réseaux qui permet de faire des appels de fonctions à distance, il permet à une machine de demander un service à un programme situé sur une autre machine. Il utilise le modèle client-serveur, le programme qui fait la requête est un client, et le programme fournisseur de services est le serveur.


===Protocol buffer ===
===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.
Le protocole 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 ===
Ligne 27 : Ligne 30 :
=== Objectif ===
=== Objectif ===


Dans cette partie, nous allons implémenter un PoC[https://fr.wikipedia.org/wiki/Preuve_de_concept] qui montre le fonctionnement du protocole gPRC entre un serveur et un client développées dans des langages différents.
Dans cette partie, nous allons implémenter un PoC[https://fr.wikipedia.org/wiki/Preuve_de_concept] 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[https://github.com/alexandredesbos/gRPC-connecting-python-javascript]


=== Installation ===
=== Installation ===
Ligne 33 : Ligne 36 :
Dans une invite de commande executé les commandes suivantes pour installer les outils de gRPC.
Dans une invite de commande executé les commandes suivantes pour installer les outils de gRPC.


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


Ligne 50 : Ligne 53 :
//On définit un service
//On définit un service
service IceCream {
service Inscription {
rpc OrderIceCream(IceCreamRequest) returns (IceCreamResponse);
rpc InscriptionUSMB(InscriptionRequest) returns (InscriptionResponse);
}
}
//On définit les types de message
//On définit les types de message
//La requête attend un entier et une chaine de caractère
//La requète attend un entier et une chaine de caractère
message IceCreamRequest {
message InscriptionRequest {
int32 scoops = 1;
int32 annee = 1;
string flavor = 2;
string nom = 2;
}
}
//La réponse sera une chaine de caractère
//La reponse sera une chaine de caractère
message IceCreamResponse {
message InscriptionResponse {
string message = 1;
string message = 1;
}
}
Ligne 72 : Ligne 75 :
Pour génerer le code avec le compilateur protoc, rentrer les commande suivante dans un terminal de commande:
Pour génerer le code avec le compilateur protoc, rentrer les commande suivante dans un terminal de commande:


<code>$python -m grpc_tools.protoc --proto_path=. --python_out=../server --grpc_python_out=../server ice_cream.proto</code>\n
<code>$python -m grpc_tools.protoc --proto_path=. --python_out=. --grpc_python_out=. USMB.proto</code> <br>
<code>$protoc --js_out=import_style=commonjs,binary:. ice_cream.proto</code>\n
<code>$protoc --js_out=import_style=commonjs,binary:. USMB.proto</code> <br>
<code>$protoc-gen-grpc --grpc_out=. --proto_path=. ice_cream.proto</code>
<code>$protoc-gen-grpc --grpc_out=. --proto_path=. USMB.proto</code>


=== création du serveur ===
=== création du serveur ===
Ligne 84 : Ligne 87 :
import concurrent
import concurrent
from concurrent import futures
from concurrent import futures

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


#On définit la fonction réponse du serveur
#On définit la fonction réponse du serveur
class InscriptionServicer(USMB_pb2_grpc.InscriptionServicer):
class IceCreamServicer(ice_cream_pb2_grpc.IceCreamServicer):
def OrderIceCream(self, request, context):
def InscriptionUSMB(self, request, context):
print('we got something!!')
print('requête reçu')
response = ice_cream_pb2.IceCreamResponse()
response = USMB_pb2.InscriptionResponse()
response.message = f"here is your {request.scoops} scoop {request.flavor} ice cream!"
response.message = f"Bonjour {request.nom}, vous êtes inscrit en {request.annee}ème année à l'univesité de Savoie"
return response
return response


#On créer un serveur en local connecter sur le port 50051
#On définit un serveur sur le port 50051
def main():
def main():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
USMB_pb2_grpc.add_InscriptionServicer_to_server(InscriptionServicer(), server)
ice_cream_pb2_grpc.add_IceCreamServicer_to_server(IceCreamServicer(), server)
print('Server Started. Listening on port 50051')
print('Serveur lancé. En écoute sur le port 50051')
server.add_insecure_port('[::]:50051')
server.add_insecure_port('[::]:50051')
server.start()
server.start()
server.wait_for_termination()
server.wait_for_termination()

main()
main()


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

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

//On rentre nos valeurs d'entrées
//On définit les variables que l'on va envoyer au serveur
const iceCreamRequest = new messages.IceCreamRequest();
const InscriptionRequest = new messages.InscriptionRequest();
iceCreamRequest.setScoops(3);
InscriptionRequest.setAnnee(3);
InscriptionRequest.setNom('Alexandre Desbos');
iceCreamRequest.setFlavor('strawberry');

//On envoie une requete au serveur
//On regarde si il y a une erreur
client.orderIceCream(iceCreamRequest, function (err, response) {
client.inscriptionUSMB(InscriptionRequest, function (err, response) {
if (err) {
if (err) {
console.log('this thing broke!', err);
console.log('Il y a une erreur', err);
} else {
} else {
console.log('response from python:', response.getMessage());
console.log('réponse de python:', response.getMessage());
}
}
})
})
}
}

main();
main();


</pre>
</pre>


=== Connection entre le serveur et le client ===
== Sources ==

Maintenant que tout est prêt, dans un terminal de commande, on execute le fichier python: <br/>
<code>$python serveur.py</code><br/><br/>
Puis dans un autre terminal, on execute le fichier javascript pour envoyé une requète au serveur:<br/>
<code>node client.js</code><br/><br/>
Le client reçoit une réponse du serveur !

== Liens utiles ==


https://grpc.io/
https://grpc.io/ <br/>
https://developers.google.com/protocol-buffers
https://developers.google.com/protocol-buffers <br/>
https://developers.google.com/web/fundamentals/performance/http2

Dernière version du 3 mai 2021 à 23:03

Etude du protocole gRPC

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[1] basé sur deux technologie qui sont HTTP/2 et protocol Buffers. Cette technologie est utilisé notamment pour la création d’API[2].

Les technologies du protocole gRPC

RPC

Le RPC[3], Remote Procedure Call est un protocole réseaux qui permet de faire des appels de fonctions à distance, il permet à une machine de demander un service à un programme situé sur une autre machine. Il utilise le modèle client-serveur, le programme qui fait la requête est un client, et le programme fournisseur de services est le serveur.

Protocol buffer

Le protocole 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[4] et le multiplexage.

Comparaison de gRPC et REST

Application

Objectif

Dans cette partie, nous allons implémenter un PoC[5] 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[6]

Installation

Dans une invite de commande executé les commandes suivantes pour installer les outils de 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 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 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

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 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.

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();

Connection entre le serveur et le client

Maintenant que tout est prêt, 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