gRPC接口定义语言使用及代码编译

最近学习了一下gRPC的使用,所以记录一下

(一)定义*.proto文件,用于生成 gRPC server 和 client使用的代码

// 声明语法版本
syntax = "proto3";
// 定义请求消息体名称和具体消息内容
message PingTask {
    string command = 1;		// 代表在消息体的第一个位置
    string host = 2;				// 代表在消息体的第二个位置
    int32 times = 3;
    string queue = 4;
    string exchange = 5;
}
// 定义响应消息体
message PingRes {
    string response = 1;
}
// 定义RPC服务
service RenderServer {
	// 定义RPC服务接口,需要传入请求消息体和响应消息体
    rpc Ping(PingTask) returns (PingRes) {}
}

(二)代码生成

安装protobuf编译器和grpc库:

pip install grpcio-tools

切换到*.proto文件目录下,编译生成代码:

python -m grpc_tools.protoc -I. --python_out=.. --grpc_python_out=.. itcast.proto
  • -I表示搜索proto文件中被导入文件的目录
  • --python_out表示保存生成Python文件的目录,生成的文件中包含接口定义中的数据类型
  • --grpc_python_out表示保存生成Python文件的目录,生成的文件中包含接口定义中的服务类型

(三)server和client端代码

client.py

# client.py
import render_pb2
import render_pb2_grpc

def invoke_ping(stub, body):
    command = body['command']
    host = body['host']
    times = body['times']
    log_queue = body['logs_queue']
    log_exchange = body['logs_exchange']
    # 构造PingTask请求消息体
    ping_task = render_pb2.PingTask(command=command, host=host, 
   									times=times, queue=log_queue, 
   									exchange=log_exchange)
    # 调用远程服务器的Ping()接口
    res = stub.Ping(ping_task)
    print(res.response)
    
if __name__ == '__main__': 
	with grpc.insecure_channel("你的远程服务器的ip:port") as channel:
	        stub = render_pb2_grpc.RenderServerStub(channel)
	        # 构造PingTask请求消息体需要的数据
	        body = {}
	        invoke_ping(stub, body)

server.py

import render_pb2
import render_pb2_grpc
import grpc
from concurrent import futures

class RenderServer(render_pb2_grpc.RenderServerServicer):
    def __init__(self):
        self.os_platform = platform.system()
    # context 用来处理gRPC响应的statuscode
	def Ping(self, request, context):
	        command = request.command
	        host = request.host
	        times = request.times
	        log_queue = request.queue
	        log_exchange = request.exchange
	        # 根据操作系统不同构建命令
	        if self.os_platform == 'Windows':
	            command = '{command} -n {times} {host}'.format(command=command, host=host, times=times)
	        elif self.os_platform == 'Linux':
	            command = '{command} -c {times} {host}'.format(command=command, host=host, times=times)
	
	        command = 'python ping_script.py -c "{command}" -q {log_queue} -e {exchange}'.format(
	            command=command,
	            log_queue=log_queue,
	            exchange=log_exchange
	        )
	
	        print("收到命令:{}".format(command))
	        print("开启一个异步进程去执行脚本,不会收到主进程的影响")
	        # 返回结果
	        return render_pb2.PingRes(response="任务正在处理")

def run_server(host=None, port=8888):
    # 多线程服务器
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    # 注册本地服务
    render_pb2_grpc.add_RenderServerServicer_to_server(RenderServer(), server)
    # 监听端口
    server.add_insecure_port('{}:{}'.format(host, port))
    # 开始接收请求进行服务
    server.start()
    # 使用 ctrl+c 可以退出服务
    try:
        time.sleep(1000)
    except KeyboardInterrupt:
        server.stop(0)

if __name__ == '__main__':
    print("开启RPC服务,正在监听8888端口")
    ip = get_host_ip()
    run_server(ip)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值