Fermer

février 10, 2021

Introduction à gRPC dans .NET Core et .NET 5


gRPC est un framework RPC hautes performances avec des fonctionnalités d'authentification enfichables et d'équilibrage de charge. Dans cet article, vous découvrirez gRPC et les tampons de protocole, comment créer des services gRPC dans .NET Core / 5 à l'aide de C # et comment créer des clients gRPC.

gRPC est un framework RPC hautes performances qui permet efficacement le service- communication en service dans et entre les centres de données. Il prend également en charge la connexion d'appareils mobiles et de clients de navigateur aux services de backend. Il a été implémenté dans Google et plus tard en open-source, et c'est actuellement un projet d'incubation de la Cloud Native Computing Foundation (CNCF). Ses fonctionnalités incluent:

  • Streaming bidirectionnel
  • Sérialisation binaire puissante
  • Authentification enfichable, équilibrage de charge et vérification de l'état

Si vous adoptez une architecture de microservice dans votre organisation, gRPC augmenterait probablement les performances du communication entre vos microservices.

Dans cet article, je vais vous montrer comment créer un service gRPC à l'aide de .NET Core 3.1 (ou version ultérieure). Je décomposerai quelques concepts fondamentaux importants de gRPC et inclurai également des étapes pour les faire pour les utilisateurs de Mac et VS Code.

Comme prérequis, je m'attends à une certaine familiarité avec C #, ASP.NET Core et Visual Studio ou VS Code.

Créer un serveur gRPC

Nous allons commencer par créer un nouveau projet dotnet avec le modèle de service gRPC.

Si vous utilisez Visual Studio, créez un nouveau projet et sélectionnez le modèle gRPC Service . Utilisez GrpcAuthor comme nom du projet.

Si vous utilisez VS Code, vous allez créer le projet à l'aide de dotnet CLI et l'ouvrir dans VS Code. Ouvrez votre application de ligne de commande (ou Terminal si vous êtes sur Mac) et exécutez la commande dotnet new grpc -o GrpcAuthor . Ouvrez ensuite le projet dans VS Code en exécutant la commande code -r GrpcAuthor .

The RPC Service Definition

Une application cliente gRPC peut appeler directement une méthode sur une application serveur comme s'il s'agissait d'un objet local. Les applications client et serveur se parlent en utilisant les tampons de protocole . Les tampons de protocole sont utilisés à la fois comme langage de définition d'interface (IDL) pour le service et comme format d'échange de messages sous-jacent.

Une interface de service est définie dans un fichier .proto utilisant un tampon de protocole. Dans celui-ci, vous spécifiez les méthodes qui peuvent être appelées à distance avec leurs paramètres et leurs types de retour. Le serveur implémente cette interface et exécute un serveur gRPC pour gérer les appels clients. Le client, d'autre part, a un stub (appelé simplement un client dans certaines langues) qui fournit les mêmes méthodes que le serveur, et avec lui, le client appelle les méthodes du serveur comme si elles étaient locales à l'application. [19659007] Une fois le service défini, vous utilisez le compilateur de tampon de protocole protoc pour générer des classes d'accès / transfert de données à partir de votre fichier de définition de proto. Ce fichier contient l'implémentation des messages et des méthodes dans l'interface de service.

Le modèle utilisé pour créer le projet comprend déjà un fichier proto greet.proto qui se trouve dans le Protos dossier.

 syntaxe  =   "proto3" ; 

option csharp_namespace  =   "GrpcAuthor" ; 

paquet salue ; 


service Greeter  {
  
  rpc  SayHello   ( HelloRequest )   renvoie   ( HelloReply ) ; 
} 


message HelloRequest  {
   string  name  =   1 ; 
} 


message HelloReply  {
   string  message  =   1 ; 
} 

Décomposons le fichier proto afin de comprendre la syntaxe du tampon de protocole. [19659037] La définition de l'interface du service Greet

 syntax = "proto3"; 

