ホームページ  >  記事  >  バックエンド開発  >  Web とサーバー間の gRPC。

Web とサーバー間の gRPC。

WBOY
WBOYオリジナル
2024-08-31 06:35:36636ブラウズ

このプロジェクトでは、Envoy プロキシを使用して Web クライアントとサーバー間の単純な gRPC 通信をセットアップする方法を示します。

私はこの目的のために gRPC-Web ライブラリを使用しています。 gRPC-Web は、Web アプリケーションが gRPC サービスと対話できるようにする JavaScript クライアント ライブラリです。ブラウザーは HTTP/2 または標準の gRPC で使用されるバイナリ プロトコルをサポートしていないため、gRPC-Web は、HTTP/1.1 または HTTP/2 を使用し、ブラウザーが処理できる方法で gRPC メッセージをエンコードすることでギャップを埋める方法を提供します。 gRPC-Web の仕組みは次のとおりです:

  1. クライアントは、gRPC-Web を使用してサーバーにリクエストを送信します。通常、HTTP/1.1 または HTTP/2 経由で通信します。メタデータ (ヘッダーなど) は、認証 (JWT トークンなど) などのためにリクエストに添付できます。

リクエストは gRPC-Web 形式でエンコードされ、通常はバイナリ gRPC ペイロードに Base64 エンコードを使用します。クライアントはこのリクエストを HTTP/1.1 または HTTP/2 経由で送信します。

  1. Envoy (または Nginx などの別のリバース プロキシ) は、gRPC-Web クライアントと gRPC サーバーの間の仲介者として機能します。 Envoy は gRPC-Web リクエストを受信し、gRPC-Web ペイロードをデコードし、それを標準の gRPC リクエストとして HTTP/2 を使用して gRPC サーバーに転送します。

gRPC サーバーは、通信に HTTP/2 を使用して、ネイティブ gRPC リクエストであるかのようにリクエストを処理します。

  1. gRPC サーバーは、受信した gRPC リクエストを処理し、必要なビジネス ロジックを実行して、応答を生成します (この例では、Go で記述されたアプリケーションです)。応答は標準の gRPC 形式でエンコードされ、Envoy に送り返されます。

  2. Envoy は gRPC 応答を受信し、それを gRPC-Web 形式 (通常は Base64 を使用) でエンコードし、HTTP/1.1 または HTTP/2 経由で gRPC-Web クライアントに送り返します。 gRPC 応答に含まれるメタデータ (ステータス コードなど) は適切に変換されます。

  3. gRPC-Web クライアントは応答をデコードし、Web アプリケーション内で使用可能な形式に変換します。 Web アプリケーションは応答を処理し、必要に応じて UI を更新したりエラーを処理したりします。

gRPC between Web and Server.

注: クライアント側および双方向ストリーミングは現在サポートされていません (ストリーミング ロードマップを参照)

gRPC-Web の利点

  • ブラウザの互換性: HTTP/2 およびバイナリ プロトコルのネイティブ サポートを必要とせずに、最新の Web アプリケーションが gRPC サービスと対話できるようにします。
  • 効率: gRPC を Web に適応させながら、そのパフォーマンスと効率を活用します。

これに関する GitHub プロジェクトがあります:

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

プロトファイル

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

サーバー側 (実行)

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

エンボイの構成

...
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 Web クライアント (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);
});

このプロジェクトに関連する GitHub プロジェクトは次のとおりです

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

以上がWeb とサーバー間の gRPC。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。