Heim >Backend-Entwicklung >Golang >gRPC zwischen Web und Server.

gRPC zwischen Web und Server.

WBOY
WBOYOriginal
2024-08-31 06:35:36668Durchsuche

Dieses Projekt zeigt, wie man eine einfache gRPC-Kommunikation zwischen einem Web-Client und einem Server mit einem Envoy-Proxy einrichtet.

Zu diesem Zweck verwende ich die gRPC-Web-Bibliothek. gRPC-Web ist eine JavaScript-Clientbibliothek, die es Webanwendungen ermöglicht, mit gRPC-Diensten zu interagieren. Da Browser HTTP/2 oder das von Standard-gRPC verwendete Binärprotokoll nicht unterstützen, bietet gRPC-Web eine Möglichkeit, diese Lücke zu schließen, indem HTTP/1.1 oder HTTP/2 verwendet und gRPC-Nachrichten so codiert werden, dass Browser sie verarbeiten können. So funktioniert gRPC-Web:

  1. Der Client sendet Anfragen über gRPC-Web an den Server, der normalerweise über HTTP/1.1 oder HTTP/2 kommuniziert. An die Anfrage können Metadaten (z. B. Header) angehängt werden, beispielsweise zur Authentifizierung (z. B. JWT-Tokens).

Die Anfrage wird in einem gRPC-Web-Format codiert, wobei normalerweise die Base64-Codierung für die binäre gRPC-Nutzlast verwendet wird. Der Client sendet diese Anfrage über HTTP/1.1 oder HTTP/2.

  1. Envoy (oder ein anderer Reverse-Proxy wie Nginx) fungiert als Vermittler zwischen dem gRPC-Web-Client und dem gRPC-Server. Envoy empfängt die gRPC-Web-Anfrage, dekodiert die gRPC-Web-Nutzlast und leitet sie als Standard-gRPC-Anfrage über HTTP/2 an den gRPC-Server weiter.

Der gRPC-Server verarbeitet die Anfrage, als wäre es eine native gRPC-Anfrage, und verwendet HTTP/2 für die Kommunikation.

  1. Der gRPC-Server verarbeitet die eingehende gRPC-Anfrage, führt die erforderliche Geschäftslogik aus und generiert eine Antwort (in diesem Beispiel handelt es sich um die von Go geschriebene Anwendung). Die Antwort wird im Standard-gRPC-Format codiert und an Envoy zurückgesendet.

  2. Envoy empfängt die gRPC-Antwort, codiert sie im gRPC-Web-Format (normalerweise mit Base64) und sendet sie über HTTP/1.1 oder HTTP/2 an den gRPC-Web-Client zurück. Alle in der gRPC-Antwort enthaltenen Metadaten, wie z. B. Statuscodes, werden entsprechend übersetzt.

  3. Der gRPC-Web-Client dekodiert die Antwort und wandelt sie in ein verwendbares Format innerhalb der Webanwendung um. Die Webanwendung verarbeitet die Antwort, aktualisiert die Benutzeroberfläche oder behandelt Fehler nach Bedarf.

gRPC between Web and Server.

HINWEIS: Clientseitiges und bidirektionales Streaming wird derzeit nicht unterstützt (siehe Streaming-Roadmap)

Vorteile von gRPC-Web

  • Browserkompatibilität: Ermöglicht modernen Webanwendungen die Interaktion mit gRPC-Diensten, ohne dass native Unterstützung für HTTP/2 und Binärprotokolle erforderlich ist.
  • Effizienz: Nutzt die Leistung und Effizienz von gRPC und passt es gleichzeitig für das Web an.

Hier ist ein GitHub-Projekt dafür:

https://github.com/ehsaniara/gRPC-web-example

Proto-Datei

syntax = "proto3";

package helloworld;

option go_package = "./proto"; // Add this line

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

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

serverseitig (go)

package main

import (
   "context"
   "google.golang.org/grpc/reflection"
   "log"
   "net"

   pb "github.com/ehsaniara/gRPC-web-example/proto"
   "google.golang.org/grpc"
)

type server struct {
 pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
 return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
 lis, err := net.Listen("tcp", ":50051")
 if err != nil {
  log.Fatalf("failed to listen: %v", err)
 }
 s := grpc.NewServer()
 pb.RegisterGreeterServer(s, &server{})

 // Register reflection service on gRPC server.
 reflection.Register(s)
 if err := s.Serve(lis); err != nil {
  log.Fatalf("failed to serve: %v", err)
 }

 log.Println("Server is running on port 50051")
 if err := s.Serve(lis); err != nil {
  log.Fatalf("failed to serve: %v", err)
 }
}

Envoy-Konfiguration

...
http_filters:
  - name: envoy.filters.http.grpc_web
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
  - name: envoy.filters.http.cors
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
  - name: envoy.filters.http.router
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
...

JS-Webclient (Webpack)

// Import the generated gRPC-Web client stubs and message classes
import {GreeterClient} from './generated/helloworld_grpc_web_pb';
import {HelloRequest} from './generated/helloworld_pb';

// Create an instance of the Greeter client
const client = new GreeterClient('http://localhost:8080');

// Function to send a greeting request
function sayHello(name) {
    // Create a new request
    const request = new HelloRequest();
    request.setName(name);

    // Call the sayHello method on the Greeter client
    client.sayHello(request, {}, (err, response) => {
        if (err) {
            console.error('Error:', err.message);
            document.getElementById('output').textContent = 'Error: ' + err.message;
        } else {
            console.log('Greeting:', response.getMessage());
            document.getElementById('output').textContent = 'Greeting: ' + response.getMessage();
        }
    });
}

// Example usage: sending a request when the page loads
document.addEventListener('DOMContentLoaded', () => {
    const name = 'World';
    sayHello(name);
});

Hier ist ein GitHub-Projekt, das mit diesem Projekt zusammenhängt

https://github.com/ehsaniara/gRPC-web-example

Das obige ist der detaillierte Inhalt vongRPC zwischen Web und Server.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn