grpc clib Networking / RPC

gRPC remote procedure calls for PascalAI. Call remote server methods as local functions over HTTP/2 — unary calls, server streaming, client streaming, and bidirectional streaming with TLS and metadata support.

ppm install grpc

Overview

grpc wraps libgrpc — Google's open-source RPC framework built on HTTP/2. It uses Protocol Buffers for efficient binary serialization and supports four communication patterns: unary (one request, one response), server streaming, client streaming, and bidirectional streaming.

You compile your .proto service definitions with protoc to generate the serialized bytes, then call the gRPC methods directly from PascalAI. The library handles framing, flow control, multiplexing, and TLS negotiation for you.

CLib package

Requires libgrpc-dev and protobuf-compiler. Ubuntu/Debian: sudo apt install libgrpc-dev protobuf-compiler

Quick Start

Unary call (like a regular function)

uses grpc;

var ch := NewChannel('api.example.com:50051');

{ Call /helloworld.Greeter/SayHello with serialized proto bytes }
var resp := UnaryCall(ch, '/helloworld.Greeter/SayHello', requestBytes, 5000);
WriteLn('Response: ' + IntToStr(Length(resp)) + ' bytes');

CloseChannel(ch);

Server streaming (receive a stream of responses)

uses grpc;

var ch := NewChannelTLS('streaming.example.com:443');
var call := ServerStreamCall(ch, '/chat.Service/Subscribe', subRequestBytes, 30000);

var msg := StreamRead(call);
while msg <> '' do
begin
  WriteLn('Received: ' + IntToStr(Length(msg)) + ' bytes');
  msg := StreamRead(call);
end;

var status := GetCallStatus(call);
WriteLn('Status: ' + IntToStr(status.Code));
CloseCall(call);
CloseChannel(ch);

Channel API

Channels represent a connection to a gRPC server. Reuse channels across multiple calls — creating a channel is expensive as it involves TCP handshake and optional TLS negotiation.

FunctionDescription
NewChannel(target)Open an insecure channel to host:port
NewChannelTLS(target)Open a TLS-secured channel (port 443 typical)
NewChannelCreds(target, certFile, keyFile, caFile)Mutual TLS with client certificate
SetChannelTimeout(ch, ms)Default deadline in milliseconds for all calls on this channel
CloseChannel(ch)Shut down the channel and release its resources
ChannelState(ch)Returns connectivity state: 0=Idle, 1=Connecting, 2=Ready, 3=TransientFailure, 4=Shutdown

Unary RPC API

One request message, one response message. The simplest and most common call type.

FunctionDescription
UnaryCall(ch, method, reqBytes, timeoutMs)Send reqBytes and return response bytes. Blocks until reply or timeout.
UnaryCallMeta(ch, method, reqBytes, metadata, timeoutMs)Same with request metadata (key/value pairs sent as HTTP/2 headers)
GetLastMetadata(ch)Returns server trailing metadata from the most recent call as a newline-delimited string
uses grpc;

var ch := NewChannel('users.internal:50051');

{ Attach auth token as metadata }
var meta := BuildMetadata(['authorization', 'Bearer eyJhbGci...',
                             'x-request-id',   'req-abc-123']);

var resp := UnaryCallMeta(ch, '/users.UserService/GetUser', reqBytes, meta, 3000);
WriteLn(Length(resp), ' bytes received');
CloseChannel(ch);

Server Streaming API

Client sends one request; server sends back a stream of response messages. Use for subscriptions, log tailing, large result sets.

FunctionDescription
ServerStreamCall(ch, method, reqBytes, timeoutMs)Start a server-streaming RPC, returns a call handle
ServerStreamCallMeta(ch, method, reqBytes, metadata, timeoutMs)Same with metadata
StreamRead(call)Read the next message bytes. Returns empty string when the stream ends.
StreamReadTimeout(call, ms)Read next message with a per-read deadline
GetCallStatus(call)Returns a TGrpcStatus record with Code and Message
CloseCall(call)Cancel and release the call handle

Client Streaming API

Client sends a stream of request messages; server replies once after the stream is complete. Use for batch uploads, aggregation.

FunctionDescription
ClientStreamStart(ch, method, timeoutMs)Open a client-streaming call, returns a writer handle
ClientStreamWrite(call, msgBytes)Send one message to the server
ClientStreamFinish(call)Signal end-of-stream and block until server response. Returns response bytes.
uses grpc;

var ch := NewChannel('ingest.example.com:50051');
var call := ClientStreamStart(ch, '/logs.Ingest/PushEvents', 15000);

for var i := 0 to Length(events) - 1 do
  ClientStreamWrite(call, events[i]);

