0Pricing
gRPC & High Performance APIs · บทเรียน

บริการ gRPC แบบยูนารีอย่างง่าย

สร้างบริการและไคลเอ็นต์ gRPC พื้นฐานแบบ “คำขอ-การตอบกลับ” ตั้งแต่ต้นด้วยโค้ดที่สร้างขึ้น

บริการ gRPC แบบยูนารีอย่างง่าย เป็นบทเรียน gRPC & High Performance APIs ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน gRPC & High Performance APIs และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส gRPC & High Performance APIs มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

Unary RPC: Simple Interactions

In gRPC, a Unary RPC is the simplest communication pattern. It's like a traditional function call where a client sends a single request to the server, and the server responds with a single reply.

Think of it as a standard "request-response" model. The client waits for the server's response before proceeding.

  • Client sends one message.
  • Server sends one message back.
  • This is the most common RPC type.

Reviewing Our Protobuf

Before we dive into implementation, let's briefly recall our simple Protocol Buffer (Protobuf) definition. This schema defines the service and messages we'll use.

We'll implement the Greeter service with a SayHello method.

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.grpc.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

(Remember, code generation was covered in a previous lesson.)

Server: Extending the Base

After generating code from our .proto file, gRPC creates an abstract base class for our server. For our Greeter service, it's GreeterGrpc.GreeterImplBase.

To implement our service, we create a new class that extends this base class and overrides the service method(s).

class GreeterImpl extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest req,
                         StreamObserver<HelloReply> resObserver) {
        // ... implementation goes here ...
    }
}

The StreamObserver is how we send the response back.

Server Logic: Building Response

Inside the sayHello method, we receive the HelloRequest. We can then process it and build our HelloReply.

The StreamObserver.onNext() method sends the reply, and onCompleted() signals that the RPC is finished.

class GreeterImpl extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest req,
                         StreamObserver<HelloReply> resObserver) {
        System.out.println("Received name: " + req.getName());
        HelloReply reply = HelloReply.newBuilder()
                                   .setMessage("Hello " + req.getName())
                                   .build();
        resObserver.onNext(reply);     // Send the response
        resObserver.onCompleted();  // Mark RPC as complete
    }
}

Full Server Implementation

Now, let's put it all together to create and start a gRPC server. This server will listen for incoming client requests on a specific port.

Try running this code and then proceed to the client implementation!

package com.example.grpc.helloworld;

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class HelloWorldServer {
    private Server server;

    private void start() throws IOException {
        int port = 50051;
        server = ServerBuilder.forPort(port)
                .addService(new GreeterImpl())
                .build()
                .start();
        System.out.println("Server started, listening on " + port);
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                try {
                    HelloWorldServer.this.stop();
                } catch (InterruptedException e) {
                    e.printStackTrace(System.err);
                }
                System.err.println("*** server shut down");
            }
        });
    }

    private void stop() throws InterruptedException {
        if (server != null) {
            server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
        }
    }

    private void blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        final HelloWorldServer server = new HelloWorldServer();
        server.start();
        server.blockUntilShutdown();
    }

    static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
            System.out.println("Received: " + req.getName());
            HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
        }
    }
}

Client Stub: Connecting & Calling

On the client side, gRPC also generates "stubs." These stubs provide the methods to call the remote service, making it feel like a local method call.

For unary RPCs, we often use a blocking stub, which means the client waits for the server's response.

// Blocking stub for our Greeter service
GreeterGrpc.GreeterBlockingStub blockingStub;

The stub will handle all the underlying network communication details for you!

Client Channel: The Connection

Before using a stub, the client needs a channel. A channel represents a connection to a gRPC server at a specific host and port.

Channels are typically long-lived and can be reused for multiple RPC calls.

ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
                                            .usePlaintext() // No TLS for simplicity
                                            .build();
blockingStub = GreeterGrpc.newBlockingStub(channel);

usePlaintext() is okay for local dev but avoid in production!

Full Client Implementation

With the channel and stub ready, we can now make our unary RPC call. We'll build a HelloRequest and send it via the stub.

Run the server from the previous step, then run this client to see it in action!

package com.example.grpc.helloworld;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;

import java.util.concurrent.TimeUnit;

public class HelloWorldClient {
    private final ManagedChannel channel;
    private final GreeterGrpc.GreeterBlockingStub blockingStub;

    public HelloWorldClient(String host, int port) {
        channel = ManagedChannelBuilder.forAddress(host, port)
                .usePlaintext() // For simplicity, no TLS
                .build();
        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }

    public void shutdown() throws InterruptedException {
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }

    public void greet(String name) {
        System.out.println("Will try to greet " + name + "...");
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloReply response;
        try {
            response = blockingStub.sayHello(request);
        } catch (StatusRuntimeException e) {
            System.err.println("RPC failed: " + e.getStatus());
            return;
        }
        System.out.println("Greeting: " + response.getMessage());
    }

    public static void main(String[] args) throws Exception {
        HelloWorldClient client = new HelloWorldClient("localhost", 50051);
        try {
            String user = "CoddyKit User";
            if (args.length > 0) {
                user = args[0];
            }
            client.greet(user);
        } finally {
            client.shutdown();
        }
    }
}

Unary Flow: Request & Reply

When you run the client, it sends the HelloRequest to the server. The server receives it, processes it using our GreeterImpl, and sends back a HelloReply.

  • Client: Creates channel, stub, builds HelloRequest.
  • Client: Calls blockingStub.sayHello(request).
  • Server: Receives HelloRequest in sayHello method.
  • Server: Processes, builds HelloReply, calls onNext() and onCompleted().
  • Client: Receives HelloReply, continues execution.

This completes one full unary RPC cycle!

Unary Service Check

Consider a gRPC unary service. Which component is responsible for receiving a request, processing it, and sending back a single response?

Recap: Simple Unary RPC

Great job! You've learned how to implement a basic unary gRPC service and client:

  • We reviewed the Protobuf schema for our service.
  • We implemented the server logic by extending the generated base class and handling requests.
  • We built a gRPC server instance and started it.
  • On the client side, we used a channel to connect and a blocking stub to make the RPC call.

Unary RPCs are fundamental to gRPC, providing a robust way for simple request-response communication. Next, we'll explore more advanced streaming patterns!

คำถามที่พบบ่อย

บทเรียน “บริการ gRPC แบบยูนารีอย่างง่าย” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “บริการ gRPC แบบยูนารีอย่างง่าย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส gRPC & High Performance APIs ให้อัปเกรดเป็น CoddyKit PRO คอร์ส gRPC & High Performance APIs มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “บริการ gRPC แบบยูนารีอย่างง่าย”

สร้างบริการและไคลเอ็นต์ gRPC พื้นฐานแบบ “คำขอ-การตอบกลับ” ตั้งแต่ต้นด้วยโค้ดที่สร้างขึ้น คุณปฏิบัติ gRPC & High Performance APIs ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน gRPC & High Performance APIs หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน gRPC & High Performance APIs บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “บริการ gRPC แบบยูนารีอย่างง่าย” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน gRPC & High Performance APIs นี้ได้ไหม

ได้ บทเรียน gRPC & High Performance APIs ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การกำหนดสคีมา Protobuf
  2. การสร้างโค้ด gRPC
  3. บริการ gRPC แบบยูนารีอย่างง่าย
  4. RPC แบบสตรีม: เซิร์ฟเวอร์ ไคลเอนต์ และสองทิศทาง
← กลับไปที่ gRPC & High Performance APIs