Le spécificateur de syntaxe est utilisé pour indiquer la version du tampon de protocole utilisée. Dans ce cas, proto3 qui est la dernière version au moment de la rédaction de cet article et a plus de fonctionnalités et de support de langage que son prédécesseur.

 option csharp_namespace  =   "GrpcAuthor" ; 

package greet ; 

L'option spécificateur csharp_namespace est utilisée pour spécifier l'espace de noms que les fichiers générés auront. Il est utilisé pour éviter les conflits de noms entre les types de messages de protocole, tout comme le spécificateur du package . La façon dont le spécificateur de package affecte le code généré dépend de la langue que vous utilisez. Pour C #, il est utilisé comme espace de noms sauf si vous fournissez une option csharp_namespace . En Java, il est utilisé comme nom de package, sauf si vous spécifiez option java_package dans le fichier .proto .

 message HelloRequest  {
   string  name  =   1 ; 
} 

message HelloReply  {
   string  message  =   1 ; 
} 

HelloRequest et HelloReply sont les structures de données qui seront utilisées pour échanger des informations entre le client et le serveur. Ils sont appelés messages et contiennent des paires nom-valeur appelées champs. Le numéro que vous voyez dans la définition de champ est un numéro unique utilisé pour identifier les champs lorsque le message est sérialisé vers Protobuf. En effet, la sérialisation d'un petit nombre est plus rapide que la sérialisation du nom de champ entier.


service Greeter  {
  rpc  SayHello   ( HelloRequest )   renvoie   ( HelloReply ) ; 
} 

Ceci est la définition du service et il contient une méthode SayHello avec un paramètre et un type de retour comme tampon de protocole messages .

Afin de générer du code pour le fichier .proto vous utilisez le compilateur protoc et le plugin C # pour générer le code serveur ou client. Cela sera fait pour vous en utilisant le package NuGet Grpc.Tools . Les classes nécessaires sont générées automatiquement par le processus de construction. Il sait comment générer les types via le paramètre de groupe d'éléments dans votre fichier .csproj .

 < ItemGroup > 
   < Protobuf   Inclure  =  " Protos  greet.proto "    GrpcServices  =  " Server "    /> 
 </  ItemGroup >  

Le code généré sait communiquer avec d'autres services / clients en utilisant des tampons de protocole. L'outillage C # génère le type GreeterBase qui sera utilisé comme classe de base pour implémenter le service gRPC.

Il existe une implémentation pour le service Greeter dans Services / GreeterService .cs :

  public   class   GreeterService  :  Greeter .  GreeterBase
 {
     privé   lecture seule  ILogger  < GreeterService >  _logger ; 
     public   GreeterService  ( ] ILogger  < GreeterService >  logger ) 
     {
        _logger  =  logger ; 
    } 

     public   override  Task  < HelloReply >   SayHello  ( HelloRequest request  ServerCallContext context ) 
     {
         return  Task .  FromResult  ( new   HelloReply [19659098] {
            Message  =   "Bonjour"   +  demande .  Nom
        } ) ; 
    } 
} 

Le service est implémenté en héritant de la classe Greeter.GreeterBase . Cette classe de base est générée au moment de la construction à l'aide du fichier greet.proto .

Créer un nouveau service gRPC

Vous avez vu le service Greeter généré à partir du modèle de projet. Vous allez créer un nouveau service avec une méthode RPC pour obtenir un auteur de livre par son nom.

Ajoutez un nouveau fichier au dossier Protos nommé author.proto puis copiez et collez-y la définition de l'interface ci-dessous.

 syntaxe  =   "proto3" ; 

option csharp_namespace  =   "GrpcAuthor" ; 

auteur du package ; 

Auteur du service  {
  rpc  GetAuthor   ( AuthorRequest )   renvoie   ( AuthorResponse ) ; 
} 

message AuthorRequest  {
   string  name  =   1 ; 
} 

message BookReply  {
   string  title  =   1 ; 
} 

message AuthorResponse  {
   string  name  =   1 ; 
  répété BookReply books_authored  =   2 ; 
} 

