gRPC für C# (.NET): Bibliotheken und Beispiele
gRPC ist ein modernes, hochleistungsfähiges Framework für entfernte Prozeduraufrufe (RPC), entwickelt von Google. Es verwendet HTTP/2 für den Transport und Protocol Buffers (protobuf) für die Datenserialisierung. Im .NET-Ökosystem ist gRPC zum wichtigsten Werkzeug für den Aufbau einer Microservice-Architektur geworden, das strenge Typisierung, bidirektionales Streaming und niedrige Latenz bietet. In diesem Artikel betrachten wir die wichtigsten Bibliotheken für die Arbeit mit gRPC in C# und geben praktische Beispiele.
Wichtige Bibliotheken für gRPC in .NET
Für die Arbeit mit gRPC in .NET werden die folgenden NuGet-Pakete verwendet:
- Grpc.Net.Client — Client-Bibliothek zum Erstellen von gRPC-Clients. Arbeitet auf Basis von HttpClient und unterstützt alle Aufrufarten: Unary, Server Streaming, Client Streaming und Bidirectional Streaming.
- Grpc.AspNetCore.Server — Server-Bibliothek zur Integration von gRPC in ASP.NET Core. Ermöglicht das Hosting von gRPC-Diensten zusammen mit gewöhnlichen REST-APIs.
- Google.Protobuf — Bibliothek für die Arbeit mit Protocol Buffers, Generierung und Deserialisierung von Nachrichten.
- Grpc.Tools — Sammlung von Werkzeugen zur automatischen Generierung von C#-Code aus .proto-Dateien während des Projektbuilds.
Der Entwicklungsprozess umfasst drei Phasen: Beschreibung des Dienstes in einer .proto-Datei, Codegenerierung und Implementierung von Server/Client.
Beispiel 1: Einfacher Unary-Dienst (Anfrage-Antwort)
Wir erstellen einen einfachen Dienst zum Abrufen von Benutzerinformationen. Dazu definieren wir die Datei user.proto:
syntax = "proto3";
package user;
service UserService { rpc GetUser (UserRequest) returns (UserResponse);}
message UserRequest { int32 id = 1;}
message UserResponse { string name = 1; string email = 2; int32 age = 3;}Fügen Sie dem Projekt Verweise auf die Pakete und die .proto-Datei hinzu. Nach dem Build werden die Klassen UserRequest, UserResponse und die Basisklasse UserServiceBase generiert.
Server-Implementierung
using Grpc.Core;using User;
public class UserServiceImpl : UserService.UserServiceBase{ public override Task<UserResponse> GetUser(UserRequest request, ServerCallContext context) { var user = new UserResponse { Name = "Ivan Petrov", Email = "ivan@example.com", Age = 30 }; return Task.FromResult(user); }}Serverstart in ASP.NET Core:
var builder = WebApplication.CreateBuilder(args);builder.Services.AddGrpc();var app = builder.Build();app.MapGrpcService<UserServiceImpl>();app.Run();Client-Implementierung
using Grpc.Net.Client;using User;
var channel = GrpcChannel.ForAddress("https://localhost:5001");var client = new UserService.UserServiceClient(channel);
var response = await client.GetUserAsync(new UserRequest { Id = 1 });Console.WriteLine($"Benutzer: {response.Name}, E-Mail: {response.Email}");Beispiel 2: Server-Streaming (Server Streaming)
Server-Streaming ist nützlich, wenn viele Daten an den Client gesendet werden müssen, z. B. eine Liste von Ereignissen oder Logs. Ergänzen wir unsere .proto-Datei:
service UserService { rpc GetUser (UserRequest) returns (UserResponse); rpc ListUsers (Empty) returns (stream UserResponse);}
message Empty {}Server-Implementierung:
public override async Task ListUsers(Empty request, IServerStreamWriter<UserResponse> responseStream, ServerCallContext context){ var users = new List<UserResponse> { new UserResponse { Name = "Anna", Email = "anna@test.com" }, new UserResponse { Name = "Boris", Email = "boris@test.com" } };