【问题标题】:Streaming data over HTTP with Java使用 Java 通过 HTTP 流式传输数据
【发布时间】:2019-11-02 06:54:31
【问题描述】:

我有两个 Java Spring Boot 应用程序,我们将它们命名为 Source 和 Consumer。 Source 有一个 GET 端点/api/data,它返回无限的数据流。这个想法是从 Consumer 调用它并每隔几秒钟侦听一次数据块,并且“从不”关闭此连接。我已经制作了一个看起来现在可以使用的简单 Source:

@RestController
@RequestMapping ("/api")
public class SourceController {

    private final Logger logger = LoggerFactory.getLogger(SourceController.class);

    @GetMapping (value = "/data", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<StreamingResponseBody> data(final HttpServletResponse response) {
        response.setContentType("application/json");
        StreamingResponseBody stream = out -> {
            try {
                for (int i = 0; i < 10; i++) {
                    String content = "{\"counter\":" + i + "}\n";
                    out.write(content.getBytes());
                    logger.info("size: "  + content.getBytes().length);
                    Thread.sleep(1000);
                }
                out.close();
            } catch (final Exception e) {
                logger.error("Exception", e);
            }
        };
        logger.info("steaming response {} ", stream);
        return new ResponseEntity(stream, HttpStatus.OK);
    }
}

我不确定这是否正是我想要的,因为当我使用 Postman 调用它时,响应会在执行 return 时的 10 秒后出现。

消费者阅读但阅读整个响应,而不是逐个阅读。

@RestController
@RequestMapping("/api")
public class ConsumerController {

    private final Logger logger = LoggerFactory.getLogger(ConsumerController.class);

    @GetMapping(value = "/consume", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> consume() throws IOException {
        URL url = new URL("http://localhost:8080/api/data");
        URLConnection connection = url.openConnection();
        connection.setDoOutput(true);

        BufferedReader in = new BufferedReader(
            new InputStreamReader(connection.getInputStream())
        );

        String decodedString;
        while ((decodedString = in.readLine()) != null) {
            logger.info(decodedString);
        }

        in.close();

        return new ResponseEntity("ok", HttpStatus.OK);
    }
}

【问题讨论】:

    标签: java spring-boot reactive-programming http-live-streaming


    【解决方案1】:

    源看起来是正确的,但是你只是在写入一大块数据后忘记刷新OutputStream,所以消费者无法立即接收到这块数据。

    所以在写一些到OutputStream 之后调用flush() 应该可以解决问题:

     for (int i = 0; i < 10; i++) {
           String content = "{\"counter\":" + i + "}\n";
           out.write(content.getBytes());
           out.flush();
           logger.info("size: "  + content.getBytes().length);
           Thread.sleep(1000);
    }
    
    

    【讨论】:

      猜你喜欢
      • 2018-03-06
      • 1970-01-01
      • 2010-09-25
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      • 1970-01-01
      • 2012-04-25
      相关资源
      最近更新 更多