Bidirectional streaming RPC in Go is implemented by defining a server and client that both implement the Server and Client interfaces generated from your .proto file, then using Send and Recv methods on the returned stream within a loop.
// Server implementation
func (s *server) BidirectionalStream(stream proto.MyService_BidirectionalStreamServer) error {
for {
msg, err := stream.Recv()
if err == io.EOF {
return nil
}
if err != nil {
return err
}
if err := stream.Send(&proto.Response{Value: msg.Value * 2}); err != nil {
return err
}
}
}
// Client usage
stream, err := client.BidirectionalStream(ctx)
if err != nil {
log.Fatal(err)
}
// Send messages in a separate goroutine
for _, req := range requests {
if err := stream.Send(&proto.Request{Value: req}); err != nil {
log.Fatal(err)
}
}
stream.CloseSend()
// Receive responses
for {
resp, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Value)
}