Servizi gRPC con C#

Questo documento descrive i concetti necessari per scrivere app gRPC in C#. Gli argomenti trattati di seguito si applicano sia alle app GRPC basate su C che a ASP.NET basate su core.

file proto

gRPC usa un approccio con priorità al contratto ("contract-first") per lo sviluppo di API. I buffer di protocollo (protobuf) vengono usati come IDL (Interface Definition Language) per impostazione predefinita. Il .proto file contiene:

  • Definizione del servizio gRPC.
  • Messaggi inviati tra client e server.

Per altre informazioni sulla sintassi dei file protobuf, vedere Creare messaggi Protobuf per le app .NET.

Si consideri ad esempio il file greet.proto usato in Introduzione al servizio gRPC:

  • Definisce un Greeter servizio.
  • Il Greeter servizio definisce una SayHello chiamata.
  • SayHello invia un HelloRequest messaggio e riceve un HelloReply messaggio:
syntax = "proto3";

option csharp_namespace = "GrpcGreeter";

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

Per visualizzare i commenti del codice tradotti in lingue diverse dall'inglese, segnalarlo in questo problema di discussione su GitHub.

Aggiungere un .proto file a un'app C#

Il .proto file è incluso in un progetto aggiungendolo al <Protobuf> gruppo di elementi:

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

Per impostazione predefinita, un <Protobuf> riferimento genera un client concreto e una classe di base del servizio. L'attributo dell'elemento di riferimento può essere usato per limitare la generazione di GrpcServices asset C#. Le opzioni valide GrpcServices sono:

  • Both (impostazione predefinita, se non presente)
  • Server
  • Client
  • None

Supporto degli strumenti C# per i file .proto

Il pacchetto di strumenti Grpc.Tools è necessario per generare gli asset C# dai .proto file. Asset generati (file):

  • Vengono generati in base alle esigenze ogni volta che viene compilato il progetto.
  • Non vengono aggiunti al progetto o controllati nel controllo del codice sorgente.
  • Sono un artefatto di compilazione contenuto nella directory obj .

Questo pacchetto è obbligatorio sia per i progetti server che per i progetti client. Il Grpc.AspNetCore metapacchetto include un riferimento a Grpc.Tools. I progetti server possono aggiungere Grpc.AspNetCore usando il Gestione pacchetti in Visual Studio o aggiungendo un <PackageReference> oggetto al file di progetto:

<PackageReference Include="Grpc.AspNetCore" Version="2.32.0" />

I progetti client devono fare riferimento Grpc.Tools direttamente insieme agli altri pacchetti necessari per usare il client gRPC. Il pacchetto di strumenti non è necessario in fase di esecuzione, quindi la dipendenza è contrassegnata con PrivateAssets="All":

<PackageReference Include="Google.Protobuf" Version="3.18.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.40.0">
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
  <PrivateAssets>all</PrivateAssets>
</PackageReference>

Asset C# generati

Il pacchetto di strumenti genera i tipi C# che rappresentano i messaggi definiti nei file inclusi .proto .

Per gli asset lato server, viene generato un tipo di base del servizio astratto. Il tipo di base contiene le definizioni di tutte le chiamate gRPC contenute nel .proto file. Creare un'implementazione concreta del servizio che deriva da questo tipo di base e implementa la logica per le chiamate gRPC. Per , l'esempio greet.protodescritto in precedenza, viene generato un tipo astratto GreeterBase che contiene un metodo virtuale SayHello . Un'implementazione concreta esegue l'override GreeterService del metodo e implementa la logica che gestisce la chiamata gRPC.

public class GreeterService : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }

    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}

Per gli asset lato client, viene generato un tipo di client concreto. Le chiamate gRPC nel .proto file vengono convertite in metodi sul tipo concreto, che può essere chiamato. Per , l'esempio greet.protodescritto in precedenza, viene generato un tipo concreto GreeterClient . Chiamare GreeterClient.SayHelloAsync per avviare una chiamata gRPC al server.

// The port number must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:7042");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
                  new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();

Per impostazione predefinita, gli asset server e client vengono generati per ogni .proto file incluso nel <Protobuf> gruppo di elementi. Per assicurarsi che vengano generati solo gli asset del server in un progetto server, l'attributo GrpcServices è impostato su Server.

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

Analogamente, l'attributo è impostato su Client nei progetti client.

Risorse aggiuntive

Questo documento descrive i concetti necessari per scrivere app gRPC in C#. Gli argomenti trattati di seguito si applicano sia alle app GRPC basate su C che a ASP.NET basate su core.

