Назад к вопросам
Middle
133
questionbank
В чем отличие между stream и unary вызовами?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
В gRPC:
Юнарный вызов: Клиент отправляет один запрос, сервер обрабатывает его и отправляет один ответ. Полная блокировка клиента до получения ответа. Используется для простых запросов типа "запрос-ответ".
Потоковый вызов: Позволяет клиенту и/или серверу отправлять несколько сообщений по одному соединению. Поддерживает:
- Клиентский поток (Client streaming): Клиент отправляет последовательность сообщений, сервер отправляет один ответ.
- Серверный поток (Server streaming): Клиент отправляет один запрос, сервер отправляет последовательность сообщений.
- Двунаправленный поток (Bidirectional streaming): Клиент и сервер отправляют последовательности сообщений независимо друг от друга. Позволяет обрабатывать большие объемы данных или поддерживать долгоживущие соединения.
| Признак | Юнарный вызов | Потоковый вызов |
|---|---|---|
| Количество запросов | 1 | 1 или N |
| Количество ответов | 1 | 1 или N |
| Поведение | Блокирующее (для клиента) | Неблокирующее (частично/полное) |
| Примеры | Получить информацию профиля | Загрузить файл, получать обновления статуса |
// Пример юнарного вызова
func (s *server) GetProfile(ctx context.Context, req *pb.ProfileRequest) (*pb.ProfileResponse, error) {
// ... логика обработки запроса
return &pb.ProfileResponse{ /* ... */ }, nil
}
// Пример серверного потокового вызова
func (s *server) ListFeatures(req *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
for _, feature := range features {
if inRectangle(feature.Location, req) {
if err := stream.Send(feature); err != nil {
return err
}
}
}
return nil
}
// Пример двунаправленного потокового вызова
func (s *server) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
for {
in, err := stream.Recv()
if err == io.EOF {
return nil // Поток завершен
}
if err != nil {
return err
}
// ... обработка полученного сообщения и отправка ответов
if err := stream.Send(reply); err != nil {
return err
}
}
}