웹과 서버 간의 gRPC.

WBOY
풀어 주다: 2024-08-31 06:35:36
원래의
619명이 탐색했습니다.

이 프로젝트는 Envoy 프록시를 사용하여 웹 클라이언트와 서버 간에 간단한 gRPC 통신을 설정하는 방법을 보여줍니다.

저는 이 목적으로 gRPC-Web 라이브러리를 사용하고 있습니다. gRPC-Web은 웹 애플리케이션이 gRPC 서비스와 상호 작용할 수 있게 해주는 JavaScript 클라이언트 라이브러리입니다. 브라우저는 HTTP/2 또는 표준 gRPC에서 사용되는 바이너리 프로토콜을 지원하지 않으므로 gRPC-Web은 HTTP/1.1 또는 HTTP/2를 사용하고 브라우저가 처리할 수 있는 방식으로 gRPC 메시지를 인코딩하여 격차를 해소하는 방법을 제공합니다. gRPC-Web의 작동 방식은 다음과 같습니다.

  1. 클라이언트는 일반적으로 HTTP/1.1 또는 HTTP/2를 통해 통신하는 gRPC-Web을 사용하여 서버에 요청을 보냅니다. 인증(예: JWT 토큰) 등을 위해 요청에 메타데이터(예: 헤더)를 첨부할 수 있습니다.

요청은 일반적으로 바이너리 gRPC 페이로드에 base64 인코딩을 사용하여 gRPC-Web 형식으로 인코딩됩니다. 클라이언트는 HTTP/1.1 또는 HTTP/2를 통해 이 요청을 보냅니다.

  1. Envoy(또는 Nginx와 같은 다른 역방향 프록시)는 gRPC-웹 클라이언트와 gRPC 서버 사이의 중개자 역할을 합니다. Envoy는 gRPC-Web 요청을 수신하고, gRPC-Web 페이로드를 디코딩한 후, 이를 HTTP/2를 사용하여 gRPC 서버에 표준 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 클라이언트는 응답을 디코딩하여 웹 애플리케이션 내에서 사용 가능한 형식으로 변환합니다. 웹 애플리케이션은 응답을 처리하고 필요에 따라 UI를 업데이트하거나 오류를 처리합니다.

gRPC between Web and Server.

참고: 클라이언트 측 및 양방향 스트리밍은 현재 지원되지 않습니다(스트리밍 로드맵 참조)

gRPC-Web의 장점

  • 브라우저 호환성: HTTP/2 및 바이너리 프로토콜에 대한 기본 지원 없이 최신 웹 애플리케이션이 gRPC 서비스와 상호 작용할 수 있도록 합니다.
  • 효율성: 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 웹 클라이언트(웹팩)

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

위 내용은 웹과 서버 간의 gRPC.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!