Dans cette définition de service, vous avez un service Author avec une méthode RPC GetAuthor . Le message AuthorResponse contient les champs name et books_authored . Le champ books_authored est un type composite de BookReply . La règle de champ répétée est utilisée pour indiquer qu’il s’agit d’une collection; par conséquent, il peut être répété un nombre illimité de fois dans un message sérialisé.

Maintenant que vous avez la définition du service, vous devez en informer votre projet afin qu'il génère le code nécessaire lors de la construction. Pour ce faire, mettez à jour le fichier GrpcAuthor.csproj pour inclure un groupe d'éléments avec un élément qui fait référence au fichier author.proto .

 < ItemGroup > 
   < Protobuf   Inclure  =  " Protos  greet.proto "    GrpcServices  = [19659020] " Serveur "    /> 
   < Protobuf   Inclure  =  " Protos  author.proto "    GrpcServices  =  " Server "    /> 
 </  ItemGroup > 

Mettre en œuvre le service Définition

Après avoir créé le contrat de service, vous devez l'implémenter. Créez un nouveau fichier dans le dossier Services nommé AuthorService.cs . Copiez et collez le code ci-dessous.

  using  System ; 
 using  System .  Collections .  Generic  ]; 
 en utilisant  System .  Linq ; 
 using  System .  Threading .  Tasks ; 
 utilisant  Grpc .  Core ; 
 using  Microsoft .  Extensions .  Logging ; 

 ] namespace  GrpcAuthor
 {
     public   class   AuthorService  :  Author .  AuthorBase
     {
         private   readonly  ILogger  < AuthorService >  _logger ; 
         private  List  < ] AuthorResponse >  auteurs ; 

         public   AuthorService  ( ILogger  < AuthorService >  logger ) 
         {
            _logger  =  enregistreur ; 
            auteurs  =   nouvelle   Liste  < AuthorResponse >  () ; 

             var  antonio  = [19659078] nouveau   AuthorResponse   { Name  =   "Antonio Gonzalez"  } ; 
            antonio .  BooksAuthored .  Add  ( new   BookReply   { Title  =   "Beaucoup de bruit pour rien"  } ) ; 
            antonio .  BooksAuthored .  Add  ( new   BookReply   { Title  =   "Comment faire une scission "} ) ; 
            auteurs .  Add  ( antonio ) ; 

             var  jack  =   new   AuthorResponse   { Nom  =   "Jack Olabisi"  } ; 
            jack .  BooksAuthored .  Add  ( new   BookReply   { Title  =   "Early morning bird" [19659023]} ) ; 
            jack .  BooksAuthored .  Add  ( new   BookReply   { Title  =   "Fly me to Paris" } ) ; 
            auteurs .  Add  ( jack ) ; 
        } 

         public   override  Task  < AuthorResponse >   GetAuthor  ( AuthorRequest request  ServerCallContext context ) 
         {
             var  author  =  auteurs .  FirstOrDefault  ( x  = >  x .  Nom  ==  demande .  ] Nom ) ; 
             return  Task .  FromResult  ( author ) ; 
        } 
    } 
} 

Le AuthorService hérite de AuthorBase qui sera généré automatiquement à partir de la définition du service. Ensuite, vous remplacez la méthode GetAuthor fournie par la classe de base. Dans cette méthode, nous recherchons dans la liste des auteurs en mémoire et retournons celui qui correspond au nom dans le paramètre AuthorRequest .

Register the Service

L'étape suivante consiste à enregistrer le service dans la configuration de l'application dans StartUp.cs . Ouvrez StartUp.cs accédez à la méthode Configure et ajoutez l'instruction de code ci-dessous après la ligne 34 et sous l'enregistrement du service pour GreeterService :

 endpoints  ].  MapGrpcService  < AuthorService >   () ; 

Tester l'application

À ce stade, vous disposez de tous les code nécessaire pour servir les services gRPC et tester si cela fonctionne. Cependant, les services gRPC ne peuvent passer que par des clients gRPC. Pour la démonstration de ce blog, vous allez créer une application console qui appellera la méthode GetAuthor . Cependant, si vous créez l'application sur macOS ou Windows 7 et versions antérieures, Kestrel ne prend pas en charge HTTP / 2 avec TLS sur ces systèmes d'exploitation. Vous allez donc configurer un point de terminaison HTTP / 2 sans TLS dans Program.cs si vous utilisez l'un de ces systèmes d'exploitation.

