พื้นฐาน gRPC และ Protobuf
กำหนดสัญญาบริการในไฟล์ .proto สร้างโค้ด C# ด้วย Grpc.Tools และทำความเข้าใจการส่งข้อมูลของ gRPC
พื้นฐาน gRPC และ Protobuf เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
gRPC คืออะไร
gRPC คือเฟรมเวิร์ก RPC ประสิทธิภาพสูงที่ไม่ขึ้นกับภาษา พัฒนาโดย Google โดยใช้ HTTP/2 เป็นตัวรับส่งข้อมูล และใช้ Protocol Buffers (Protobuf) เป็นรูปแบบการแปลงข้อมูล ซึ่งเร็วกว่าและมีขนาดกะทัดรัดกว่า JSON บน HTTP/1.1 มาก
Protocol Buffers: IDL
คุณกำหนดสัญญาบริการไว้ในไฟล์ .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# ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 93
- บทเรียน
- 346
คำถามที่พบบ่อย
บทเรียน “พื้นฐาน gRPC และ Protobuf” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “พื้นฐาน gRPC และ Protobuf” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “พื้นฐาน gRPC และ Protobuf”
กำหนดสัญญาบริการในไฟล์ .proto สร้างโค้ด C# ด้วย Grpc.Tools และทำความเข้าใจการส่งข้อมูลของ gRPC คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “พื้นฐาน gRPC และ Protobuf” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน gRPC และ Protobuf
- RPC แบบเอกภาพและการสตรีมจากเซิร์ฟเวอร์
- การสตรีมจากไคลเอ็นต์และแบบสองทิศทาง
- เส้นตาย การยกเลิก และตัวดักจับ