gRPC für JavaScript (Node.js): Bibliotheken und Beispiele
\n\ngRPC ist ein von Google entwickeltes Hochleistungs-Framework für entfernte Prozeduraufrufe (RPC). Es verwendet Protocol Buffers (protobuf) zur Datenserialisierung und HTTP/2 für den Transport. In der Node.js-Ökosystem ermöglicht gRPC die Erstellung zuverlässiger Mikroservices mit strenger Typisierung, Unterstützung für Streaming und bidirektionale Kommunikation. In diesem Artikel betrachten wir die wichtigsten Bibliotheken für die Arbeit mit gRPC in JavaScript (Node.js) und analysieren ein praktisches Beispiel für Server und Client.
\n\nWichtigste Bibliotheken für gRPC in Node.js
\n\nFür die Arbeit mit gRPC in Node.js werden zwei Hauptpakete verwendet:
\n\n- \n
- @grpc/grpc-js — eine reine JavaScript-Implementierung von gRPC. Sie benötigt keine nativen Abhängigkeiten, funktioniert auf allen Plattformen und unterstützt alle gRPC-Funktionen (unäre Aufrufe, Server- und Client-Streaming, bidirektionales Streaming). \n
- @grpc/proto-loader — ein Dienstprogramm zum Laden von
.proto-Dateien zur Laufzeit. Es ermöglicht die dynamische Erstellung von JavaScript-Objekten aus Protobuf-Definitionen. \n
Zur Kompilierung von .proto-Dateien in statische Module kann grpc-tools (Teil von grpc-tools) verwendet werden, aber in modernen Projekten wird häufiger das dynamische Laden über @grpc/proto-loader eingesetzt.
Installation der Abhängigkeiten
\n\nnpm install @grpc/grpc-js @grpc/proto-loader\n\nBeispiel: Definition einer Proto-Datei
\n\nErstellen wir eine Datei helloworld.proto mit einem einfachen Dienst:
syntax = "proto3";\n\npackage helloworld;\n\nservice Greeter {\n rpc SayHello (HelloRequest) returns (HelloReply) {}\n}\n\nmessage HelloRequest {\n string name = 1;\n}\n\nmessage HelloReply {\n string message = 1;\n}\n\nServerteil (Node.js)
\n\nErstellen wir eine Datei server.js:
const grpc = require('@grpc/grpc-js');\nconst protoLoader = require('@grpc/proto-loader');\nconst path = require('path');\n\nconst PROTO_PATH = path.join(__dirname, 'helloworld.proto');\n\nconst packageDefinition = protoLoader.loadSync(PROTO_PATH, {\n keepCase: true,\n longs: String,\n enums: String,\n defaults: true,\n oneofs: true\n});\n\nconst helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;\n\nfunction sayHello(call, callback) {\n const name = call.request.name || 'Guest';\n callback(null, { message: `Hallo, ${name}!` });\n}\n\nfunction main() {\n const server = new grpc.Server();\n server.addService(helloProto.Greeter.service, { sayHello: sayHello });\n server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {\n console.log('gRPC-Server gestartet auf Port 50051');\n server.start();\n });\n}\n\nmain();\n\nClientteil (Node.js)
\n\nErstellen wir eine Datei client.js:
const grpc = require('@grpc/grpc-js');\nconst protoLoader = require('@grpc/proto-loader');\nconst path = require('path');\n\nconst PROTO_PATH = path.join(__dirname, 'helloworld.proto');\n\nconst packageDefinition = protoLoader.loadSync(PROTO_PATH, {\n keepCase: true,\n longs: String,\n enums: String,\n defaults: true,\n oneofs: true\n});\n\nconst helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;\n\nfunction main() {\n const client = new helloProto.Greeter('localhost:50051',\n grpc.credentials.createInsecure());\n\n const userName = process.argv[2] || 'Welt';\n\n client.sayHello({ name: userName }, (error, response) => {\n if (error) {\n console.error('Fehler:', error.message);\n return;\n }\n console.log('Serverantwort:', response.message);\n });\n}\n\nmain();\n\nStarten und Testen
\n\nStarten Sie den Server in einem Terminal:
\n\nnode server.js\n\nFühren Sie in einem anderen Terminal den Client aus:
\n\nnode client.js Ivan\n\nSie sollten