gRPC لـ C# (.NET): المكتبات والأمثلة
gRPC هو إطار عمل حديث عالي الأداء لاستدعاء الإجراءات عن بُعد (RPC)، طورته Google. يستخدم HTTP/2 للنقل و Protocol Buffers (protobuf) لتسلسل البيانات. في نظام .NET البيئي، أصبح gRPC الأداة الرئيسية لبناء بنية الخدمات المصغرة، مما يوفر كتابة صارمة، وإرسالاً متدفقاً ثنائي الاتجاه، وزمن وصول منخفض. في هذه المقالة، سنستعرض المكتبات الرئيسية للعمل مع gRPC في C# ونقدم أمثلة عملية.
المكتبات الأساسية لـ gRPC في .NET
للعمل مع gRPC في .NET، تُستخدم حزم NuGet التالية:
- Grpc.Net.Client — مكتبة العميل لإنشاء عملاء gRPC. تعمل فوق HttpClient وتدعم جميع أنواع الاستدعاءات: unary، server streaming، client streaming و bidirectional streaming.
- Grpc.AspNetCore.Server — مكتبة الخادم لدمج gRPC في ASP.NET Core. تسمح باستضافة خدمات gRPC جنباً إلى جنب مع REST API العادية.
- Google.Protobuf — مكتبة للعمل مع Protocol Buffers، وتوليد الرسائل وإلغاء تسلسلها.
- Grpc.Tools — مجموعة أدوات للتوليد التلقائي لرمز C# من ملفات .proto أثناء بناء المشروع.
تتضمن عملية التطوير ثلاث مراحل: وصف الخدمة في ملف .proto، توليد الكود، وتنفيذ الخادم/العميل.
مثال 1: خدمة unary بسيطة (طلب-استجابة)
لنقم بإنشاء خدمة بسيطة للحصول على معلومات المستخدم. لهذا، نحدد ملف user.proto:
syntax = "proto3";
package user;
service UserService { rpc GetUser (UserRequest) returns (UserResponse);}
message UserRequest { int32 id = 1;}
message UserResponse { string name = 1; string email = 2; int32 age = 3;}أضف مراجع للحزم وملف .proto إلى المشروع. بعد البناء، سيتم توليد الفئات UserRequest و UserResponse والفئة الأساسية UserServiceBase.
تنفيذ الخادم
using Grpc.Core;using User;
public class UserServiceImpl : UserService.UserServiceBase{ public override Task<UserResponse> GetUser(UserRequest request, ServerCallContext context) { var user = new UserResponse { Name = "إيفان بيتروف", Email = "ivan@example.com", Age = 30 }; return Task.FromResult(user); }}تشغيل الخادم في ASP.NET Core:
var builder = WebApplication.CreateBuilder(args);builder.Services.AddGrpc();var app = builder.Build();app.MapGrpcService<UserServiceImpl>();app.Run();تنفيذ العميل
using Grpc.Net.Client;using User;
var channel = GrpcChannel.ForAddress("https://localhost:5001");var client = new UserService.UserServiceClient(channel);
var response = await client.GetUserAsync(new UserRequest { Id = 1 });Console.WriteLine($"المستخدم: {response.Name}، البريد الإلكتروني: {response.Email}");مثال 2: الإرسال المتدفق من الخادم (Server Streaming)
الإرسال المتدفق من الخادم مفيد عندما تحتاج إلى إرسال كمية كبيرة من البيانات إلى العميل، مثل قائمة الأحداث أو السجلات. لنقم بتوسيع ملف .proto الخاص بنا:
service UserService { rpc GetUser (UserRequest) returns (UserResponse); rpc ListUsers (Empty) returns (stream UserResponse);}
message Empty {}تنفيذ الخادم:
public override async Task ListUsers(Empty request, IServerStreamWriter<UserResponse> responseStream, ServerCallContext context){ var users = new List<UserResponse> { new UserResponse { Name = "آنا", Email = "anna@test.com" }, new UserResponse { Name = "بوريس", Email = "boris@test.com" } };