首頁  >  文章  >  後端開發  >  Web 和伺服器之間的 gRPC。

Web 和伺服器之間的 gRPC。

WBOY
WBOY原創
2024-08-31 06:35:36622瀏覽

此專案示範如何使用 Envoy 代理程式在 Web 用戶端和伺服器之間建立簡單的 gRPC 通訊。

我正在使用 gRPC-Web 程式庫來實現此目的。 gRPC-Web 是一個 JavaScript 用戶端程式庫,允許 Web 應用程式與 gRPC 服務互動。由於瀏覽器不支援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 負載,並使用 HTTP/2 將其作為標準 gRPC 請求轉送到 gRPC 伺服器。

gRPC 伺服器處理請求,就好像它是本機 gRPC 請求一樣,使用 HTTP/2 進行通訊。

  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 的優點

  • 瀏覽器相容性:允許現代 Web 應用程式與 gRPC 服務交互,而不需要對 HTTP/2 和二進位協定的本機支援。
  • 效率:利用 gRPC 的效能和效率,同時適應網路。

這裡有一個 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn