1.protocl buffer一種高效的序列化結構。
2.支持http 2.0標準化協議。python
1.http/2對每一個源只需建立一個持久鏈接,在這一個鏈接內,能夠並行的處理多個請求和響應,並且作到不相互影響。
2.容許客戶端和服務端實現本身的數據流和鏈接流控制,這對咱們傳輸大數據很是有幫助。linux
這裏咱們須要使用 protobuf 解釋器 將 protobuf 語法的代碼轉化成對應語言的代碼,以及使用 grpc 實現跨越性,因此咱們須要先安裝它們。
本教程中只會用到 python3 以及 golang ,因此咱們只安裝這兩個語言的解釋器就足夠了git
安裝 grpc 庫github
pip3 install grpcio
安裝 grpc 工具 以及 protobuf 解釋器golang
pip3 install grpcio-tools googleapis-common-protos
安裝 grpc 庫:api
go get -u -v google.golang.org/grpc
而後從 https://github.com/protocolbuffers/protobuf/releases 下載 與你操做系統對應的 protobuf 解釋器,這裏選擇的 linux64 進行下載
首先新建一個目錄用來容納下載安裝包解壓後的文件,並進入目錄app
mkdir protobuf && cd protobuf
下載 protobuf 解釋器tcp
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protoc-3.6.1-linux-x86_64.zip
解壓縮下載的文件工具
unzip protoc*.zip
刪除剛纔下載好的壓縮包大數據
rm protoc*.zip
移動 protobuf 目錄到 ~/.local
mv ~/protobuf/ ~/.local/
將 protobuf 的可執行文件添加進系統變量
echo "PATH=\"\$HOME/.local/protobuf/bin:\$PATH\"" >> ~/.profile
安裝 protobuf go 語言的插件
go get -u github.com/golang/protobuf/protoc-gen-go
將插件添加進系統變量
echo "PATH=\$PATH:\$GOPATH/bin" >> ~/.profile
而後使用 cd 命令回到用戶根目錄
cd
建立工程目錄並進入目錄
mkdir $GOPATH/src/demo && cd $GOPATH/src/demo
proto 文件爲 protobuf 的擴展名,咱們編寫這個文件用於生成 python 與 go 都支持的代碼。
這裏咱們再新建一個目錄用來容納 proto 文件以及 使用 protobuf 編譯器轉化過的代碼
建立目錄並進入目錄
mkdir hello && cd hello
接下來開始編寫 proto 文件,這裏咱們新建一個 名爲 hello.proto 的文件並在裏面寫入如下內容
syntax = "proto3"; //指定語法爲 protobuf3 語法,若是不寫這句的話默認語法爲 protobuf2 package hello; //指定包名,這句在本次演示中只對 go 生效,python 的 protobuf 解釋器會忽略它 service Greeter { // 定義grpc 遠程調用的方法 rpc SayHello (HelloRequest) returns (HelloReply) {} // 接受 HelloRequest 返回 HelloReply,SayHello 須要本身在服務端實現 } message HelloRequest { //定義一個消息類型 string name = 1; //定義 name 字段爲 string 類型 tag 爲 1 } message HelloReply { string message = 1; }
完成後保存並退出編輯
編輯好 proto 文件後咱們並不能直接使用它,還須要將它轉化成對應語言的代碼才能使用
生成 go 語言的代碼
protoc hello.proto --go_out=plugins=grpc:.
生成 python 的代碼
python3 -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. hello.proto
而後咱們回到 demo 工程目錄,開始真正的 代碼編寫
cd ..
服務端端這裏我採用的 go 語言進行編寫
建立一個名爲 server.go 的文件並寫入如下內容
package main import ( "context" "google.golang.org/grpc" "google.golang.org/grpc/reflection" "log" "demo/hello" "net" ) const ( port = ":50051" // 監聽端口 ) type server struct{} func (s *server) SayHello(ctx context.Context, in *hello.HelloRequest) (*hello.HelloReply, error) { // 服務端實現 proto 中定義的方法 return &hello.HelloReply{Message: "Hello " + in.Name}, nil //拼接客戶端發送過來的消息,並返回給客戶端 } func main() { lis, err := net.Listen("tcp", port) // 啓動監聽 if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() hello.RegisterGreeterServer(s, &server{}) reflection.Register(s) // 在 grpc 上註冊服務 if err := s.Serve(lis); err != nil { //啓動服務並處理錯誤 log.Fatalf("failed to server: %v", err) } }
客戶端我採用的 python3 進行編寫
建立一個名爲 client.py 的文件寫入如下內容
#! /usr/bin/env python3 # -*- coding: utf-8 -*- import grpc # 導入 grpc 模塊 import sys sys.path.append('hello') # 將 hello 目錄臨時添加進環境變量,否則接下來的導入會失敗 import hello_pb2 #導入咱們剛纔從 helloWorld.proto 生成的 python 代碼 import hello_pb2_grpc def run(): with grpc.insecure_channel('localhost:50051') as channel: # 建立鏈接到服務端的通道 stub = hello_pb2_grpc.GreeterStub(channel) #建立提供調用的存根 response = stub.SayHello(hello_pb2.HelloRequest(name = 'niconiconi')) #調用 SayHello 方法 發送咱們剛纔在 proto 文件中定義的字段,返回咱們在 proto 中定義的返回值 print("Greeter client received: " + response.message) #打印返回值 if __name__ == '__main__': run()
首先咱們啓動服務端
go run server.go
使用 CTRL + z 將 正在運行的服務端掛起在後臺,而後使用 bg命令使掛起的 程序繼續運行。
接下來運行咱們編寫的客戶端
python3 client.py
不出意外的話你的屏幕上應該會打印
Greeter client received: Hello niconiconi
到這裏 演示就所有結束了。