file proto

gRPC usa un approccio con priorità al contratto ("contract-first") per lo sviluppo di API. I buffer di protocollo (protobuf) vengono usati come IDL (Interface Definition Language) per impostazione predefinita. Il .proto file contiene:

  • Definizione del servizio gRPC.
  • Messaggi inviati tra client e server.

Per altre informazioni sulla sintassi dei file protobuf, vedere Creare messaggi Protobuf per le app .NET.

Si consideri ad esempio il file greet.proto usato in Introduzione al servizio gRPC:

  • Definisce un Greeter servizio.
  • Il Greeter servizio definisce una SayHello chiamata.
  • SayHello invia un HelloRequest messaggio e riceve un HelloReply messaggio:
syntax = "proto3";

option csharp_namespace = "GrpcGreeter";

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

Per visualizzare i commenti del codice tradotti in lingue diverse dall'inglese, segnalarlo in questo problema di discussione su GitHub.

Aggiungere un .proto file a un'app C#

Il .proto file è incluso in un progetto aggiungendolo al <Protobuf> gruppo di elementi:

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

Per impostazione predefinita, un <Protobuf> riferimento genera un client concreto e una classe di base del servizio. L'attributo dell'elemento di riferimento può essere usato per limitare la generazione di GrpcServices asset C#. Le opzioni valide GrpcServices sono:

  • Both (impostazione predefinita, se non presente)
  • Server
  • Client
  • None

Supporto degli strumenti C# per i file .proto

Il pacchetto di strumenti Grpc.Tools è necessario per generare gli asset C# dai .proto file. Asset generati (file):

  • Vengono generati in base alle esigenze ogni volta che viene compilato il progetto.
  • Non vengono aggiunti al progetto o controllati nel controllo del codice sorgente.
  • Sono un artefatto di compilazione contenuto nella directory obj .

Questo pacchetto è obbligatorio sia per i progetti server che per i progetti client. Il Grpc.AspNetCore metapacchetto include un riferimento a Grpc.Tools. I progetti server possono aggiungere Grpc.AspNetCore usando il Gestione pacchetti in Visual Studio o aggiungendo un <PackageReference> oggetto al file di progetto:

<PackageReference Include="Grpc.AspNetCore" Version="2.28.0" />

I progetti client devono fare riferimento Grpc.Tools direttamente insieme agli altri pacchetti necessari per usare il client gRPC. Il pacchetto di strumenti non è necessario in fase di esecuzione, quindi la dipendenza è contrassegnata con PrivateAssets="All":

<PackageReference Include="Google.Protobuf" Version="3.11.4" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.28.1">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

Asset C# generati

Il pacchetto di strumenti genera i tipi C# che rappresentano i messaggi definiti nei file inclusi .proto .

Per gli asset lato server, viene generato un tipo di base del servizio astratto. Il tipo di base contiene le definizioni di tutte le chiamate gRPC contenute nel .proto file. Creare un'implementazione concreta del servizio che deriva da questo tipo di base e implementa la logica per le chiamate gRPC. Per , l'esempio greet.protodescritto in precedenza, viene generato un tipo astratto GreeterBase che contiene un metodo virtuale SayHello . Un'implementazione concreta esegue l'override GreeterService del metodo e implementa la logica che gestisce la chiamata gRPC.

public class GreeterService : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }

    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}

Per gli asset lato client, viene generato un tipo di client concreto. Le chiamate gRPC nel .proto file vengono convertite in metodi sul tipo concreto, che può essere chiamato. Per , l'esempio greet.protodescritto in precedenza, viene generato un tipo concreto GreeterClient . Chiamare GreeterClient.SayHelloAsync per avviare una chiamata gRPC al server.

static async Task Main(string[] args)
{
    // The port number(5001) must match the port of the gRPC server.
    using var channel = GrpcChannel.ForAddress("https://localhost:5001");
    var client = new Greeter.GreeterClient(channel);
    var reply = await client.SayHelloAsync(
                      new HelloRequest { Name = "GreeterClient" });
    Console.WriteLine("Greeting: " + reply.Message);
    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
}

Per impostazione predefinita, gli asset server e client vengono generati per ogni .proto file incluso nel <Protobuf> gruppo di elementi. Per assicurarsi che vengano generati solo gli asset del server in un progetto server, l'attributo GrpcServices è impostato su Server.

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

Analogamente, l'attributo è impostato su Client nei progetti client.

Risorse aggiuntive