Vue grpc +docker nginx+ Python后端 集成

1. 前提

简单地说,RPC 就是调用方采用参数传递的方式,通过调用本机器上的一个函数或方法,去执行远程机器上的函数或方法(可以统称为服务),并返回结果。在整个过程中,RPC 会隐藏具体的通信细节。

RPC的核心是目的是: 本地调用远程(跨内存可访问的)方法。

RPC框架: 开箱即用的实现了RPC调用的框架,其中开源框架如 阿里Dubbo、Google gRPC、Facebook Thrift

远程通信协议: REST(HTTP JSON), SOAP(HTTP XML), gRPC(HTTP2 protobuf)

序列化/反序列化: 文本(XML、JSON)与二进制(Java原生的)与 protobuf

加粗的为这里选用的

2. 准备Proto文件,用于定义统一的接口

文件: hello.proto

syntax = "proto3";

package api;

// 这里可以写服务注释
service HelloWorldService {
    // 这里可以写方法注释
    rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

// 这里可以写请求结构注释
message HelloRequest {
    // 这里可以写参数注释
    string name = 1;
}

// 这里可以写响应结构注释
message HelloResponse {
    // 这里可以写参数注释
    string message = 1;
}
复制代码

3. 准备Python环境

pip install grpcio
pip install grpcio-tools
复制代码
# 编译 proto 文件
python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. hello.proto

python -m grpc_tools.protoc: python 下的 protoc 编译器通过 python 模块(module) 实现, 所以说这一步非常省心
--python_out=. : 编译生成处理 protobuf 相关的代码的路径, 这里生成到当前目录
--grpc_python_out=. : 编译生成处理 grpc 相关的代码的路径, 这里生成到当前目录
-I. helloworld.proto : proto 文件的路径, 这里的 proto 文件在当前目录
复制代码

4. 生成如下文件

helloworld_pb2.py: 用来和 protobuf 数据进行交互

helloworld_pb2_grpc.py: 用来和 grpc 进行交互

image.png

创建新的文件用来启动grpc服务

服务器端: helloworld_grpc_server.py

from concurrent import futures
import time
import grpc
import hello_pb2
import hello_pb2_grpc

# 实现 proto 文件中定义的 HelloWorldServiceServicer
class Greeter(hello_pb2_grpc.HelloWorldServiceServicer):
    # 实现 proto 文件中定义的 rpc 调用
    def SayHello(self, request, context):
        return hello_pb2.HelloResponse(message = 'hello {msg}'.format(msg = request.name))


def serve():
    # 启动 rpc 服务
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    hello_pb2_grpc.add_HelloWorldServiceServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    try:
        while True:
            time.sleep(60*60*24) # one day in seconds
    except KeyboardInterrupt:
        server.stop(0)

if __name__ == '__main__':
    serve()
复制代码

python helloworld_grpc_server.py 启动服务

到此python服务端启动完成,监听50051端口

5. 生成前端代码

生成grpc-web client代码

在windows下处理起来比较麻烦,直接使用win10 子系统处理了,bash如下

# 下载protoc
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protoc-3.17.3-linux-x86_64.zip
# 解压
unzip protoc-3.17.3-linux-x86_64.zip -d protoc
cd protoc/
# 拷贝protoc.exe到path
sudo mv bin/protoc /usr/local/bin

cd ..

# 下载protoc-gen-grpc-web
wget https://github.com/grpc/grpc-web/releases/download/1.2.1/protoc-gen-grpc-web-1.2.1-linux-x86_64

sudo mv protoc-gen-grpc-web-1.2.1-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web

复制代码

生成代码

js版本:
protoc -I=. --js_out=import_style=commonjs:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. hello.proto

ts版本:
protoc -I=. --js_out=import_style=commonjs:. --grpc-web_out=import_style=typescript,mode=grpcwebtext:. hello.proto
复制代码

image.png

前端项目安装依赖

yarn add grpc-web
yarn add google-protobuf
复制代码

把生成的2个js文件直接丢到node_modules 里

Vue模板

<template>
  <div className="home">
    {{ message }}
  </div>
</template>

<script>
import { HelloRequest } from 'hello_pb'
import { HelloWorldServicePromiseClient } from 'hello_grpc_web_pb'

export default {
  name: 'Home',
  data () {
    return {
      message: ''
    }
  },
  methods: {
    // 获取消息(使用async await)
    async getMessage () {
      // 注意这个端口是代理服务器的端口,不是grpc的端口
      var client = new HelloWorldServicePromiseClient('http://localhost:8080', null, null)

      // simple unary call
      var request = new HelloRequest()
      request.setName('World')

      // eslint-disable-next-line handle-callback-err
      const res = client.sayHello(request, {}, (err, response) => {
        // document.getElementById('response').innerHTML = response.getMessage()
      })
      res.then(res => {
        console.log(res)
      })
    }
  },
  mounted () {
    this.getMessage()
  }
}
</script>
复制代码

6. 部署代理

由于Grpc使用的Http2 这里需要部署一代理进行处理,同时解决跨域问题

github.com/improbable-…

grpcwebproxy-v0.14.0-win64.exe --backend_addr=localhost:50051 --run_tls_server=false --allow_all_origins

image.png

7. 愉快运行

最后就可以愉快的进行交互了

image.png

后续我还会在学习学习用法….

参考文章:

segmentfault.com/a/119000002…

www.fenxianglu.cn/article/285

www.jianshu.com/p/43fdfeb10…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享