Contenido del curso
gRPC
- 6

gRPC: qué lo hace más rápido que REST
08:35 min - 7

JSON vs Protobuf: cuándo usar cada uno
08:56 min - 8

Definir un StudentService con proto buffers en Go
04:27 min - 9

Implementación de Repositorios y gRPC en Go con PostgreSQL
11:59 min - 10

Criando o primeiro servidor gRPC em Go
12:50 min - 11

Prueba tu servidor gRPC con Postman
04:08 min - 12

Definiendo el servicio de test en gRPC
03:38 min - 13

Implementando servidor gRPC con PostgreSQL en Go
17:45 min - 14

Client streaming en gRPC con Go
16:53 min - 15

Implementación de Streaming del Servidor con gRPC y Protobufs
16:25 min - 16

Streaming del servidor con gRPC en Go
16:23 min - 17

Streaming bidireccional en gRPC con Go
16:04 min - 18

Prueba de streaming bidireccional con gRPC
04:55 min - 19

Implementando un cliente gRPC en Go
13:10 min - 20

Streaming bidireccional en gRPC con Go
Viendo ahora
Conclusión
Streaming bidireccional en gRPC con Go
Resumen
Implementar server streaming y streaming bidireccional en gRPC con Go te permite intercambiar datos en pequeños pedazos entre cliente y servidor, ya sea en una sola dirección o de forma simultánea. Si ya completaste los métodos unario y de client streaming, este es el paso que te faltaba para dominar los cuatro patrones de comunicación que ofrece gRPC.
Aquí vas a ver cómo se escribe el cliente para ambos casos, cómo se manejan los streams con stream.Recv y stream.Send, y por qué necesitas goroutines y channels cuando la comunicación es bidireccional.
Cómo implementar server streaming en gRPC desde el cliente
El server streaming aplica cuando el cliente hace una petición única y el servidor responde con múltiples mensajes. Un caso típico es traer una lista de estudiantes asociados a un test [01:00].
La función doServerStreaming recibe como parámetro un testpb.TestServiceClient y llama al método GetStudentsPerTest. Antes de invocarlo, construyes el request con el test_id correspondiente, por ejemplo T1, y luego ejecutas la llamada que devuelve un stream y un posible error.
¿Qué hace stream.Recv en gRPC? Es el método que lee mensajes del servidor uno a uno. Devuelve el mensaje y un error; si el error es
io.EOF, significa que el servidor terminó de enviar datos.
El flujo de lectura se hace dentro de un for indefinido porque no sabes cuántos estudiantes vas a recibir. En cada iteración:
- Llamas a
stream.Recv()para obtener el mensaje y el error. - Si el error es
io.EOF, hacesbreakpara salir del ciclo. - Si hay otro tipo de error, ejecutas
log.Fatalfcon un mensaje descriptivo. - Si todo salió bien, imprimes la respuesta del servidor.
Al probarlo, el cliente recibe al primer estudiante, después al segundo, luego al tercero, y finaliza limpiamente cuando el servidor cierra el stream [02:30].
Cómo implementar streaming bidireccional en gRPC con goroutines
El streaming bidireccional es el patrón más potente: cliente y servidor pueden enviar y recibir mensajes de forma simultánea sobre el mismo stream. Para emular ese comportamiento en Go, necesitas dos goroutines, una para escribir y otra para leer, coordinadas mediante un channel [03:30].
Por qué usar un channel de control vacío
La función doBidirectionalStreaming invoca a TakeTest, que abre un stream donde se envían respuestas y se reciben preguntas o feedback. Como vas a lanzar dos goroutines concurrentes, defines un canal de tipo chan struct{} que no transporta datos, solo sirve para bloquear el programa principal hasta que la lectura termine.
go waitChannel := make(chan struct{})
Este patrón es muy común en Go cuando solo te interesa señalizar finalización, no transmitir información. Después construyes la respuesta, por ejemplo un TakeTestRequest con answer = 42, y defines un total de cuatro preguntas a responder.
¿Para qué sirve un chan struct{} en Go? Es un channel sin payload que se usa como mecanismo de señalización. Ocupa cero bytes de memoria y permite sincronizar goroutines sin enviar datos reales.
Cómo separar la goroutine de envío y la de recepción
La primera goroutine itera con un for desde i = 0 hasta i < numero_de_preguntas y en cada vuelta ejecuta stream.Send(answer). Para observar el comportamiento asíncrono, agregas un time.Sleep que emula un tiempo de respuesta entre envíos [04:30].
La segunda goroutine itera de forma indefinida porque no sabes cuántas respuestas vendrán del servidor. Su lógica es:
- Llamar a
stream.Recv()para obtenerresyerr. - Si el error es
io.EOF, hacerbreak. - Si el error es distinto de nulo, ejecutar
log.Fatalfy romper el ciclo. - Si todo es correcto, imprimir la respuesta del servidor.
Al terminar el for de lectura, cierras el waitChannel. En el cuerpo principal de la función, bloqueas con una lectura sobre ese mismo channel para que el programa no termine antes de que el servidor cierre el stream.
Cuando ejecutas go run client/main.go, ves cómo se envían las respuestas con el valor 42 y cómo el servidor devuelve sus mensajes en paralelo, demostrando que el mismo stream funciona para lectura y escritura simultáneas [06:30].
Cuáles son los cuatro métodos de gRPC y cuándo usar cada uno
Con esta implementación cierras el recorrido por los cuatro patrones de comunicación que ofrece gRPC, cada uno pensado para un escenario distinto.
- Unario: un request y un response. Es el equivalente más cercano a una REST API tradicional y funciona bien cuando el intercambio es puntual.
- Client streaming: el cliente envía múltiples mensajes en pedazos pequeños y el servidor responde una sola vez al final. Útil para cargar grandes volúmenes de datos por partes.
- Server streaming: el cliente envía una sola petición y el servidor responde con un flujo continuo de mensajes. Ideal para listados largos o feeds de datos.
- Streaming bidireccional: cliente y servidor intercambian mensajes simultáneamente sobre el mismo stream. Perfecto para chats, juegos en tiempo real o cualquier interacción conversacional.
¿Cuál es la diferencia entre stream.Send y stream.Recv?
Sendempuja un mensaje hacia el otro extremo del stream;Recvlee el siguiente mensaje entrante. En streaming bidireccional, ambos métodos coexisten en el mismo stream.
Ya tienes los cuatro métodos implementados tanto en servidor como en cliente. ¿Cuál de los cuatro patrones crees que vas a usar más en tus proyectos? Cuéntame en los comentarios qué caso de uso tienes en mente.