Обзор
Запустите gRPC, в этой статье рассказывается, как использовать gRPC для вывода Hello World.
- Внедрите сервер gRPC в Go.
- Клиент для gRPC, реализованный на Go.
gRPC поддерживает 4 типа методов обслуживания, на этот раз мы реализуем одноэлементный RPC и потоковый RPC на стороне сервера.
Четыре типа методов обслуживания
Один RPC
Сервер отправляет запрос на сервер и получает ответ от сервера, как при обычном вызове функции.
rpc SayHello(HelloRequest) returns (HelloResponse){}
Потоковая RPC на стороне сервера
Клиент отправляет запрос на сервер, чтобы получить поток данных для чтения серии сообщений. Клиент читает из возвращенного потока данных до тех пор, пока не останется сообщений.
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}
Клиентская потоковая передача RPC
Клиент пишет и отправляет серию сообщений на сервер, используя предоставленный поток данных. Как только клиент заканчивает писать сообщения, он ждет, пока сервер прочитает сообщения и вернет ответ.
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}
Двунаправленный потоковый RPC
Обе стороны могут отправлять серию сообщений через поток данных чтения и записи соответственно. Операции с двумя потоками данных независимы друг от друга, поэтому клиент и сервер могут читать и записывать в любом порядке, который они хотят, например: сервер может ждать всех клиентских сообщений, прежде чем писать ответ, или он может сначала прочитать сообщение Записать другое сообщение или какое-либо другое сочетание чтения и записи. Порядок сообщений в каждом потоке данных сохраняется.
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}
Установить
Установите компилятор protobuf
brew install protobuf
проверять:
protoc --version
//输出:libprotoc 3.7.1
Установите плагин Go protobuf
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
Установить grpc-go
go get -u google.golang.org/grpc
Написать сервис Hello World
- сервер записи
.proto
документ - сгенерировать сервер
.pb.go
файл и синхронизировать его с клиентом - Напишите код, обеспечивающий интерфейс на стороне сервера
- Напишите код, который клиент вызывает интерфейс
Структура каталогов
├─ 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
Этот каталог создан для того, чтобы впоследствии go_client и go_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;
}
Чтобы узнать больше о синтаксисе Protobuf, см.:
Developers.Google.com/protocol - нет...
сгенерировать сервер.pb.go
protoc -I . --go_out=plugins=grpc:. ./hello.proto
также будет генерироватьhello.pb.go
копировать клиенту.
Просмотрите дополнительные параметры команды, выполните protoc и просмотрите OPTION .
Напишите код, обеспечивающий интерфейс на стороне сервера
// 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)
}
}
бегать:
go run main.go
2019/07/28 17:51:20 Listen on 0.0.0.0:9090
Напишите код для интерфейса запроса клиента
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)
}
}
бегать:
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
Посмотреть исходный код:GitHub.com/Бессердечный не…
Рекомендуемое чтение
Джин каркас
- Gin Framework — специальная обработка ошибок
- Gin Framework — привязка и проверка данных
- Gin Framework — ведение журнала с помощью Logrus
- Gin framework — установка и настройка маршрутизации
Основы
- Перейти - функции
- Идти - петля
- Go - Коллекция карт
- Перейти — Структура Структура
- Идти - Нарезать
- Перейти — Массивы
- Go - объявление переменной
- Перейти — Установка среды
Эту статью можно переслать, пожалуйста, укажите автора и источник для пересылки, спасибо!