gRPC och högpresterande API:er · Lektion

Enkel unary-gRPC-tjänst

Implementera en grundläggande gRPC-tjänst och klient med modellen ”begäran-svar” från grunden med hjälp av genererad kod.

Lektion 3 av 411 steg

Enkel unary-gRPC-tjänst är en gratis lektion i gRPC och högpresterande API:er på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för gRPC och högpresterande API:er, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i gRPC och högpresterande API:er innehåller totalt 4 lektioner.

Unary RPC: enkla interaktioner

I gRPC är en Unary RPC det enklaste kommunikationsmönstret. Det fungerar som ett traditionellt funktionsanrop där en klient skickar en enda begäran till servern och servern svarar med ett enda svar.

Tänk på det som en vanlig modell för "begäran-svar". Klienten väntar på serverns svar innan den fortsätter.

  • Klienten skickar ett meddelande.
  • Servern skickar tillbaka ett meddelande.
  • Detta är den vanligaste typen av RPC.

Gå igenom vår Protobuf

Innan vi börjar med implementeringen ska vi kort repetera vår enkla Protocol Buffer- (Protobuf-) definition. Detta schema definierar tjänsten och de meddelanden vi ska använda.

Vi implementerar tjänsten Greeter med metoden SayHello.

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;
}

(Kom ihåg att kodgenerering behandlades i en tidigare lektion.)

Servern: utöka basklassen

När kod har genererats från vår .proto-fil skapar gRPC en abstrakt basklass för servern. För tjänsten Greeter är den GreeterGrpc.GreeterImplBase.

För att implementera tjänsten skapar vi en ny klass som extends denna basklass och åsidosätter tjänstemetoden eller tjänstemetoderna.

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

StreamObserver används för att skicka tillbaka svaret.

Serverlogik: skapa svaret

I metoden sayHello tar vi emot HelloRequest. Därefter kan vi behandla den och skapa HelloReply.

Metoden StreamObserver.onNext() skickar svaret, och onCompleted() signalerar att RPC-anropet är klart.

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
    }
}

Fullständig serverimplementering

Nu sätter vi ihop allt för att skapa och starta en gRPC-server. Servern lyssnar efter inkommande klientförfrågningar på en specifik port.

Försök köra koden och gå sedan vidare till klientimplementeringen!

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();
        }
    }
}

Klientstub: ansluta och anropa

På klientsidan genererar gRPC också "stubbar". Dessa stubbar tillhandahåller metoder för att anropa fjärrtjänsten, så att det känns som ett lokalt metodanrop.

För unary RPC-anrop använder vi ofta en blocking stub, vilket innebär att klienten väntar på serverns svar.

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

Stubben hanterar alla underliggande detaljer kring nätverkskommunikationen åt dig!

Klientkanal: anslutningen

Innan klienten kan använda en stub behöver den en kanal. En kanal representerar en anslutning till en gRPC-server på en specifik värd och port.

Kanaler är vanligtvis långlivade och kan återanvändas för flera RPC-anrop.

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

usePlaintext() går bra vid lokal utveckling, men undvik det i produktion!

Fullständig klientimplementering

När kanalen och stubben är klara kan vi nu göra vårt unary RPC-anrop. Vi skapar en HelloRequest och skickar den via stubben.

Kör servern från föregående steg och kör sedan den här klienten för att se den i praktiken!

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-flöde: begäran och svar

När du kör klienten skickar den HelloRequest till servern. Servern tar emot den, behandlar den med hjälp av vår GreeterImpl och skickar tillbaka en HelloReply.

  • Klient: Skapar kanal och stubb och bygger HelloRequest.
  • Klient: Anropar blockingStub.sayHello(request).
  • Server: Tar emot HelloRequest i metoden sayHello.
  • Server: Bearbetar begäran, bygger HelloReply och anropar onNext() och onCompleted().
  • Klient: Tar emot HelloReply och fortsätter körningen.

Detta slutför en hel unary RPC-cykel!

Kontroll av unary-tjänst

Anta att du har en unary gRPC-tjänst. Vilken komponent ansvarar för att ta emot en begäran, behandla den och skicka tillbaka ett enda svar?

Sammanfattning: enkel unary RPC

Bra jobbat! Du har lärt dig att implementera en grundläggande unary gRPC-tjänst och klient:

  • Du har repeterat Protobuf-schemat för tjänsten.
  • Du har implementerat serverlogiken genom att utöka den genererade basklassen och hantera begäranden.
  • Du har skapat och startat en gRPC-server.
  • På klientsidan använde du en kanal för att ansluta och en blocking stub för att göra RPC-anropet.

Unary RPC-anrop är grundläggande i gRPC och erbjuder ett robust sätt att hantera enkel kommunikation enligt modellen begäran-svar. Nästa steg är att utforska mer avancerade streamingmönster!

Gratis att börja

Lär dig gRPC och högpresterande API:er med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
12
Lektioner
48

Vanliga frågor

Är lektionen ”Enkel unary-gRPC-tjänst” gratis?

Ja – hela texten till ”Enkel unary-gRPC-tjänst” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i gRPC och högpresterande API:er, kan Ni uppgradera till CoddyKit PRO. Kursen i gRPC och högpresterande API:er innehåller totalt 4 lektioner.

Vad lär jag mig i ”Enkel unary-gRPC-tjänst”?

Implementera en grundläggande gRPC-tjänst och klient med modellen ”begäran-svar” från grunden med hjälp av genererad kod. Ni övar på gRPC och högpresterande API:er med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig gRPC och högpresterande API:er?

Du behöver inga förkunskaper. Utbildningen i gRPC och högpresterande API:er på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Enkel unary-gRPC-tjänst”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här gRPC och högpresterande API:er-lektionen?

Ja. Varje gRPC och högpresterande API:er-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Definition av Protobuf-scheman
  2. Generera gRPC-kod
  3. Enkel unary-gRPC-tjänst
  4. Streamande RPC-anrop: server, klient och dubbelriktade
← Tillbaka till gRPC och högpresterande API:er