var ack := ClientStreamFinish(call);
WriteLn('Server ack: ' + Length(ack).ToString + ' bytes');
CloseChannel(ch);

Bidirectional Streaming API

Both sides send streams of messages independently. Use for real-time chat, audio streaming, collaborative editing.

FunctionDescription
BidiStreamStart(ch, method, timeoutMs)Open a bidirectional streaming call
BidiWrite(call, msgBytes)Send one message to the server
BidiRead(call)Read next server message. Returns empty string when server half-closes.
BidiWriteDone(call)Half-close the write side (signals end of client stream)
BidiClose(call)Cancel and release the call

Metadata API

Metadata is gRPC's equivalent of HTTP headers — key/value string pairs sent alongside calls. Keys should be lowercase; binary values use the -bin suffix convention.

FunctionDescription
BuildMetadata(pairs)Build a metadata string from a flat array of key/value pairs
GetLastMetadata(ch)Server trailing metadata from the last completed call
ParseMetadata(raw)Parse raw metadata string into a list of key=value entries

Server API

Host a gRPC server inside your PascalAI program. Register handlers and serve requests on a port.

FunctionDescription
NewServer(port)Create an insecure server listening on the given port
NewServerTLS(port, certFile, keyFile)Create a TLS server
RegisterUnaryHandler(srv, method, handler)Register a handler for a unary method. Handler signature: function(reqBytes): TBytes
RegisterStreamHandler(srv, method, handler)Register a server-streaming handler
StartServer(srv)Begin accepting connections (blocking)
StopServer(srv)Gracefully stop the server
uses grpc;

var srv := NewServer(50051);

RegisterUnaryHandler(srv, '/hello.Greeter/SayHello',
  function(req: TBytes): TBytes begin
    { Deserialize req, build response proto bytes }
    Result := BuildHelloReply('Hello, world!');
  end);

WriteLn('Serving on :50051');
StartServer(srv);

gRPC Status Codes

Every gRPC call completes with a status code. Check GetCallStatus(call).Code after streaming calls, or catch an exception on unary failures.

CodeNameMeaning
0OKSuccess
1CancelledClient cancelled the call
2UnknownServer returned an unrecognized error
3InvalidArgumentClient sent a bad argument
4DeadlineExceededTimeout elapsed before completion
5NotFoundRequested entity not found
7PermissionDeniedNo permission to execute the call
8ResourceExhaustedQuota exceeded or server overloaded
12UnimplementedMethod not implemented on server
14UnavailableServer temporarily unavailable (retry-able)
16UnauthenticatedRequest not authenticated

Key Concepts

HTTP/2 transport

gRPC runs exclusively over HTTP/2, which provides multiplexed streams over a single TCP connection. Multiple concurrent RPCs share one connection with no head-of-line blocking. This makes gRPC dramatically faster than REST for high-frequency calls.

Protocol Buffers

gRPC uses Protocol Buffers for message encoding by default. Compile your .proto files with protoc to get serialization helpers. The grpc package works with raw TBytes so you can use any serializer, but protobuf gives the best performance and cross-language compatibility.

Service types at a glance

PatternClient sendsServer sendsTypical use
Unary1 message1 messageCRUD, lookups
Server streaming1 messageN messagesSubscriptions, exports
Client streamingN messages1 messageBatch uploads, aggregation
BidirectionalN messagesN messagesChat, audio, live sync
Tip — connection reuse

Create one channel per server endpoint at startup and reuse it for all calls. Channels are thread-safe and handle reconnection automatically on Unavailable (status 14) errors.

Package Info

Version1.0.0
Typeclib
C Librarylibgrpc-dev
Authorgustavo

System Requirements

libgrpc-dev
protobuf-compiler

Ubuntu/Debian:
sudo apt install libgrpc-dev protobuf-compiler

TGrpcStatus

.Code — integer status code
.Message — human-readable error
.IsOK — True when Code = 0

Functions

  • NewChannel / NewChannelTLS
  • NewChannelCreds
  • CloseChannel / ChannelState
  • SetChannelTimeout
  • UnaryCall / UnaryCallMeta
  • ServerStreamCall
  • ServerStreamCallMeta
  • StreamRead / StreamReadTimeout
  • GetCallStatus / CloseCall
  • ClientStreamStart
  • ClientStreamWrite
  • ClientStreamFinish
  • BidiStreamStart
  • BidiWrite / BidiRead
  • BidiWriteDone / BidiClose
  • BuildMetadata
  • GetLastMetadata
  • ParseMetadata
  • NewServer / NewServerTLS
  • RegisterUnaryHandler
  • RegisterStreamHandler
  • StartServer / StopServer

See Also