從0到1:帶你完整寫一個 Golang Grpc 服務
# 1. 環境準備
第一步:安裝 protoc
前往 protobuf,下載最新版的 protoc ,我下載的是 win 64
第二步:安裝 protoc-gen-go
前往 protobuf-go ,同樣下載最新版的 protoc,同樣下載的是 win 64
將下載后的 protoc.exe 和 protoc-gen-go 放到 %GOPATH%\bin\ 目錄下。
或者更簡單的方法,直接執行如下命令就可以安裝
- go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
第三步:下載 grpc
- # 安裝 grpc
- go get -u google.golang.org/grpc
- # gRPC運行時接口編解碼支持庫
- go get -u github.com/golang/protobuf/proto
# 2. 項目目錄結構
在 $GOPATH/src 下新建 iswbm.com 目錄及三個子目錄(client,server,proto),在終端上進入該目錄,執行如下命令創建 go.mod
- mkdir $GOPATH/src/iswbm.com/{client,server,proto}
- cd mkdir $GOPATH/src/iswbm.com/
- # 設置環境變量,確保 GO111MODULE 是開啟的
- go env -w GO111MODULE=auto
- # 初始化項目
- go mod init
# 3. 編寫 proto 文件
編寫 proto/simple.proto
- syntax = "proto3";
- package proto;
- option go_package ="/proto";
- // 定義發送請求信息
- message SimpleRequest{
- // 參數類型 參數名稱 標識號
- string data = 1;
- }
- // 定義響應信息
- message SimpleResponse{
- int32 code = 1;
- string value = 2;
- }
- // 定義我們的服務(可以定義多個服務,每個服務可以定義多個接口)
- service Simple{
- rpc GetSimpleInfo(SimpleRequest) returns (SimpleResponse){};
在 iswbm.com 目錄下,執行如下命令
- protoc --go_out=. ./proto/simple.proto
- protoc --go-grpc_out=. ./proto/simple.proto
完成后,會在當前目錄下生成一個 simple 目錄,該目錄下有一個 simple.pb.go 和 simple_grpc.pb.go
# 4. 編寫 server.go
- package main
- import (
- "context"
- pb "iswbm.com/proto"
- "google.golang.org/grpc"
- "log"
- "net"
- )
- const (
- Address string = ":8000"
- Network string = "tcp"
- )
- // 定義我們的服務
- type SimpleService struct{
- pb.UnimplementedSimpleServer
- }
- // 實現 GetSimpleInfo 方法
- func (s *SimpleService) GetSimpleInfo(ctx context.Context, req *pb.SimpleRequest) (*pb.SimpleResponse, error) {
- data := req.Data
- log.Println("get from client: ", data)
- resp := &pb.SimpleResponse{
- Code: 8888,
- Value: "grpc",
- }
- return resp, nil
- }
- func main() {
- // 1.監聽端口
- listener, err := net.Listen(Network, Address)
- if err != nil {
- log.Fatalf("net.listen err: %v", err)
- }
- log.Println(Address, " net listening...")
- // 2.實例化gRPC服務端
- grpcServer := grpc.NewServer()
- // 3.注冊我們實現的服務 SimpleService
- pb.RegisterSimpleServer(grpcServer, &SimpleService{})
- // 4.啟動gRPC服務端
- err = grpcServer.Serve(listener)
- if err != nil {
- log.Fatalf("grpc server err: %v",err)
- }
- }
完成后,先安裝依賴包
- go install
執行如下命令運行服務端
- > go run server/server.go
- 2021/07/28 18:31:42 :8000 net listening...
# 5. 編寫 client.go
- package main
- import (
- "context"
- "google.golang.org/grpc"
- "log"
- pb "iswbm.com/proto"
- )
- const (
- Address string = ":8000"
- )
- func main() {
- // 1.創建于gRPC服務端的連接
- conn, err := grpc.Dial(Address, grpc.WithInsecure())
- if err != nil {
- log.Fatalf("dial conn err: %v", err)
- }
- defer conn.Close()
- // 2.創建grpc客戶端
- client := pb.NewSimpleClient(conn)
- // 3.調用服務端提供的服務
- req := pb.SimpleRequest{
- Data: "Hello,Server",
- }
- resp, err := client.GetSimpleInfo(context.Background(), &req)
- if err != nil {
- log.Fatalf("resp err: %v", err)
- }
- log.Printf("get from server,code: %v,value: %v", resp.Code, resp.Value)
- }
執行如下命令運行,立馬就能收到來自 server 返回的消息
- > go run client/client.go
- 2021/07/28 18:54:35 get from server,code: 8888,value: grpc
同時,在 server 端也會打印來自 client 端的消息
- > go run server/server.go
- 2021/07/28 18:51:59 :8000 net listening...
- 2021/07/28 18:54:35 get from client: Hello,Server