gRPC og højtydende API'er · Lektion

Serverstreaming forklaret

Forstå og implementér server-side streaming, hvor en server sender flere svar på én klientanmodning.

Lektion 1 af 412 trin

Serverstreaming forklaret er en gratis gRPC og højtydende API'er-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i gRPC og højtydende API'er, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. gRPC og højtydende API'er-kurset indeholder 4 lektioner i alt.

Grundlæggende serverstreaming

I gRPC er et serverbaseret streamingkald et kald, hvor en klient sender én enkelt forespørgsel, men serveren svarer med en sekvens af meddelelser.

Tænk på det som at abonnere på et nyhedsbrev: Du sender én forespørgsel (abonnér), og serveren sender dig mange opdateringer over tid (nyhedsbreve).

Anvendelser af streaming

Serverstreaming er perfekt i situationer, hvor serveren løbende skal sende opdateringer eller store mængder data til klienten. Almindelige anvendelser omfatter:

  • Datafeeds i realtid: Aktiekurser og sensormålinger.
  • Notifikationer: Advarsler og chatmeddelelser.
  • Download af store datamængder: Opdeling af en stor fil i mindre dele.

Protobuf til serverstreaming

Hvis du vil definere en serverbaseret streamingmetode i din .proto-fil, skal du blot tilføje nøgleordet stream før svar-typen.

Det fortæller gRPC, at serveren sender flere meddelelser for hver klientforespørgsel i stedet for kun én.

Eksempel på streaming med Protobuf

Sådan definerer du en tjeneste, der streamer meddelelser fra serveren:

syntax = "proto3";

option java_package = "com.coddykit.grpc";
option java_outer_classname = "StreamingProto";

service NotifierService {
  rpc SubscribeToNotifications (SubscriptionRequest) returns (stream Notification);
}

message SubscriptionRequest {
  string userId = 1;
}

message Notification {
  string message = 1;
  int64 timestamp = 2;
}

Implementering af serverstreaming

På serversiden modtager din streamingmetode ét forespørgselsobjekt, ligesom ved et unary-kald. I stedet for at returnere ét enkelt svar bruger du dog en StreamObserver til at sende flere svar tilbage til klienten.

Typisk gentager du en løkke, sender meddelelser og kalder derefter onCompleted(), når du er færdig.

Strukturen i en servermetode

Servermetoden for et streamet kald modtager forespørgslen og en StreamObserver. Du sender svar via responseObserver.onNext() og signalerer afslutning med responseObserver.onCompleted().

// Example (Java)
public void subscribeToNotifications(SubscriptionRequest request,
    io.grpc.stub.StreamObserver<Notification> responseObserver) {

  String userId = request.getUserId();
  System.out.println("Client " + userId + " subscribed.");

  // Simulate sending multiple notifications
  for (int i = 0; i < 3; i++) {
    Notification notification = Notification.newBuilder()
        .setMessage("Update " + (i + 1) + " for " + userId)
        .setTimestamp(System.currentTimeMillis())
        .build();
    responseObserver.onNext(notification); // Send a message
    try {
      Thread.sleep(1000); // Wait a bit
    } catch (InterruptedException e) { /* handle */ }
  }

  responseObserver.onCompleted(); // Signal completion
  System.out.println("Finished sending notifications to " + userId);
}

Modtagelse af streamede svar

Klienten foretager ét kald, men skal derefter vente på og behandle flere svar. Den leverer en StreamObserver til at håndtere de indkommende meddelelser, fejl og afslutningssignalet fra serveren.

Denne observer har metoderne onNext(), onError() og onCompleted().

Klientens stream-observer

Klientens StreamObserver definerer, hvordan den reagerer på hver hændelse fra serverens stream. Den behandler hver onNext-meddelelse, indtil der kaldes onCompleted.

// Example (Java)
StreamObserver<Notification> responseObserver = new StreamObserver<Notification>() {
  @Override
  public void onNext(Notification notification) {
    System.out.println("Received: " + notification.getMessage());
  }

  @Override
  public void onError(Throwable t) {
    System.err.println("Error: " + t.getMessage());
  }

  @Override
  public void onCompleted() {
    System.out.println("Server stream completed.");
  }
};

// Call the streaming method
// asyncStub.subscribeToNotifications(request, responseObserver);

Komplet serverstreamtjeneste

Her er en komplet gRPC-server, der implementerer den serverside-streamende metode SubscribeToNotifications. Kør denne først og derefter klienten!

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import com.coddykit.grpc.StreamingProto.SubscriptionRequest;
import com.coddykit.grpc.StreamingProto.Notification;
import com.coddykit.grpc.NotifierServiceGrpc.NotifierServiceImplBase;

