An open API service indexing awesome lists of open source software.

https://github.com/redmooner/go-grpc-demo


https://github.com/redmooner/go-grpc-demo

Last synced: 2 months ago
JSON representation

Awesome Lists containing this project

README

          

# Объяснение работы gRPC-приложения на Go

В этом документе мы подробно разберем, как работает простое gRPC-приложение на Go, состоящее из клиента и сервера. Мы рассмотрим каждый файл и объясним, как они взаимодействуют между собой.

## 1. Архитектура приложения

Приложение состоит из следующих компонентов:

- **Клиент (`client.go`)**: Отправляет запросы на сервер и получает ответы.
- **Сервер (`server.go`)**: Обрабатывает запросы от клиента и возвращает ответы.
- **Protobuf-файл (`greet.proto`)**: Определяет структуру данных и сервис, который будет использоваться для взаимодействия между клиентом и сервером.
- **Сгенерированные файлы (`greet.pb.go` и `greet_grpc.pb.go`)**: Автоматически сгенерированные файлы на основе `greet.proto`, содержащие код для работы с gRPC.
- **Файл зависимостей (`go.mod`)**: Определяет зависимости проекта.

## 2. Protobuf-файл (`greet.proto`)

Файл `greet.proto` определяет структуру данных и сервис, который будет использоваться для взаимодействия между клиентом и сервером.

```proto
syntax = "proto3";

package greet;

option go_package = "src/go/greet";

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
string name = 1;
}

message HelloReply {
string message = 1;
}
```

### 2.1. Сервис `Greeter`

- **`SayHello`**: Это RPC-метод, который принимает сообщение типа `HelloRequest` и возвращает сообщение типа `HelloReply`.

### 2.2. Сообщения

- **`HelloRequest`**: Сообщение, которое клиент отправляет серверу. Оно содержит одно поле `name` типа `string`.
- **`HelloReply`**: Сообщение, которое сервер возвращает клиенту. Оно содержит одно поле `message` типа `string`.

## 3. Сгенерированные файлы

На основе `greet.proto` сгенерированы два файла:

- **`greet.pb.go`**: Содержит структуры данных для `HelloRequest` и `HelloReply`, а также методы для работы с этими структурами.
- **`greet_grpc.pb.go`**: Содержит интерфейсы и методы для реализации gRPC-сервиса `Greeter`.

### 3.1. `greet.pb.go`

Этот файл содержит Go-структуры, соответствующие сообщениям `HelloRequest` и `HelloReply`, а также методы для работы с ними.

```go
type HelloRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}

type HelloReply struct {
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
```

### 3.2. `greet_grpc.pb.go`

Этот файл содержит интерфейсы и методы для реализации gRPC-сервиса `Greeter`.

- **`GreeterClient`**: Интерфейс для клиента, который позволяет вызывать метод `SayHello`.
- **`GreeterServer`**: Интерфейс для сервера, который должен реализовать метод `SayHello`.

```go
type GreeterClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}

type GreeterServer interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}
```

## 4. Сервер (`server.go`)

Сервер реализует интерфейс `GreeterServer` и обрабатывает запросы от клиента.

```go
type server struct {
pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
```

### 4.1. Реализация метода `SayHello`

Метод `SayHello` принимает запрос `HelloRequest`, логирует имя, переданное в запросе, и возвращает ответ `HelloReply` с сообщением, содержащим это имя.

### 4.2. Запуск сервера

Сервер запускается на порту `50051` и начинает слушать входящие соединения. Когда клиент подключается, сервер обрабатывает запросы с помощью метода `SayHello`.

## 5. Клиент (`client.go`)

Клиент подключается к серверу и вызывает метод `SayHello`.

```go
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "World"})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}
```

### 5.1. Подключение к серверу

Клиент подключается к серверу по адресу `localhost:50051` с использованием небезопасного соединения (`grpc.WithInsecure()`).

### 5.2. Вызов метода `SayHello`

Клиент создает запрос `HelloRequest` с именем `"World"` и вызывает метод `SayHello`. Ответ от сервера логируется.

## 6. Зависимости (`go.mod`)

Файл `go.mod` определяет зависимости проекта, включая версии библиотек `grpc` и `protobuf`.

```go
module go-grpc-demo

go 1.24.0

require (
google.golang.org/grpc v1.71.0
google.golang.org/protobuf v1.36.5
)
```

## 7. Взаимодействие клиента и сервера

1. **Клиент** подключается к серверу по адресу `localhost:50051`.
2. **Клиент** отправляет запрос `HelloRequest` с именем `"World"`.
3. **Сервер** получает запрос, логирует имя и возвращает ответ `HelloReply` с сообщением `"Hello World"`.
4. **Клиент** получает ответ и логирует его.

## 8. Заключение

Это простое gRPC-приложение демонстрирует базовую структуру взаимодействия между клиентом и сервером. Protobuf используется для определения структуры данных и сервисов, а gRPC обеспечивает эффективную коммуникацию между клиентом и сервером.