أساسيات gRPC وProtobuf
عرّفوا عقود الخدمات في ملفات .proto، وولّدوا شيفرة C# باستخدام Grpc.Tools، وافهموا آلية نقل gRPC.
أساسيات gRPC وProtobuf درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
ما هو gRPC؟
gRPC هو إطار عمل RPC عالي الأداء ومحايد اللغة، طوّرته Google. ويستخدم HTTP/2 للنقل وProtocol Buffers (Protobuf) لتنسيق التسلسل، وهو أسرع بكثير وأكثر إحكامًا من JSON عبر HTTP/1.1.
Protocol Buffers: لغة تعريف الواجهات
تعرّف عقد الخدمة في ملف .proto. وتتميز Protobuf IDL (لغة تعريف الواجهات) بصرامة الأنواع وحيادها تجاه اللغة، إذ ينشئ الملف نفسه شفرة العميل والخادم بلغات مثل C# وGo وPython.
// greet.proto
syntax = "proto3";
option csharp_namespace = "GrpcService";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}إعداد خادم gRPC في .NET
أنشئ مشروع gRPC باستخدام dotnet new grpc. أضف ملفات .proto إلى المشروع، وستنشئ Grpc.Tools فئات C# تلقائيًا أثناء وقت البناء.
// .csproj snippet
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
// Program.cs
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<GreeterService>();
app.Run();تنفيذ خدمة gRPC
ورّث من الفئة الأساسية المُنشأة وتجاوز أسلوب RPC. ويتولى الإطار تلقائيًا التسلسل وتأطير HTTP/2 والتوجيه.
using Grpc.Core;
using GrpcService;
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger) => _logger = logger;
public override Task<HelloReply> SayHello(
HelloRequest request,
ServerCallContext context)
{
_logger.LogInformation("Saying hello to {Name}", request.Name);
return Task.FromResult(new HelloReply
{
Message = $"Hello, {request.Name}!"
});
}
}إنشاء عميل gRPC
ينشئ مترجم Protobuf أيضًا فئة عميل ذات أنواع صارمة. استخدم GrpcChannel للاتصال بالخدمة واستدعائها كما لو كانت أسلوبًا محليًا.
// Client project: add Grpc.Net.Client package
using var channel = GrpcChannel.ForAddress("https://localhost:7042");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "Alice" });
Console.WriteLine(reply.Message); // Hello, Alice!أنواع Protobuf وأرقام الحقول
يملك كل حقل في رسالة Protobuf رقم حقل فريدًا (من 1 إلى 536870911). وتُرمّز أرقام الحقول في التنسيق الثنائي، لذا لا تغيّرها بعد النشر، وإلا أخللت بالتوافق مع الإصدارات السابقة.
message Product {
int32 id = 1;
string name = 2;
double price = 3;
int32 stock = 4;
bool is_active = 5;
repeated string tags = 6; // array
}
// Supported scalar types:
// int32, int64, uint32, uint64, float, double
// bool, string, bytes, enumالتعدادات والرسائل المتداخلة
تدعم Protobuf التعدادات وأنواع الرسائل المتداخلة. استخدمها لنمذجة كائنات المجال المعقدة في عقد الخدمة.
enum OrderStatus {
ORDER_STATUS_UNSPECIFIED = 0;
ORDER_STATUS_PENDING = 1;
ORDER_STATUS_SHIPPED = 2;
ORDER_STATUS_CANCELLED = 3;
}
message Order {
int32 id = 1;
OrderStatus status = 2;
repeated OrderLine lines = 3;
}
message OrderLine {
int32 product_id = 1;
int32 quantity = 2;
double price = 3;
}نقل HTTP/2 وgRPC
يستخدم gRPC بروتوكول HTTP/2 الذي يدعم التعددية، أي تنفيذ عدة استدعاءات RPC متزامنة عبر اتصال TCP واحد، مما يقلل زمن الاستجابة والعبء الناتج عن الاتصالات مقارنةً بـ HTTP/1.1.
// gRPC requires HTTP/2
// For local dev with HTTP (not HTTPS), enable HTTP/2 cleartext:
builder.WebHost.ConfigureKestrel(opt =>
opt.ListenLocalhost(5000, o => o.Protocols = HttpProtocols.Http2));
// Client for cleartext (dev only)
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
using var channel = GrpcChannel.ForAddress("http://localhost:5000");معالجة الأخطاء باستخدام StatusCode
يستخدم gRPC رموز حالة خاصة به تختلف عن رموز HTTP. اطرح RpcException مع Status لإرسال استجابات أخطاء ذات أنواع إلى العملاء.
public override Task<ProductReply> GetProduct(
ProductRequest request,
ServerCallContext context)
{
var product = _repo.FindById(request.Id);
if (product is null)
throw new RpcException(
new Status(StatusCode.NotFound, $"Product {request.Id} not found"));
return Task.FromResult(MapToReply(product));
}انعكاس gRPC للتطوير
فعّل انعكاس gRPC حتى تتمكن أدوات مثل grpcurl وPostman من اكتشاف خدماتك من دون الوصول مباشرةً إلى ملف .proto.
// dotnet add package Grpc.AspNetCore.Server.Reflection
builder.Services.AddGrpcReflection();
if (app.Environment.IsDevelopment())
app.MapGrpcReflectionService();
// Now use grpcurl:
// grpcurl -plaintext localhost:5000 list
// grpcurl -plaintext localhost:5000 greet.Greeter/SayHelloمن الواقع العملي: البحث عن منتج في بنية الخدمات المصغرة
خدمة منتجات تعرض نقطة نهاية gRPC وتستخدمها خدمة الطلبات داخليًا، وهو نمط تقليدي للاتصال بين الخدمات.
// product.proto
service ProductService {
rpc GetProduct (GetProductRequest) returns (ProductResponse);
rpc ListProducts (ListProductsRequest) returns (ListProductsResponse);
}
// Order service calls it:
public class OrderService
{
private readonly ProductService.ProductServiceClient _products;
public OrderService(ProductService.ProductServiceClient p) => _products = p;
public async Task<Order> PlaceOrderAsync(int productId, int qty)
{
var product = await _products.GetProductAsync(
new GetProductRequest { Id = productId });
return new Order { ProductName = product.Name, Quantity = qty };
}
}اختبار سريع
لماذا يجب ألا تغيّر أبدًا رقم حقل Protobuf موجودًا بعد النشر؟
مراجعة: أساسيات gRPC وProtobuf
أهم النقاط:
- يستخدم gRPC بروتوكول HTTP/2 وProtobuf لاتصال سريع بين الخدمات وذي أنواع صارمة
- عرّف عقود الخدمة في ملفات
.proto، إذ تُنشأ الشفرة أثناء وقت البناء - أرقام الحقول هي ترميز النقل، لذا لا تغيّرها أو تعِد استخدامَها أبدًا
- ورّث من الفئة الأساسية المُنشأة وتجاوز أساليب RPC
- استخدم RpcException مع StatusCode لاستجابات أخطاء ذات أنواع
- فعّل انعكاس gRPC لدعم الأدوات أثناء التطوير
تعلم C# مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 93
- الدروس
- 346
الأسئلة الشائعة
هل درس «أساسيات gRPC وProtobuf» مجاني؟
نعم — نص درس «أساسيات gRPC وProtobuf» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «أساسيات gRPC وProtobuf»؟
عرّفوا عقود الخدمات في ملفات .proto، وولّدوا شيفرة C# باستخدام Grpc.Tools، وافهموا آلية نقل gRPC. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «أساسيات gRPC وProtobuf»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أساسيات gRPC وProtobuf
- استدعاءات RPC الأحادية والبث من الخادم
- البث من العميل والبث ثنائي الاتجاه
- المهل الزمنية والإلغاء والمعترضات