環境
-
go版本要求: go 1.6及以上
C:\> go version go version go1.12 windows/amd64
-
設置goproxy及go mod開啓(win cmd)
set GOPROXY=https://goproxy.io set GO111MODULE=on
-
安裝protoc編譯工具(protobuf轉成相應語言代碼的工具)
下載: https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protoc-3.9.1-win64.zip
並配置protoc到PATH環境變量
驗證protoc是否安裝成功:C:\>protoc --version libprotoc 3.9.1
-
相關sdk下載
go get -u google.golang.org/grpc go get -u github.com/golang/protobuf/protoc-gen-go # protoc生成go語言的插件
簡單示例
我們以一個"計算器"的例子來入門grpc在go語言中的使用:
示例項目(calculator)結構如下:
D:\workspace\test\grpc\calculator
│ go.mod
│ go.sum
│
├─client
│ client.go
│
├─protobuf
│ calculator.pb.go
│ calculator.proto
│
└─server
server.go
定義service(calculator.proto)
syntax = "proto3"; // 使用protobuf版本3
option go_package = "protobuf"; // 這個影響生成的目錄及go的package命名
// 定義一個計算服務, 輸入爲CalcRequest, 輸出爲CalcResponse
service CalculatorService {
rpc calc(CalcRequest) returns (CalcResponse) {};
}
// 計算兩個數某種運算(如加法)的參數
message CalcRequest {
double a = 1;
double b = 2;
string op = 3;
}
// 計算結果
message CalcResponse {
double r = 1;
}
// cd path/to/calculator
// protoc -I .\protobuf --go_out=plugins=grpc:.\protobuf .\protobuf\calculator.proto
生成.pb.go文件
進入到項目根目錄(calculator根目錄), 執行:
protoc -I .\protobuf --go_out=plugins=grpc:.\protobuf .\protobuf\calculator.proto
則會在calculator/protobuf目錄下生成.pb.go文件
實現rpc service
新建文件: calculator/server/server.go, 內容如下:
package main
import (
"calculator/protobuf"
"context"
"fmt"
"google.golang.org/grpc"
"net"
)
// 實現: CalculatorServiceServer接口, 在calculator.pb.go中定義
type server struct {}
func (server) Calc(ctx context.Context, req *protobuf.CalcRequest) (resp *protobuf.CalcResponse, err error) {
a := req.GetA()
b := req.GetB()
op := req.GetOp()
resp = &protobuf.CalcResponse{}
switch op {
case "+":
resp.R = a + b
case "-":
resp.R = a - b
case "*":
resp.R = a * b
case "/":
if b == 0 {
err = fmt.Errorf("divided by zero")
return
}
resp.R = a / b
}
return
}
// 啓動rpc server
func main() {
listener, err := net.Listen("tcp", "localhost:3233")
if err != nil {
panic(err)
}
s := grpc.NewServer()
protobuf.RegisterCalculatorServiceServer(s, &server{})
fmt.Println("server start")
err = s.Serve(listener)
if err != nil {
panic(err)
}
}
生成go.mod
進到項目根目錄執行:
go mod init calculator
go mod tidy
客戶端調用示例
新建文件: calculator/client/client.go, 內容如下:
package main
import (
"calculator/protobuf"
"context"
"fmt"
"google.golang.org/grpc"
"log"
)
func main() {
// 連上grpc server
conn, err := grpc.Dial("localhost:3233", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := protobuf.NewCalculatorServiceClient(conn)
// 調用遠程方法
resp, err := c.Calc(context.Background(), &protobuf.CalcRequest{
A: 1,
B: 2,
Op: "+",
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(resp.GetR()) // 3
resp, err = c.Calc(context.Background(), &protobuf.CalcRequest{
A: 1,
B: 0,
Op: "/",
})
if err != nil { // 如果有error, 說明此次調用不成功, 作相應處理
fmt.Println(err) // rpc error: code = Unknown desc = divided by zero
return
}
fmt.Println(resp.GetR())
}
運行結果
開兩個cmd窗口, 一個進到server目錄, 執行go run server.go
來啓動rpc服務.
一個進到client目錄, 執行go run client.go
, 效果如下圖:
資源下載
上述示例可在這裏下載.
參考
https://grpc.io/docs/quickstart/go/
https://developers.google.com/protocol-buffers/docs/proto3