Ouvrez Program.cs en ligne 23 et ajoutez l'instruction de code ci-dessous dans l'appel de méthode à ConfigureWebHostDefaults

  if   ( RuntimeInformation .  IsOSPlatform  ( OSPlatform .  OSX ) )   {
    webBuilder .  Configurer Kestrel  ( options  = > 
     {
        
        options .  ListenLocalhost  ( 5000  o  = >  o .  Protocols  = 
            HttpProtocols .  Http2 ) ; 
    } ) ; 
  } 

Puis ajoutez les instructions using suivantes:

  using  Microsoft .  AspNetCore .  Server .  Kestrel .  Core ; 
 using  System  using  System  ].  Runtime .  InteropServices ; 

Le code que vous avez ajouté permet de configurer un point de terminaison HTTP / 2 sans TLS pour Kestrel, si le programme s'exécute sous macOS. [19659007] Votre fichier Program.cs doit correspondre au code ci-dessous:

  using  System ; 
 using  System .  Collections .  Generic ; 
 using  System .  IO ; 
 using  System .  Linq  ; 
 en utilisant le système  .  Threading .  Tâches ; 
 avec  Microsoft .  AspNetCore .  Hébergement ; 
 avec  Microsoft  .  Extensions .  Hosting ; 
 using  Microsoft .  AspNetCore .  Server .  Kestrel .  Core ; 
 using  System .  Runtime .  InteropServices ; 

 namespace  GrpcAuthor
 {
     public   class   Program 
     {
         public   static   void   Main  ( string  [ ]]  args ) 
         {
             CreateHostBuilder  ( args ) .  Build  () ).  Exécutez  () ; 
        } 

        
        
         public   static  IHostBuilder  CreateHostBuilder  ( string  [ ]]  args )   = > 
            Hôte .  CreateDefaultBuilder  ( args ) 
                .  ConfigureWebHostDefaults  ( webBuilder  = > 
                 = > 
                 19659342] if   ( RuntimeInformation .  IsOSPlatform  ( OSPlatform .  OSX ) )   {
                     webBuilder .  ConfigurerKestrel  ( options  = > 
                      {
                         
                         options .  ListenLocalhost  ( 5000  o  = >  o .  Protocols  = 
                             HttpProtocols .  Http2 ) ; 
                     } ) ; 
                    } 

                    webBuilder .  UseStartup  < Startup >   () ; 
                } ) ; [19659086]} 
} 

Créez le client de console gRPC .NET

Ouvrez une autre instance de Visual Studio et créez un nouveau projet de console nommé GrpcAuthorClient . Vous pouvez également ajouter le nouveau projet au fichier de solution du projet précédent si vous le souhaitez. Si vous utilisez VS Code, ouvrez votre application de ligne de commande et exécutez dotnet new console -o GrpcAuthorClient puis code -r GrpcAuthorClient pour l'ouvrir dans VS Code.

Puis installez les packages NuGet requis. Pour les utilisateurs de Visual Studio, ouvrez la fenêtre Package Manager Console et exécutez:

 Install-Package Grpc.Net.Client
Package d'installation Google.Protobuf
Install-Package Grpc.Tools

Pour les utilisateurs de VS Code, ouvrez le terminal intégré et exécutez

 dotnet add GrpcAuthorClient.csproj package Grpc.Net.Client
dotnet ajouter le package GrpcAuthorClient.csproj Google.Protobuf
dotnet ajouter le package GrpcAuthorClient.csproj Grpc.Tools

Le package Grpc.Net.Client contient le client .NET Core, le package Google.Protobuf contient les API de message protobuf et la prise en charge des outils pour les fichiers protobuf se trouve dans le Package Grpc.Tools .

Créez un dossier Protos puis copiez et collez le fichier author.proto depuis le projet serveur.

Mise à jour option csharp_namespace valeur à GrpcAuthorClient .

