https://github.com/redmooner/go-grpc-demo
https://github.com/redmooner/go-grpc-demo
Last synced: 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/redmooner/go-grpc-demo
- Owner: RedMooner
- Created: 2025-03-05T07:13:21.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-05T07:18:12.000Z (over 1 year ago)
- Last Synced: 2025-12-25T16:16:14.543Z (6 months ago)
- Language: Go
- Size: 9.77 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
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 обеспечивает эффективную коммуникацию между клиентом и сервером.