Zum Inhalt springen
Deutsch

gRPC

Das Framework stellt zwei Actor-Klassen für gRPC bereit:

KlasseRolle
GrpcServerActorHostet einen gRPC-Server; stellt Service-Methoden bereit.
GrpcClientActorVerbindet sich mit einem Remote-gRPC-Service; ruft Methoden auf.

Beide umschließen @grpc/grpc-js. Nützlich, wenn du Protobuf-typisierte Verträge hast und den Broker-Actor- Lifecycle (Reconnect, Buffer, Subscriber-Fan-out) für clientseitige Aufrufe willst.

import { ActorSystem, Props, GrpcServerActor } from 'actor-ts';
const server = system.spawn(
Props.create(() => new GrpcServerActor({
host: '0.0.0.0',
port: 50051,
services: [
{
protoPath: './proto/orders.proto',
serviceName: 'orders.v1.OrderService',
handler: orderHandlerRef, // Actor, der eingehende Calls verarbeitet
},
],
})),
'grpc-server',
);

Eingehende RPC-Calls werden als Actor-Nachrichten an handler weitergeleitet. Das Framework deserialisiert das Protobuf-Payload und verpackt es in ein Envelope.

import { GrpcClientActor } from 'actor-ts';
const client = system.spawn(
Props.create(() => new GrpcClientActor({
target: 'orders.svc:50051',
protoPath: './proto/orders.proto',
serviceName: 'orders.v1.OrderService',
})),
'orders-client',
);
// Einen unären Call absetzen:
client.tell({
kind: 'unary',
method: 'GetOrder',
request: { id: 'order-42' },
replyTo: this.self,
});
// Die Antwort empfangen:
override onReceive(msg: GrpcReply) {
if (msg.kind === 'reply') handleOrder(msg.response);
if (msg.kind === 'error') handleError(msg.error);
}

Der Actor übernimmt Verbindungsmanagement, Retries und das Routen der Antwort an den Anfragenden.

gRPC unterstützt vier Call-Typen; das Framework deckt alle ab:

TypClient sendetServer liefert
UnärEinen RequestEine Response
Server-StreamingEinen RequestStream von Responses
Client-StreamingStream von RequestsEine Response
Bidirektionales StreamingStream von RequestsStream von Responses
// Server-Streaming:
client.tell({
kind: 'server-stream',
method: 'WatchOrders',
request: { customerId: '42' },
subscriber: streamHandler, // bekommt jede Response
});
// Bidirektional:
client.tell({
kind: 'bidi-stream',
method: 'Chat',
subscriber: chatHandler,
});
// Nachrichten in den Stream senden:
client.tell({ kind: 'stream-send', method: 'Chat', message: { text: 'hello' } });

Streams bleiben offen, bis eine Seite sie schließt oder der Actor stoppt.

new GrpcServerActor({
host: '0.0.0.0',
port: 50051,
tls: {
cert: fs.readFileSync('./server.crt'),
key: fs.readFileSync('./server.key'),
},
services: [...],
});
new GrpcClientActor({
target: 'orders.svc:50051',
tls: {
ca: fs.readFileSync('./ca.crt'),
},
...
});

Standard-TLS-Konfiguration über cert / key / ca. Für Mutual TLS (mTLS) gib das Cert + Key des Clients an.

Terminal-Fenster
npm install @grpc/grpc-js @grpc/proto-loader
# oder: bun add @grpc/grpc-js @grpc/proto-loader

Beide Pakete sind Peer-Dependencies.

Zwei primäre Einsatzfälle:

  1. Service-zu-Service innerhalb eines Clusters, wenn Protobuf-typisierte Verträge für Evolution wichtig sind.
  2. Externe Clients, die bereits gRPC sprechen (Mobile-Apps, Services in anderen Sprachen).

Für interne Actor-zu-Actor-Kommunikation innerhalb eines Clusters ist der Cluster-Transport besser — direkt über TypeScript typisiert, kein Protobuf erforderlich. gRPC ist für sprachübergreifende oder externe Vertrags-Fälle.