[Series] Go gRPC Hello World

Outline

GRPC the beginning, learning to use this article gRPC, output a Hello World.

  • Implement server gRPC with Go.
  • Go with the realization gRPC clients.

gRPC supports four types of service method, and this time we will realize individual RPC server-side streaming RPC.

Four categories of service method

Individual RPC

The server sends a request to the server, gets a response from the server, just like a normal function call.

rpc SayHello(HelloRequest) returns (HelloResponse){}

RPC server streaming

The client sends a request to the server, can obtain a series of data flow to read the message. The client has been read from the returned data stream until no more news so far.

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}

Streaming client RPC

A client data stream is written and provided with a series of messages sent to the server. Once the client has completed message is written, it will wait for the server to read the message and returns a response.

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}

Two-way flow RPC

Both sides can be transmitted separately flow through a series of messages read and write data. The two data streams is independent of the operation, so the client and server can read and write its desired any order, for example: the server may wait for all of the clients before the write reply message, or it may first read a message write a message, or other combination of reading and writing. Message in order for each data stream will be maintained.

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}

installation

Installation protobuf compiler

brew install protobuf

verification:

protoc --version

//输出:libprotoc 3.7.1

Go protobuf plug-in installation

go get -u github.com/golang/protobuf/proto

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

Installation grpc-go

go get -u google.golang.org/grpc

Write a Hello World Service

  • Write server .protofile
  • Generate server .pb.gofiles and synchronize to the client
  • Write server provides the interface code
  • The interface code to write client calls

Directory Structure

├─ hello  -- 代码根目录
│  ├─ go_client
│     ├── main.go
│     ├── proto
│         ├── hello
│            ├── hello.pb.go
│  ├─ go_server
│     ├── main.go
│     ├── controller
│         ├── hello_controller
│            ├── hello_server.go
│     ├── proto
│         ├── hello
│            ├── hello.pb.go
│            ├── hello.proto

This creates a directory for go_client and post go_server can be split into two projects.

Write file server hello.proto

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

package hello;     // 指定包名

// 定义 Hello 服务
service Hello {

    // 定义 SayHello 方法
    rpc SayHello(HelloRequest) returns (HelloResponse) {}

    // 定义 LotsOfReplies 方法
    rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}
}

// HelloRequest 请求结构
message HelloRequest {
    string name = 1;
}

// HelloResponse 响应结构
message HelloResponse {
    string message = 1;
}

For more Protobuf syntax, see:

https://developers.google.com/protocol-buffers/

Generation server .pb.go

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

While the generated hello.pb.gocopy to a client.

View more command parameters, perform protoc, see OPTION.

Write server provides the interface code

// hello_server.go
package hello_controller

import (
    "fmt"
    "golang.org/x/net/context"
    "hello/go_server/proto/hello"
)

type HelloController struct{}

func (h *HelloController) SayHello(ctx context.Context, in *hello.HelloRequest) (*hello.HelloResponse, error) {
    return &hello.HelloResponse{Message : fmt.Sprintf("%s", in.Name)}, nil
}

func (h *HelloController) LotsOfReplies(in *hello.HelloRequest, stream hello.Hello_LotsOfRepliesServer)  error {
    for i := 0; i < 10; i++ {
        stream.Send(&hello.HelloResponse{Message : fmt.Sprintf("%s %s %d", in.Name, "Reply", i)})
    }
    return nil
}
// main.go
package main

import (
    "log"
    "net"
    "hello/go_server/proto/hello"
    "hello/go_server/controller/hello_controller"
    "google.golang.org/grpc"
)

const (
    Address = "0.0.0.0:9090"
)

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

    s := grpc.NewServer()

    // 服务注册
    hello.RegisterHelloServer(s, &hello_controller.HelloController{})

    log.Println("Listen on " + Address)

    if err := s.Serve(listen); err != nil {
        log.Fatalf("Failed to serve: %v", err)
    }
}

run:

go run main.go

2019/07/28 17:51:20 Listen on 0.0.0.0:9090

Write the client requests the interface code

package main

import (
    "hello/go_client/proto/hello"
    "io"
    "log"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
)

const (
    // gRPC 服务地址
    Address = "0.0.0.0:9090"
)

func main() {
    conn, err := grpc.Dial(Address, grpc.WithInsecure())
    if err != nil {
        log.Fatalln(err)
    }
    defer conn.Close()

    // 初始化客户端
    c := hello.NewHelloClient(conn)

    // 调用 SayHello 方法
    res, err := c.SayHello(context.Background(), &hello.HelloRequest{Name: "Hello World"})

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

    log.Println(res.Message)

    // 调用 LotsOfReplies 方法
    stream, err := c.LotsOfReplies(context.Background(),&hello.HelloRequest{Name: "Hello World"})
    if err != nil {
        log.Fatalln(err)
    }

    for {
        res, err := stream.Recv()
        if err == io.EOF {
            break
        }

        if err != nil {
            log.Printf("stream.Recv: %v", err)
        }

        log.Printf("%s", res.Message)
    }
}

run:

go run main.go

2019/07/28 17:58:13 Hello World
2019/07/28 17:58:13 Hello World Reply 0
2019/07/28 17:58:13 Hello World Reply 1
2019/07/28 17:58:13 Hello World Reply 2
2019/07/28 17:58:13 Hello World Reply 3
2019/07/28 17:58:13 Hello World Reply 4
2019/07/28 17:58:13 Hello World Reply 5
2019/07/28 17:58:13 Hello World Reply 6
2019/07/28 17:58:13 Hello World Reply 7
2019/07/28 17:58:13 Hello World Reply 8
2019/07/28 17:58:13 Hello World Reply 9

View Source: https://github.com/xinliangnote/Go

Recommended Reading

Gin framework

Basics

This article Welcome forwarding, please indicate the source and author, thank you!

Guess you like

Origin www.cnblogs.com/xinliangcoder/p/11268128.html