สร้างเซิร์ฟเวอร์ gRPC
ให้บริการเมธอด RPC แบบเอกภาพ
สร้างเซิร์ฟเวอร์ gRPC เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
เทรตเซิร์ฟเวอร์ที่สร้างขึ้น
สำหรับบริการชื่อ Greeter tonic จะสร้างเทรตไว้ใน greeter_server คุณจะนำเทรตนี้ไปใช้งานกับโครงสร้างของคุณเองเพื่อกำหนดพฤติกรรม
เทรตนี้เป็น async ผ่าน #[tonic::async_trait] ดังนั้นแต่ละเมธอดจึงเป็น async fn ที่คืนค่าเป็น Result
use greeter::v1::greeter_server::{Greeter, GreeterServer};
use greeter::v1::{HelloRequest, HelloReply};ตัวห่อหุ้มคำขอและการตอบกลับ
เมธอดรับค่า tonic::Request<T> และคืนค่า tonic::Response<T> ตัวห่อหุ้มเหล่านี้เก็บข้อมูลเมตา ส่วนขยาย และข้อความด้านใน
เรียก .into_inner() เพื่อรับข้อความที่ถอดรหัสแล้ว และใช้ Response::new(..) เพื่อสร้างการตอบกลับ
let req: HelloRequest = request.into_inner();
let reply = HelloReply { message: format!("Hi {}", req.name) };
Ok(Response::new(reply))โครงสร้างเซิร์ฟเวอร์
กำหนดโครงสร้างเพื่อเก็บสถานะที่ใช้ร่วมกัน เช่น พูลฐานข้อมูล โดยมักอนุมาน Default เมื่อไม่มีสถานะ
คุณจะนำเทรตที่สร้างขึ้นไปใช้งานกับโครงสร้างนี้
#[derive(Default)]
pub struct MyGreeter {}การนำเมธอดเอกภาคไปใช้งาน
ใส่คำอธิบายกำกับบล็อก impl ด้วย #[tonic::async_trait] และนำ rpc แต่ละรายการไปใช้งานเป็น async fn ที่ตรงกับลายเซ็นซึ่งสร้างขึ้น
เมื่อสำเร็จ ให้คืนค่า Ok(Response::new(reply))
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(&self, request: Request<HelloRequest>)
-> Result<Response<HelloReply>, Status> {
let name = request.into_inner().name;
Ok(Response::new(HelloReply { message: format!("Hello {name}") }))
}
}การคืนข้อผิดพลาดด้วย Status
ข้อผิดพลาดจะถูกคืนค่าเป็น tonic::Status ซึ่งจับคู่กับรหัสสถานะของ gRPC ใช้ตัวสร้างอย่าง Status::invalid_argument หรือ Status::not_found
สตริงข้อความจะถูกส่งไปยังไคลเอ็นต์พร้อมกับรหัส
if name.is_empty() {
return Err(Status::invalid_argument("name must not be empty"));
}การสร้างและให้บริการ
ใช้ tonic::transport::Server ภายใน main แบบอะซิงโครนัส เพิ่มบริการของคุณโดยห่อด้วยชนิด ...Server ที่สร้างขึ้น แล้วเรียก serve พร้อมที่อยู่ซ็อกเก็ต
มาโคร #[tokio::main] จะจัดเตรียมสภาพแวดล้อมรันให้
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
Server::builder()
.add_service(GreeterServer::new(MyGreeter::default()))
.serve(addr)
.await?;
Ok(())
}การตอบกลับแบบสตรีมจากเซิร์ฟเวอร์
เมธอดที่สตรีมจากเซิร์ฟเวอร์จะคืนชนิดสตรีม tonic ใช้ชนิดที่เกี่ยวข้องร่วมกับสตรีมแบบกล่อง โดยช่อง mpsc เป็นวิธีทั่วไปสำหรับป้อนข้อความ
คุณคืนค่า ReceiverStream ที่ห่ออยู่ใน Response
use tokio_stream::wrappers::ReceiverStream;
let (tx, rx) = tokio::sync::mpsc::channel(8);
tokio::spawn(async move { tx.send(Ok(reply)).await.ok(); });
Ok(Response::new(ReceiverStream::new(rx)))การอ่านข้อมูลเมตา
ข้อมูลเมตาของคำขอเก็บส่วนหัว เช่น โทเค็นการยืนยันตัวตน เข้าถึงได้ด้วย request.metadata() ก่อนใช้เนื้อหาของคำขอ
คีย์เป็น ASCII และไม่แยกตัวพิมพ์เล็กใหญ่ ส่วนค่าจะถูกคืนเป็น MetadataValue
if let Some(token) = request.metadata().get("authorization") {
// validate token
} else {
return Err(Status::unauthenticated("missing token"));
}ตัวดักคำขอ
ตัวดักคำขอจะทำงานก่อนแต่ละคำขอ จึงเหมาะสำหรับการยืนยันตัวตนหรือการบันทึกข้อมูล โดยรับ Request แล้วคืนค่ากลับหรือคืนข้อผิดพลาด Status
แนบตัวดักคำขอด้วย with_interceptor ขณะเพิ่มบริการ
fn auth(req: Request<()>) -> Result<Request<()>, Status> {
match req.metadata().get("authorization") {
Some(_) => Ok(req),
None => Err(Status::unauthenticated("no token")),
}
}
// .add_service(GreeterServer::with_interceptor(svc, auth))การปิดระบบอย่างสุภาพ
ใช้ serve_with_shutdown เพื่อหยุดรับการเชื่อมต่อเมื่ออนาคตเสร็จสมบูรณ์ เช่น เมื่อได้รับสัญญาณ Ctrl-C
คำขอที่กำลังดำเนินการจะเสร็จสิ้นก่อนเซิร์ฟเวอร์ปิด ทำให้ไม่ถูกตัดทิ้งอย่างกะทันหัน
Server::builder()
.add_service(GreeterServer::new(MyGreeter::default()))
.serve_with_shutdown(addr, async {
tokio::signal::ctrl_c().await.ok();
})
.await?;สถานะที่ใช้ร่วมกัน
หากต้องการใช้สถานะที่เปลี่ยนแปลงได้ร่วมกันระหว่างคำขอ ให้เก็บสถานะนั้นไว้ภายใน Arc และกลไกประสานงาน เช่น tokio::sync::Mutex ในโครงสร้างเซิร์ฟเวอร์
tonic จะโคลนบริการสำหรับแต่ละการเชื่อมต่อ ดังนั้นรูปแบบที่เหมาะสมคือใช้ตัวจัดการร่วมที่โคลนได้โดยมีต้นทุนต่ำ
use std::sync::Arc;
use tokio::sync::Mutex;
#[derive(Default)]
pub struct MyGreeter {
hits: Arc<Mutex<u64>>,
}ตรวจสอบอย่างรวดเร็ว
เมธอด gRPC รายงานความล้มเหลวใน tonic อย่างไร
สรุปทบทวน
คุณได้นำเทรตเซิร์ฟเวอร์ที่สร้างขึ้นไปใช้งานแล้ว ได้แก่ การดึงคำขอด้านใน การคืนการตอบกลับและข้อผิดพลาด Status การให้บริการด้วย tokio การสตรีมการตอบกลับ การอ่านข้อมูลเมตา การเพิ่มตัวดักคำขอ การปิดระบบอย่างสุภาพ และการใช้สถานะร่วมผ่าน Arc
ถัดไป คุณจะสร้างไคลเอ็นต์เพื่อเรียกใช้เซิร์ฟเวอร์นี้
คำถามที่พบบ่อย
บทเรียน “สร้างเซิร์ฟเวอร์ gRPC” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สร้างเซิร์ฟเวอร์ gRPC” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สร้างเซิร์ฟเวอร์ gRPC”
ให้บริการเมธอด RPC แบบเอกภาพ คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “สร้างเซิร์ฟเวอร์ gRPC” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม
ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Protobuf และนิยามบริการ
- สร้างโค้ดด้วย tonic-build
- สร้างเซิร์ฟเวอร์ gRPC
- เรียกใช้จากไคลเอนต์ gRPC