Потоковая передача между сервером и клиентом
Двунаправленная потоковая передача и обратное давление
«Потоковая передача между сервером и клиентом» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Типы потоковой передачи gRPC
Помимо унарного режима, gRPC поддерживает ещё три режима потоковой передачи: поток от сервера (сервер отправляет множество сообщений), поток от клиента (клиент отправляет множество сообщений) и двунаправленный поток (поток передают обе стороны).
Поток от сервера в .proto
Используйте ключевое слово stream перед типом ответа:
service EventService {
rpc ListEvents (ListEventsRequest) returns (stream Event);
}Реализация потока от сервера
Сервер отправляет несколько сообщений, вызывая stream.Send(), и возвращает nil после завершения:
func (s *server) ListEvents(req *pb.ListEventsRequest, stream pb.EventService_ListEventsServer) error {
for _, event := range s.events {
if err := stream.Send(event); err != nil { return err }
}
return nil
}Получение потока от сервера клиентом
Клиент вызывает Recv() в цикле до тех пор, пока не получит io.EOF:
stream, err := client.ListEvents(ctx, &pb.ListEventsRequest{})
for {
event, err := stream.Recv()
if err == io.EOF { break }
if err != nil { log.Fatal(err) }
fmt.Println(event)
}Поток от клиента в .proto
Используйте stream перед типом запроса:
service UploadService {
rpc Upload (stream Chunk) returns (UploadResponse);
}Реализация потока от клиента
Клиент отправляет несколько сообщений, а затем закрывает поток с помощью CloseAndRecv:
stream, _ := client.Upload(ctx)
for _, chunk := range chunks {
stream.Send(chunk)
}
resp, err := stream.CloseAndRecv()Получение потока от клиента сервером
Вызывайте stream.Recv() в цикле до тех пор, пока не получите io.EOF, а затем верните итоговый ответ:
func (s *server) Upload(stream pb.UploadService_UploadServer) error {
for {
chunk, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&pb.UploadResponse{Received: total})
}
if err != nil { return err }
total += len(chunk.Data)
}
}Двунаправленный поток
И клиент, и сервер могут независимо отправлять и получать данные. В .proto укажите stream с обеих сторон.
service ChatService {
rpc Chat (stream Message) returns (stream Message);
}Реализация двунаправленного потока на сервере
Сервер получает данные в горутине и независимо отправляет их:
func (s *server) Chat(stream pb.ChatService_ChatServer) error {
for {
msg, err := stream.Recv()
if err == io.EOF { return nil }
if err != nil { return err }
stream.Send(&pb.Message{Text: "echo: " + msg.Text})
}
}Управление потоком
gRPC использует управление потоком HTTP/2, чтобы быстрые отправители не перегружали медленных получателей. Вызовы Recv() естественным образом создают обратное давление — отправка блокируется, когда получатель не читает данные.
Отмена контекста
Передавайте контекст с крайним сроком или отменой во все вызовы потоковой передачи. Поток отменяется после завершения контекста, из-за чего Recv/Send возвращают ошибку.
Быстрая проверка
Как сервер RPC с потоком от сервера сообщает о завершении отправки?
Итоги: потоковая передача gRPC
Основные моменты:
- Поток от сервера: ключевое слово stream у ответа; сервер вызывает Send()
- Поток от клиента: ключевое слово stream у запроса; клиент вызывает Send(), затем CloseAndRecv()
- Двунаправленный поток: stream с обеих сторон; независимые горутины Send и Recv
- Отмена контекста применяется ко всем вызовам потоковой передачи
Часто задаваемые вопросы
Урок «Потоковая передача между сервером и клиентом» бесплатный?
Да — полный текст урока «Потоковая передача между сервером и клиентом» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Потоковая передача между сервером и клиентом»?
Двунаправленная потоковая передача и обратное давление Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Потоковая передача между сервером и клиентом»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Protocol Buffers и .proto-файлы
- Реализация унарного сервиса gRPC
- Потоковая передача между сервером и клиентом
- Перехватчики и метаданные gRPC