首页 > 后端开发 > Golang > Web 和服务器之间的 gRPC。

Web 和服务器之间的 gRPC。

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
发布: 2024-08-31 06:35:36
原创
728 人浏览过

该项目演示了如何使用 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

原始文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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;

}

登录后复制

服务器端(去)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

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)

 }

}

登录后复制

特使配置

1

2

3

4

5

6

7

8

9

10

11

12

...

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)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

// 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
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板