An overview of the

This article will learn to use gRPC, output a Hello World.

  • Use Go to realize gRPC server.
  • GRPC client with Go.

GRPC supports 4 types of service methods, let’s implement single RPC and server-side streaming RPC this time.

Four classes of service methods

A single RPC

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

rpc SayHello(HelloRequest) returns (HelloResponse){}
Copy the code

Server-side streaming RPC

The client sends a request to the server to get a data stream to read a series of messages. The client reads from the returned data stream until there are no more messages.

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}
Copy the code

Client-side streaming RPC

The client writes and sends a series of messages to the server using one of the data streams provided. Once the client has finished writing the messages, it waits for the server to read them and return a reply.

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}
Copy the code

Two-way streaming RPC

Each side can send a series of messages via a read/write data stream. The two data flow operations are independent of each other, so the client and server can read and write in any order they wish. For example, the server can wait for all client messages before writing a reply, or it can read one message and then write another, or some other combination of read and write. The order of messages in each data stream is maintained.

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}
Copy the code

The installation

Install the Protobuf compiler

brew install protobuf
Copy the code

Validation:

Protoc --version // Output: libprotoc 3.7.1Copy the code

Install the Go Protobuf plugin

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

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

Install GRPC – go

go get -u google.golang.org/grpc
Copy the code

Write a Hello World service

  • Write server.protofile
  • Generate the server.pb.goFile and synchronize to client
  • Write code for the interface that the server provides
  • Write the code for the client to call the interface

The directory structure

├ ─ hello - code root │ ├ ─ go_client │ ├ ─ ─ main. Go │ ├ ─ ─ proto │ ├ ─ ─ the hello │ ├ ─ ─ hello. Pb. Go │ ├ ─ go_server │ ├ ─ ─ main. Go │ ├── Hello_Controller │ ├─ Hello_Controller │ ├─ Hello_serverCopy the code

The directories are created so that go_client and GO_server can be split into two projects later.

Write the server hello. Proto file

syntax = "proto3"; // Specify proto version package hello; Service Hello {// Define SayHello method RPC SayHello(HelloRequest) returns (HelloResponse) {} // define RPC LotsOfReplies(HelloRequest) returns (stream HelloResponse){}} // HelloRequest request structure message HelloRequest { string name = 1; Message HelloResponse {string message = 1; }Copy the code

For more Protobuf syntax, see:

Developers.google.com/protocol-bu…

Generate the server.pb.go

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

At the same time, copy the generated hello.pb.go to the client.

To view more command parameters, execute protoc to view options.

Write code for the interface that the server provides

// 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
}
Copy the code
// 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)
	iferr ! = nil { log.Fatalf("Failed to listen: %v", err)} s: = GRPC. NewServer ()/hello/service registration. RegisterHelloServer (s, & hello_controller HelloController {}) the Println ("Listen on " + Address)

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

Run:

Go run main. Go 2019/07/28 17:51:20 Listen on 0.0.0.0:9090Copy the code

Write code for the client request interface

package main

import (
	"hello/go_client/proto/hello"
	"io"
	"log"
	"golang.org/x/net/context"
	"google.golang.org/grpc") const (// gRPC service Address ="0.0.0.0:9090"
)

func main() {
	conn, err := grpc.Dial(Address, grpc.WithInsecure())
	iferr ! = nil {log.fatalln (err)} defer conn.close () // initialize the client c := hello.newhelloclient (conn) // call SayHello res, err := c.SayHello(context.Background(), &hello.HelloRequest{Name:"Hello World"})

	iferr ! = nil {log.fatalln (err)} log.println (res.message) err := c.LotsOfReplies(context.Background(),&hello.HelloRequest{Name:"Hello World"})
	iferr ! = nil { log.Fatalln(err) }for {
		res, err := stream.Recv()
		if err == io.EOF {
			break
		}

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

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

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
Copy the code

View source: github.com/xinliangnot…

Recommended reading

Gin framework

  • Gin Framework – Custom error handling
  • Gin Framework – Data binding and validation
  • Gin Framework – Using Logrus logging
  • Gin Framework – Installation and routing configuration

Based on article

  • Go – function
  • Go – cycle
  • Go-map collection
  • Go-struct structure
  • Go-slice
  • Go – array
  • Go – Variable declaration
  • Go – Environment installation

This article is welcome to forward, forward please indicate the author and source, thank you!