Het component TsgcGRPCClient brengt gRPC naar Delphi en C++Builder zonder enige externe runtime. Het maakt deel uit van de sgcWebSockets Enterprise-editie en draait op Windows, macOS, Linux, iOS en Android. Deze gids legt uit hoe de client werkt, hoe je hem configureert en hoe je elk van de vier gRPC-aanroeptypen vanuit Delphi uitvoert.
Hoe het werkt
gRPC bestaat uit Protocol Buffers-berichten die in frames over HTTP/2 worden verstuurd. Elk bericht wordt als een payload met lengteprefix op een HTTP/2-stream verzonden, het verzoek bevat headers zoals content-type: application/grpc en grpc-timeout, en de uiteindelijke status komt aan als de grpc-status- en grpc-message-trailers.
sgcWebSockets bevat al een complete HTTP/2-stack, dus TsgcGRPCClient draait bovenop een TsgcHTTP2Client-transport. Je geeft het je geserialiseerde verzoekbytes, het verzorgt het framen, de headers en de timeout, opent de HTTP/2-stream en parseert het antwoord en de trailers terug naar een getypeerde TsgcGRPCResponse. Omdat de client met ruwe TBytes werkt, kun je het combineren met elke Protocol Buffers-bibliotheek die je al gebruikt.
De client opzetten
Een gRPC-channel is een HTTP/2-verbinding. Maak een TsgcHTTP2Client aan, wijs hem naar de host en poort, en ken hem vervolgens toe aan de Client-eigenschap van het gRPC-component. Voor TLS gebruikt de HTTP/2-client OpenSSL of Windows SChannel; voor een lokale plaintext-server (h2c) zet je TLS op False.
uses
sgcHTTP2, sgcGRPC_Client, sgcGRPC_Classes, sgcGRPC_Types;
var
HTTP2: TsgcHTTP2Client;
GRPC: TsgcGRPCClient;
begin
HTTP2 := TsgcHTTP2Client.Create(nil);
HTTP2.Host := 'grpc.example.com';
HTTP2.Port := 443;
HTTP2.TLS := True; // False for a local h2c server
HTTP2.TLSOptions.IOHandler := iohOpenSSL; // or iohSChannel on Windows
GRPC := TsgcGRPCClient.Create(nil);
GRPC.Client := HTTP2;
end;
Het channel configureren
Channel-brede instellingen bevinden zich in ChannelOptions. Je kunt per-bericht gzip-compressie inschakelen, het wire-contenttype kiezen en de limieten voor bericht- en metadatagrootte verhogen.
// gzip-compress outgoing messages
GRPC.ChannelOptions.Compression := grpcGzip; // grpcNoCompression, grpcGzip, grpcDeflate, grpcSnappy
// application/grpc+proto (default) or application/grpc+json
GRPC.ChannelOptions.ContentType := grpcProto; // or grpcJSON
// raise the limits for large messages
GRPC.ChannelOptions.MaxMessageSize := 16 * 1024 * 1024;
GRPC.ChannelOptions.MaxMetadataSize := 64 * 1024;
Metadata en authenticatie
Aangepaste headers reizen mee als gRPC-metadata. Voeg ze toe aan DefaultMetadata om ze bij elke aanroep te versturen, wat de gebruikelijke plaats is voor een autorisatietoken of een tracing-header.
GRPC.DefaultMetadata.Add('authorization', 'Bearer eyJ...');
GRPC.DefaultMetadata.Add('x-api-key', 'my-api-key');
Deadlines en annulering
Een timeout per aanroep wordt verstuurd als de standaard grpc-timeout-header, zodat de server op hetzelfde moment kan opgeven als je client. Een lopende streaming-aanroep kan op elk moment worden gestopt met CancelCall, door de stream-id mee te geven die werd teruggegeven toen de stream werd geopend.
Unary-aanroepen
Een unary-aanroep verstuurt één verzoek en ontvangt één antwoord. Call blokkeert totdat het antwoord binnenkomt en geeft een TsgcGRPCResponse terug met de StatusCode, StatusMessage, de ruwe Data-bytes (of DataString) en de Trailers.
var
oResponse: TsgcGRPCResponse;
begin
oResponse := GRPC.Call('helloworld.Greeter', 'SayHello', RequestBytes);
if oResponse.StatusCode = grpcOK then
Memo1.Text := oResponse.DataString
else
ShowMessage('gRPC error ' + oResponse.StatusMessage);
end;
Om de gebruikersinterface responsief te houden, gebruik je CallAsync. Die keert meteen terug en levert het antwoord via het OnGRPCResponse-event.
GRPC.OnGRPCResponse := GRPCResponse;
GRPC.CallAsync('helloworld.Greeter', 'SayHello', RequestBytes);
procedure TForm1.GRPCResponse(Sender: TObject; const Response: TsgcGRPCResponse);
begin
if Response.StatusCode = grpcOK then
Memo1.Text := Response.DataString;
end;
Server-streaming
Bij server-streaming verstuur je één verzoek en geeft de server een stroom berichten terug. Elk bericht roept OnGRPCStreamMessage op, en OnGRPCStreamEnd wordt eenmaal geactiveerd met de uiteindelijke status.
GRPC.OnGRPCStreamMessage := GRPCStreamMessage;
GRPC.OnGRPCStreamEnd := GRPCStreamEnd;
GRPC.ServerStreamingCall('chat.Feed', 'Subscribe', RequestBytes);
procedure TForm1.GRPCStreamMessage(Sender: TObject; aStreamId: Integer;
const aData: TBytes);
begin
Memo1.Lines.Add(DecodeMessage(aData));
end;
Client-streaming
Client-streaming is het spiegelbeeld: jij stuurt een stroom berichten en de server antwoordt eenmaal. Open de stream, verstuur elk bericht en sluit hem vervolgens om het enkele antwoord te lezen.
var
vStreamId: Integer;
oResponse: TsgcGRPCResponse;
begin
vStreamId := GRPC.OpenClientStream('upload.Service', 'Send');
GRPC.SendStreamMessage(vStreamId, ChunkBytes1);
GRPC.SendStreamMessage(vStreamId, ChunkBytes2);
oResponse := GRPC.CloseClientStream(vStreamId);
if oResponse.StatusCode = grpcOK then
ShowMessage('Upload accepted');
end;
Bidirectionele streaming
Bidirectionele streaming voert een full-duplex uitwisseling uit over één enkele HTTP/2-stream: beide kanten versturen wanneer ze willen. Open de stream, verstuur berichten zoals nodig, verwerk binnenkomende berichten in OnGRPCStreamMessage en sluit af wanneer je klaar bent.
var
vStreamId: Integer;
begin
vStreamId := GRPC.OpenBidiStream('chat.Room', 'Connect');
GRPC.SendBidiMessage(vStreamId, EncodeMessage('hello'));
// ... incoming messages arrive on OnGRPCStreamMessage ...
GRPC.CloseBidiStream(vStreamId);
end;
Statuscodes en foutafhandeling
Elk antwoord bevat een getypeerde StatusCode van grpcOK tot en met de standaard gRPC-set (grpcNOT_FOUND, grpcUNAVAILABLE, grpcDEADLINE_EXCEEDED, grpcUNAUTHENTICATED en de rest). Voor asynchrone en streaming-aanroepen meldt OnGRPCError een gRPC-status die niet OK is, en OnGRPCException meldt een transport- of verbindingsfout.
GRPC.OnGRPCError := GRPCError;
procedure TForm1.GRPCError(Sender: TObject; aStreamId: Integer;
aStatusCode: TsgcGRPCStatusCode; const aStatusMessage: string);
begin
Memo1.Lines.Add(Format('gRPC error %d: %s', [Ord(aStatusCode), aStatusMessage]));
end;
Automatische retry
De client kan mislukte aanroepen voor je opnieuw proberen. Schakel RetryPolicy in, stel het aantal pogingen en de backoff in en geef de statuscodes op die een retry moeten activeren. Dit is de typische configuratie voor tijdelijke grpcUNAVAILABLE-fouten.
GRPC.RetryPolicy.Enabled := True;
GRPC.RetryPolicy.MaxAttempts := 4;
GRPC.RetryPolicy.InitialBackoff := 200; // ms
GRPC.RetryPolicy.BackoffMultiplier := 2.0;
GRPC.RetryPolicy.RetryableStatusCodes :=
GRPC.RetryPolicy.RetryableStatusCodes + [grpcUNAVAILABLE, grpcRESOURCE_EXHAUSTED];
Voor overkoepelende logica zoals logging of het verversen van een token voeg je een vermelding toe aan de Interceptors-keten, die elke aanroep op één plek omvat.
Hoe nu verder
Bovenop deze generieke client levert sgcWebSockets getypeerde clients voor de gRPC-diensten van Google Cloud (Pub/Sub, Speech-to-Text, Translation, Vision, Natural Language, Cloud Storage, BigQuery en Vertex AI), zodat je methoden op hoog niveau aanroept in plaats van handmatig protobufs samen te stellen. Een direct uitvoerbaar voorbeeld vind je in Demos\21.GRPC\01.GRPC_Client, en de volledige referentie staat op de productpagina van de gRPC-client.
Vragen of hulp nodig bij het beginnen? Neem contact op. Je krijgt antwoord van de mensen die de code geschreven hebben.
