(一)環(huán)境搭建
1.安裝protoc工具
地址:https://github.com/protocolbuffers/protobuf/releases
找到需要的版本贮折,windows的下載protoc-3.12.4-win64.zip(版本可自行選擇)
或protoc-3.12.4-win32.zip(版本可自行選擇),找個(gè)地方解壓,然后將bin加入path
2.安裝protoc-gen-go 插件
地址:https://github.com/protocolbuffers/protobuf-go
下載成功后,然后進(jìn)入 protobuf-go\cmd\protoc-gen-go 目錄
執(zhí)行g(shù)o install 吭从,此時(shí)protoc-gen-go已經(jīng)安裝在gopath/bin 目錄下了
3.安裝protoc-gen-go-grpc 插件
地址:https://github.com/grpc/grpc-go
下載成功后,進(jìn)入grpc-go\cmd\protoc-gen-go-grpc目錄
執(zhí)行g(shù)o install 此時(shí)protoc-gen-go-grpc已經(jīng)安裝在gopath/bin 目錄下了
至此環(huán)境搭建已經(jīng)成功了恶迈,需要注意的是涩金,本人已將gopath加入path環(huán)境變量,如果不加入的話暇仲,可以自行將相關(guān)插件加入path
(二)入門
1.搭建server端
找個(gè)地方建個(gè)server文件夾(不要放在gopath下面)
進(jìn)入server目錄執(zhí)行g(shù)o mod init server (建立module)
在server目錄下面建個(gè)pb文件夾(此文件夾放.proto文件)
在pb文件夾下面建個(gè)arith.proto文件步做,內(nèi)容如下:
syntax?=?"proto3";
package?pb;
option?go_package?=?".;pb";
message?ArithRequest?{
????double??num1?=?1;
????double??num2?=?2;
}
message?ArithResponse?{
????double?result?=?1;
}
service?Arith?{
????rpc?multiply?(ArithRequest)?returns?(ArithResponse);???
????rpc?divide?(ArithRequest)?returns?(ArithResponse);
}
在pb目錄下執(zhí)行
protoc --go_out=. --plugin=grpc .\arith.proto
protoc --go-grpc_out=requireUnimplementedServers=false:. .\arith.proto
以上兩條是根據(jù)proto文件自動(dòng)生成go文件,至于proto的書寫規(guī)則奈附,去網(wǎng)上看看就知道了
回到server目錄下全度,建個(gè)server.go文件,內(nèi)容如下:
package?main
import?(
????"context"
????"errors"
????"log"
????"net"
????"server/pb"
????"google.golang.org/grpc"
)
type?Arith?struct{}
//乘法
func?(m?*Arith)?Multiply(ctx?context.Context,?req?*pb.ArithRequest)?(resp?*pb.ArithResponse,?err?error)?{
????resp?=?new(pb.ArithResponse)
????resp.Result?=?req.Num1?*?req.Num2
????return?resp,?nil
}
//?除法
func?(m?*Arith)?Divide(ctx?context.Context,?req?*pb.ArithRequest)?(resp?*pb.ArithResponse,?err?error)?{
????resp?=?new(pb.ArithResponse)
????if?req.Num2?==?0?{
????????return?nil,?errors.New("the dividend is 0")
????}
????resp.Result?=?req.Num1?/?req.Num2
????return?resp,?nil
}
func?main()?{
????lis,?err?:=?net.Listen("tcp",?"127.0.0.1:8888")
????if?err?!=?nil?{
????????log.Fatal("failed?to?listen:?%v",?err)
????}
????s?:=?grpc.NewServer()
????pb.RegisterArithServer(s,?&Arith{})
????log.Println("proto?server?start")
????err?=?s.Serve(lis)
????if?err?!=?nil?{
????????log.Fatal(err)
????}
}
在server目錄下執(zhí)行?go?run?server.go桅狠,服務(wù)端就建立起來了
2.搭建client客戶端
建個(gè)client文件夾讼载,進(jìn)入client目錄執(zhí)行?go?mod?init?client,建立pb文件夾中跌,進(jìn)入pb目錄,將server>pb>arith.proto文件拷貝至此菇篡,然后執(zhí)行
protoc --go_out=. --plugin=grpc .\arith.proto
protoc --go-grpc_out=requireUnimplementedServers=false:. .\arith.proto
然后在client目錄下面新建client.go文件漩符,內(nèi)容如下:
package?main
import?(
????"context"
????"log"
????"time"
????pb?"client/pb"
????"google.golang.org/grpc"
)
func?main()?{
? ? conn,?err?:=?grpc.Dial("localhost:8888",?grpc.WithInsecure(),?grpc.WithBlock())
????if?err?!=?nil?{
????????log.Fatalf("did?not?connect:?%v",?err)
????}
????defer?conn.Close()
????c?:=?pb.NewArithClient(conn)
????ctx,?cancel?:=?context.WithTimeout(context.Background(),?time.Second)
????defer?cancel()
????r,?err?:=?c.Multiply(ctx,?&pb.ArithRequest{Num1:?1.0,?Num2:?2.0})
????if?err?!=?nil?{
????????log.Fatal(err)
????}
????log.Printf("result:?%f",?r.Result)
????ctx2,?cancel2?:=?context.WithTimeout(context.Background(),?time.Second)
????defer?cancel2()
????r,?err?=?c.Divide(ctx2,?&pb.ArithRequest{Num1:?1.0,?Num2:?2.0})
????if?err?!=?nil?{
????????log.Fatal(err)
????}
????log.Printf("result:?%f",?r.Result)
}
然后執(zhí)行 go run client.go,就會(huì)得到結(jié)果:
2020/08/04 18:34:41 result: 2.000000
2020/08/04 18:34:41 result: 0.500000