public class StreamingServer {

  private Server server;

  private void start() throws Exception {
    int port = 50051;
    server = ServerBuilder.forPort(port)
        .addService(new NotifierServiceImpl())
        .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");
        StreamingServer.this.stop();
        System.err.println("*** server shut down");
      }
    });
  }

  private void stop() {
    if (server != null) {
      server.shutdown();
    }
  }

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

  public static void main(String[] args) throws Exception {
    final StreamingServer server = new StreamingServer();
    server.start();
    server.blockUntilShutdown();
  }

  static class NotifierServiceImpl extends NotifierServiceImplBase {
    @Override
    public void subscribeToNotifications(SubscriptionRequest request,
        StreamObserver<Notification> responseObserver) {

      String userId = request.getUserId();
      System.out.println("Server received subscription from: " + userId);

      for (int i = 0; i < 3; i++) {
        Notification notification = Notification.newBuilder()
            .setMessage("Update " + (i + 1) + " for " + userId)
            .setTimestamp(System.currentTimeMillis())
            .build();
        responseObserver.onNext(notification);
        try {
          Thread.sleep(1000); // Simulate some work
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          responseObserver.onError(e);
          return;
        }
      }
      responseObserver.onCompleted();
      System.out.println("Server finished sending notifications to: " + userId);
    }
  }
}

Komplet modtager af klientstream

Kør nu denne klientkode. Den opretter forbindelse til serveren og modtager streamen med notifikationer.

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.StreamObserver;
import com.coddykit.grpc.StreamingProto.SubscriptionRequest;
import com.coddykit.grpc.StreamingProto.Notification;
import com.coddykit.grpc.NotifierServiceGrpc;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class StreamingClient {

  public static void main(String[] args) throws InterruptedException {
    ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
        .usePlaintext() // For local testing, no TLS
        .build();

    NotifierServiceGrpc.Stub asyncStub = NotifierServiceGrpc.newStub(channel);

    CountDownLatch latch = new CountDownLatch(1);

    System.out.println("Client sending subscription request...");
    SubscriptionRequest request = SubscriptionRequest.newBuilder()
        .setUserId("user123")
        .build();

    asyncStub.subscribeToNotifications(request, new StreamObserver<Notification>() {
      @Override
      public void onNext(Notification notification) {
        System.out.println("Client received notification: " + notification.getMessage());
      }

      @Override
      public void onError(Throwable t) {
        System.err.println("Client received error: " + t.getMessage());
        latch.countDown();
      }

      @Override
      public void onCompleted() {
        System.out.println("Client stream completed.");
        latch.countDown();
      }
    });

    latch.await(5, TimeUnit.SECONDS); // Wait for stream to complete
    System.out.println("Client finished.");

    channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
  }
}

Kontrol af streammetode

Du er ved at bygge en gRPC-tjeneste, hvor en klient anmoder om en liste over de seneste logposter, og serveren løbende sender nye poster, efterhånden som de opstår. Hvilken Protobuf-definition opsætter korrekt metoden GetLogStream til dette?

Opsummering af streaming

Godt klaret! I denne lektion har du lært om serverside-streaming i gRPC.

  • Det gør det muligt for en server at sende flere svar på én klientforespørgsel.
  • Det defineres ved hjælp af nøgleordet stream på svartypen i Protobuf.
  • Du har implementeret både server- og klientlogik til at håndtere disse kontinuerlige dataflows.

Derefter ser vi på klientside-streaming, hvor klienten sender flere forespørgsler!

Gratis at komme i gang

Lær gRPC og højtydende API'er med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
12
Lektioner
48

Ofte stillede spørgsmål

Er lektionen “Serverstreaming forklaret” gratis?

Ja — hele teksten til “Serverstreaming forklaret” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af gRPC og højtydende API'er-kurset, skal du opgradere til CoddyKit PRO. gRPC og højtydende API'er-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Serverstreaming forklaret”?

Forstå og implementér server-side streaming, hvor en server sender flere svar på én klientanmodning. Du øver dig i gRPC og højtydende API'er med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på gRPC og højtydende API'er?

Der kræves ingen tidligere erfaring. gRPC og højtydende API'er på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Serverstreaming forklaret”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne gRPC og højtydende API'er-lektion?

Ja. Alle gRPC og højtydende API'er-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Serverstreaming forklaret
  2. Klientstreaming forklaret
  3. Tovejsstreaming
  4. Flowkontrol og backpressure i streaming
← Tilbage til gRPC og højtydende API'er