es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

no hay respuesta de streaming en Spring WebFlux Flux

@GetMapping(value = "/download")
public Flux<databuffer> flux(ServerHttpResponse response) throws IOException {
    final Stream<integer> stream = Stream.iterate(1, i -> i + 1).limit(1000);

    String fileName = String.format("%s.csv", RandomStringUtils.randomAlphabetic(10));
    response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
    response.getHeaders().setContentType(MediaType.APPLICATION_OCTET_STREAM);

    final Flux<databuffer> next = Flux.create(emitter -> {
                stream
                        .map(i -> String.format("%d", i).getBytes(StandardCharsets.UTF_8))
                        .forEach(bytes -> {
                            final DefaultDataBuffer dataBuffer = new DefaultDataBufferFactory().allocateBuffer();
                            final OutputStream outputStream = dataBuffer.asOutputStream();
                            try {
                                outputStream.write(bytes);
                                outputStream.flush();
                                emitter.next(dataBuffer);
                            } catch (IOException  e) {
                                e.printStackTrace();
                            }
                        });
                emitter.complete();
            }
    );

    return next;
}

Cuando emitter.next(dataBuffer) , no recibo una respuesta desde el servidor WebFlux.

Cuando emitter.complete(), obtengo una respuesta completa. Quiero obtener el streaming en tiempo real, ¿cómo puedo hacerlo?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para obtener la transmisión en tiempo real, puedes utilizar el método response.writeWith(), el cual permite escribir en el flujo de salida en tiempo real. En lugar de devolver un Flux<databuffer> desde el método flux(), puedes modificarlo para escribir en la respuesta en tiempo real utilizando el siguiente código:

    @GetMapping(value = "/download")
    public Mono<void> flux(ServerHttpResponse response) throws IOException {
        final Stream<integer> stream = Stream.iterate(1, i -> i + 1).limit(1000);
    
        String fileName = String.format("%s.csv", RandomStringUtils.randomAlphabetic(10));
        response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
        response.getHeaders().setContentType(MediaType.APPLICATION_OCTET_STREAM);
    
        final Mono<void> next = response.writeWith(Flux.create(emitter -> {
            stream.map(i -> String.format("%d", i).getBytes(StandardCharsets.UTF_8))
                    .forEach(bytes -> {
                        final DataBuffer dataBuffer = new DefaultDataBufferFactory().wrap(bytes);
                        emitter.next(dataBuffer);
                    });
            emitter.complete();
        }));
    
        return next;
    }
    

    Aquí, estamos devolviendo un Mono<void> y utilizando response.writeWith() para escribir en el flujo de salida en tiempo real. Creamos un Flux<databuffer> dentro de él y utilizamos el emitter para emitir los objetos DataBuffer. Envolvemos los bytes generados en un DataBuffer utilizando DefaultDataBufferFactory, lo emitimos utilizando el emitter y completamos el Flux. Finalmente, devolvemos el Mono<void> devuelto por response.writeWith().

    De esta manera, la respuesta se transmitirá en tiempo real y no necesitas esperar a que se complete emitter.complete() para obtener la respuesta.

Comments are closed.