gRPC لـ TypeScript: المكتبات والأمثلة
\n\ngRPC هو إطار عمل RPC عالي الأداء من Google، يعمل عبر HTTP/2 ويستخدم Protocol Buffers (protobuf) لتسلسل البيانات. في TypeScript (و Node.js) يتيح gRPC بناء بنى خدمية مصغرة فعالة مع دعم البث والاتصال ثنائي الاتجاه. في هذه الصفحة، سنستعرض المكتبات الرئيسية، إعداد بيئة العمل، ونكتب مثالاً عملياً لتطبيق خادم-عميل.
\n\nالمكتبات الرئيسية لـ gRPC في TypeScript
\n\nللعمل مع gRPC في نظام TypeScript، هناك ثلاث حزم رئيسية:
\n\n- \n
@grpc/grpc-js— تطبيق JavaScript خالص لـ gRPC (بدون تبعيات أصلية)، يدعم HTTP/2 بالكامل ويعمل على Node.js 12+. \n @grpc/proto-loader— محمّل ملفات.proto، يقوم بإنشاء فئات JavaScript ديناميكياً بناءً على تعريفات protobuf. \n ts-proto— مولد لأنواع TypeScript من ملفات proto. بديل لـgrpc-toolsالمدمج، لكن مع دعم أفضل للكتابة الصارمة. \n
تثبيت جميع المكونات بأمر واحد:
\n\nnpm install @grpc/grpc-js @grpc/proto-loader ts-proto\nnpm install -D typescript @types/node\n\nإنشاء ملف .proto
\n\nلنبدأ بتعريف الخدمة. أنشئ ملفاً باسم hello.proto:
syntax = "proto3";\n\npackage hello;\n\nservice Greeter {\n rpc SayHello (HelloRequest) returns (HelloReply);\n rpc SayHelloStream (HelloRequest) returns (stream HelloReply);\n}\n\nmessage HelloRequest {\n string name = 1;\n}\n\nmessage HelloReply {\n string message = 1;\n}\n\nتوليد أنواع TypeScript باستخدام ts-proto
\n\nيقوم ts-proto بإنشاء واجهات وفئات رسائل كاملة. قم بتثبيت protoc والإضافة:
npm install -g protoc-gen-ts-proto\nprotoc --ts_proto_out=./generated hello.proto\n\nستحصل على ملف generated/hello.ts يحتوي على واجهات HelloRequest و HelloReply وخدمة GreeterClient المكتوبة بشكل صارم.
جزء الخادم (خادم gRPC على TypeScript)
\n\nأنشئ ملفاً باسم server.ts:
import * as grpc from '@grpc/grpc-js';\nimport * as protoLoader from '@grpc/proto-loader';\nimport { ProtoGrpcType } from './generated/hello';\n\nconst packageDef = protoLoader.loadSync('hello.proto');\nconst grpcObj = (grpc.loadPackageDefinition(packageDef) as unknown) as ProtoGrpcType;\nconst server = new grpc.Server();\n\nserver.addService(grpcObj.hello.Greeter.service, {\n SayHello: (call: any, callback: any) => {\n const name = call.request.name;\n callback(null, { message: `مرحباً، ${name}!` });\n },\n SayHelloStream: (call: any) => {\n const name = call.request.name;\n for (let i = 0; i < 5; i++) {\n call.write({ message: `الرسالة ${i + 1} لـ ${name}` });\n }\n call.end();\n }\n});\n\nserver.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {\n console.log('الخادم يعمل على المنفذ 50051');\n});\n\nجزء العميل (عميل gRPC على TypeScript)
\n\nأنشئ ملفاً باسم client.ts:
import * as grpc from '@grpc/grpc-js';\nimport * as protoLoader from '@grpc/proto-loader';\nimport { ProtoGrpcType } from './generated/hello';\n\nconst packageDef = protoLoader.loadSync('hello.proto');\nconst grpcObj = (grpc.loadPackageDefinition(packageDef) as unknown) as ProtoGrpcType;\n\nconst client = new grpcObj.hello.Greeter(\n 'localhost:50051',\n grpc.credentials.createInsecure()\n);\n\n// استدعاء أحادي\nclient.SayHello({ name: 'أليس' }, (err, response) => {\n if (!err) console.log('الرد:', response?.message);\n});\n\n// استدعاء بث من الخادم\nconst stream = client.SayHelloStream({ name: 'بوب' });\nstream.on('data', (data) => console.log('البث:', data.message));\nstream.on('end', (