Modifiez le fichier GrpcAuthorClient.csproj et ajoutez un groupe d'éléments avec un élément qui pointe vers author.proto :

 < ItemGroup > 
   < Protobuf   Include  =  " Protos  author.proto  "   GrpcServices  = "  Client  "   /> 
 </  ItemGroup >  [19659036]Ouvert  Program.cs  et mettre à jour la méthode  Main ()  ce code: 

  static   async  Task  Main  ( string  []  args ) 
 {
     var  serverAddress  =   "https: // localhost: 5001" ; [19659081] if   ( RuntimeInformation .  IsOSPlatform  ( OSPlatform .  OSX ) )   {
        
        AppContext .  SetSwitch  (
             "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport"   true ) ; 
        serverAddress  =   "http: // localhost: 5000" ; 
    } 

     using   var  channel  =  GrpcChannel . [19659094] ForAddress  ( serverAddress ) ; 
     var  client  =    new   Author .  AuthorClient  ( channel ) ; 
     var  reply  =   wait  client .  GetAuthorAsync  ( new [19659079] AuthorRequest   { Name  =   "Antonio Gonzalez"  } ) ; 

    Console .  WriteLine  ( "Auteur:"   +  réponse .  ToString  () ) ) [19659020]; 

    Console .  WriteLine  ( "Appuyez sur n'importe quelle touche pour quitter ..." ) ; 
    Console .  ReadKey  () ; 
} 

Le code crée GrpcChannel avec l'adresse du serveur. S'il s'exécute sur macOS, il configure l'application pour utiliser une connexion HTTP / 2 non sécurisée et définit l'URL du serveur sur l'URL HTTP non sécurisée. Si vous utilisez .NET 5, vous n’avez pas besoin de cette configuration supplémentaire. Il vous suffit de vous assurer que vous utilisez Grpc.Net.Client version 2.32.0 ou ultérieure.

L'objet GrpcChannel est ensuite utilisé pour instancier le AuthorClient . L'objet client est ensuite utilisé pour effectuer un appel asynchrone à l'aide de la méthode GetAuthorAsync . Lorsque le serveur répond, le résultat est imprimé sur la console.

Ajoutez les instructions using suivantes au fichier.

  using  System .  Net .  ] Http ; 
 utilisant le système  .  Threading .  Tasks ; 
 using  Grpc .  Net .  Client ; 
 using  System .  Runtime .  InteropServices ; 

Vous êtes maintenant prêt à tester le service. Démarrez d'abord le projet serveur en exécutant dotnet run dans le terminal intégré dans VS Code ou appuyez sur Ctrl + F5 pour exécuter sans le débogueur dans Visual Studio. Au démarrage du serveur, exécutez le projet client GrpcAuthorClient . Vous devriez obtenir le résultat suivant:

 Auteur:  {  "name" :   "Antonio Gonzalez"  "booksAuthored" :   [  {  "title" :   "Beaucoup de bruit pour rien"  }  {  "title" :   " Comment faire une scission " }  ]  } 

Appuyez sur n'importe quelle touche pour quitter  .. .

Résumé

gRPC est un framework RPC hautes performances avec des fonctionnalités d'authentification et d'équilibrage de charge enfichables. Vous définissez la manière dont vous souhaitez que vos données soient structurées à l'aide de tampons de protocole. Vous pouvez ensuite utiliser du code source généré automatiquement pour écrire et lire facilement vos données structurées vers et depuis divers flux de données et dans divers langages.

Dans cet article, vous avez appris à définir une interface de service à l'aide du tampon de protocole (version 3) et implémentez également le service en C #. En fin de compte, vous avez appris à créer un client gRPC et à appeler les méthodes sur le serveur.

Vous pouvez trouver le code source de ce message sur GitHub .

Ressources supplémentaires

  1. Protocole Buffer Language Guide
  2. gRPC docs
  3. Pourquoi Microsoft recommande gRPC aux développeurs WCF migrant vers .NET Core ou .NET 5
  4. Comment faire Ajouter gRPC à votre application Blazor




Source link

février 10, 2021 gRPC