go语言gRPC简单例子

一个简单的用go语言开发gRPC程序例子。

安装gRPC

gRPC的安装需要3块内容

1. 安装gRPC环境

这个环境包括gRPC编译运行时刻需要的库。

$ go get google.golang.org/grpc

2. 安装 Protocol Buffers v3

这个是protoc编译器, 用来编译.proto文件生成gRPC服务的go代码。

直接从下面链接下载二进制发布包即可:
https://github.com/google/protobuf/releases

选择平台对应的zip包
protoc--.zip

解开之后在bin目录下面会有一个protoc可执行文件

3. 安装protoc plugin for Go

这个工具在go编译protoc文件的时候需要用到。

$ go get -u github.com/golang/protobuf/protoc-gen-go

安装完之后可执行程序protoc-gen-go会存放在$GOROOT/bin或者$GOPATH/bin下面。

一个ToUpper的例子

这个例子是一个ToUpper程序,接收客户端请求包含一个传入字符串参数,服务端返回大写字符串。

1. 定义protoc文件

$ cat proto/toupper.proto 
syntax = "proto3";

package proto;

// The service definition.
service ToUpper{
  // Sends a greeting
  rpc Upper (UpperRequest) returns (UpperReply) {}
}

// The request message
message UpperRequest {
  string name = 1;
}

// The response message
message UpperReply {
  string message = 1;
}

定义了一个ToUpper服务,定义了两个消息UpperRequest和UpperReply分别用来接收和回复消息。

2. 定义服务端代码

$ cat main/server.go 
package main

import (
    "log"
    "net"
    "strings"

    "golang.org/x/net/context"
    "google.golang.org/grpc"
 pb "toupper/proto"
    "google.golang.org/grpc/reflection"
)

const (
    port = ":50051"
)

type server struct{}

func (s *server) Upper(ctx context.Context, in *pb.UpperRequest) (*pb.UpperReply, error) {
    log.Printf("Received: %s", in.Name)
    return &pb.UpperReply{Message: strings.ToUpper(in.Name)}, nil
}

func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterToUpperServer(s, &server{})
    // Register reflection service on gRPC server.
    reflection.Register(s)
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

3. 客户端代码

$ cat main/client.go 
package main

import (
    "log"
    "os"

    "golang.org/x/net/context"
    "google.golang.org/grpc"
 pb "toupper/proto"
)

const (
    address     = "localhost:50051"
)

func main() {
  // Set up a connection to the server.
    conn, err := grpc.Dial(address, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewToUpperClient(conn)

    // Contact the server and print out its response.
    name := "hello world"
    if len(os.Args) > 1 {
        name = os.Args[1]
    }
    r, err := c.Upper(context.Background(), &pb.UpperRequest{Name: name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Response: %s", r.Message)
}

工程目录结构如下

toupper
├── main
│   ├── client.go
│   └── server.go
├── makefile
└── proto
    └── toupper.proto

makefile文件

$ cat makefile 

PB=proto/toupper.pb.go

all: client server

server: $(PB)
    go build main/server.go
client: $(PB)
    go build main/client.go
$(PB):
    protoc -I proto toupper.proto --go_out=plugins=grpc:proto

clean:
    rm -f $(PB) client server

编译

$ make
protoc -I proto toupper.proto --go_out=plugins=grpc:proto
go build main/client.go
go build main/server.go

注意在编译前需要把前面安装的protoc和protoc-gen-go设置到PATH环境变量。
编译完总共会生成3个文件:

  1. proto/toupper.pb.go
  2. 可执行文件client, 和
  3. 可执行文件server

运行

在终端直接运行server:

$ ./server 

在另一个终端运行client:

$ ./client 
2017/10/27 15:54:10 Response: HELLO WORLD
$ ./client abcd
2017/10/27 15:54:14 Response: ABCD

这时我们可以看到在服务端的输出:

2017/10/27 15:54:10 Received: hello world
2017/10/27 15:54:14 Received: abcd

参考

https://grpc.io/docs/quickstart/go.html

你可能感兴趣的:(go语言gRPC简单例子)