師父給了我一個 .proto 文件,我應該怎么使用?
回想我年輕的時候,在做一個項目時,需要計算斐波那契數(shù)列第 n 項的值。但是我只會使用遞歸來實現(xiàn)。眾所周知,遞歸算法計算斐波那契數(shù)列的效率極差,速度極慢。
于是我求助于當時我的師父,問他有沒有辦法幫我解決這個問題。
我?guī)煾刚f:“有啊,我寫過,但是代碼是用C++ 寫的,你估計看不懂。不過沒關系,你用 Python 直接調用就可以了。”
我很驚訝:“用 Python 直接調用C++代碼嗎?看起來似乎很麻煩啊。”
師父說:“一點也不麻煩。我給你一個.proto 文件和一個地址,你拿去自動生成代碼就能調用了。”
于是,我拿到了一個mentors_secret.proto文件,里面的內容非常簡單:
- syntax = "proto3";
- message NumToCalc {
- int32 num = 1;
- }
- message Result {
- int32 result = 1;
- string msg = 2;
- bool success = 3;
- }
- service MentorsSecret {
- rpc CalcFib(NumToCalc) returns (Result) {}
- }
還有一個地址:122.51.39.219:8766。
原來是使用 gRPC 啊。這樣我就知道怎么做了。
安裝環(huán)境
首先,我們先安裝Python 版本的gRPC:
- pip install grpcio grpcio-tools
生成代碼
接下來,基于這個mentors_secret.proto文件,自動生成代碼。cd進入mentors_secret.proto文件所在的文件,執(zhí)行下面的命令:
- python3 -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. ./mentors_secret.proto
此時,可以看到當前文件夾中生成了兩個文件:mentors_secret_pb2.py和mentors_secret_pb2_grpc.py。
如下圖所示:
這兩個文件的內容,不需要看。
調用遠程服務
接下來,創(chuàng)建一個新文件,叫做client.py,用來調用遠程的函數(shù):
- import grpc
- from mentors_secret_pb2 import NumToCalc
- from mentors_secret_pb2_grpc import MentorsSecretStub
- channel = grpc.insecure_channel('122.51.39.219:8766')
- stub = MentorsSecretStub(channel)
- result = stub.CalcFib(NumToCalc(num=36))
- print('斐波那契數(shù)列第36像是:', result.result)
代碼加上空行總共只有10行。1-3行導入模塊,6,7行創(chuàng)建遠程鏈接。第9行調用遠程的函數(shù)。第10行打印結果。
我們來看看運行效果:
運行結果秒出。
總結
當我們拿到一個.proto文件,需要去調用gRPC 服務時,我們一般有如下步驟:
(1) 自動生成mentors_secret_pb2.py和mentors_secret_pb2_grpc.py文件。
(2) 查看.proto文件里面,service后面的名字MentorsSecret,如下圖所示:
(3) 編寫固定的代碼:
- import grpc
- from mentors_secret_pb2_grpc import MentorsSecretStub # service 名字后面加上 Stub
- channel = grpc.insecure_channel('遠程服務地址和 端口')
- stub = MentorsSecretStub(channel)
(4) 調用遠程函數(shù)。通過.proto文件,可以知道遠程函數(shù)CalcFib接收一個參數(shù)NumToCalc,所以把它導入進來:from mentors_secret_pb2 import NumToCalc,它里面的參數(shù)為num,所以調用遠程服務時賦值:
- para = NumToCalc(num=36)
- calc_result = stub.CalcFib(para)
(5) 從.proto知道返回的結果是Result里面的result屬性。于是打印calc_result.result獲得結果。