Golang gRPC實踐 連載二 Hello gRPC

Hello gRPC

按照慣例,這裏從一個Hello項目開始,本項目定義了一個Hello Service,客戶端發送包含字符串名字的請求,服務端返回Hello消息。git

流程:

  1. 編寫.proto描述文件github

  2. 編譯生成.pb.go文件golang

  3. 服務端實現約定的接口並提供服務tcp

  4. 客戶端按照約定調用方法請求服務google

項目目錄:

$GOPATH/src/grpc-go-practice/

example/
|—— hello/
    |—— client/
        |—— main.go   // 客戶端
    |—— server/
        |—— main.go   // 服務端
|—— proto/
    |—— hello.proto   // proto描述文件
    |—— hello.pb.go   // proto編譯後文件

示例代碼

描述文件:proto/hello.proto

syntax = "proto3"; // 指定proto版本

package proto;     // 指定包名

// 定義Hello服務
service Hello {
    // 定義SayHello方法
    rpc SayHello(HelloRequest) returns (HelloReply) {}
}

// HelloRequest 請求結構
message HelloRequest {
    string name = 1;
}

// HelloReply 響應結構
message HelloReply {
    string message = 1;
}

hello.proto文件中定義了一個Hello Service,該服務包含一個SayHello方法,同時聲明瞭HelloRequestHelloReply消息結構用於請求和響應。客戶端使用HelloRequest參數調用SayHello方法請求服務端,服務端響應HelloReply消息。protobuf的語法後面會詳細介紹,這裏先不用過多糾結。code

編譯生成.pb.go文件:

# 編譯hello.proto
protoc -I . --go_out=plugins=grpc:. ./hello.proto

生成的.pb.go文件,按照.proto文件中的說明,包含服務端接口HelloServer描述,客戶端接口及實現HelloClient,及HelloRequestHelloResponse結構體,不要手動編輯該文件server

實現服務端接口:server/main.go

package main

import (
    "net"

    pb "go-grpc-practice/example/proto" // 引入編譯生成的包

    "golang.org/x/net/context"
    "google.golang.org/grpc"
    "google.golang.org/grpc/grpclog"
)

const (
    // Address gRPC服務地址
    Address = "127.0.0.1:50052"
)

// 定義helloService並實現約定的接口
type helloService struct{}

// HelloService ...
var HelloService = helloService{}

func (h helloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    resp := new(pb.HelloReply)
    resp.Message = "Hello " + in.Name + "."

    return resp, nil
}

func main() {
    listen, err := net.Listen("tcp", Address)
    if err != nil {
        grpclog.Fatalf("failed to listen: %v", err)
    }

    // 實例化grpc Server
    s := grpc.NewServer()

    // 註冊HelloService
    pb.RegisterHelloServer(s, HelloService)

    grpclog.Println("Listen on " + Address)

    s.Serve(listen)
}

運行:接口

go run main.go

Listen on 50051  //服務端已開啓並監聽50051端口

服務端引入編譯後的proto包,實現約定的接口,接口描述能夠查看hello.pb.go文件中的HelloServer接口描述。實例化grpc Server並註冊HelloService,開始提供服務。字符串

客戶端調用:client/main.go

package main

import (
    pb "go-grpc-practice/example/proto" // 引入proto包

    "golang.org/x/net/context"
    "google.golang.org/grpc"
    "google.golang.org/grpc/grpclog"
)

const (
    // Address gRPC服務地址
    Address = "127.0.0.1:50052"
)

func main() {
    // 鏈接
    conn, err := grpc.Dial(Address, grpc.WithInsecure())

    if err != nil {
        grpclog.Fatalln(err)
    }

    defer conn.Close()

    // 初始化客戶端
    c := pb.NewHelloClient(conn)

    // 調用方法
    reqBody := new(pb.HelloRequest)
    reqBody.Name = "gRPC"
    r, err := c.SayHello(context.Background(), reqBody)
    if err != nil {
        grpclog.Fatalln(err)
    }

    grpclog.Println(r.Message)
}

運行:rpc

go run main.go

Hello gRPC     // 接收到服務端響應

客戶端初始化鏈接後直接調用聲明的方法,便可向服務端發起請求,使用姿式就像調用本地方法同樣。若是你收到了"Hello gRPC"的回覆,恭喜你已經會使用go-gRPC了。

下節將詳細介紹protobuf的語法,並詳細解析protobuf聲明與編譯後golang代碼的對應關係。

參考

本系列示例代碼

相關文章
相關標籤/搜索