Назад к вопросам
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
		}
	}
}