如何通过 RestController 代理内部 mjpeg 端点

问题描述 投票:0回答:1

我需要公开从我的应用程序服务器(jhipster 网关)的 RestController 中的端点传递的本地 Motion JPEG 端点(例如“http://192.168.1.10/video.mjpg”),因为我需要保证授予并授权对其进行流式传输。

我已经尝试过这个解决方案

@GetMapping("/video")
@Timed
public void stream(@RequestParam(name = "url") String url, HttpServletResponse response) throws IOException {
        log.debug("REST request to stream : {}", url);
        response.setStatus(HttpStatus.OK.value());
        response.setHeader(HttpHeaders.CONTENT_TYPE, "multipart/x-mixed-replace");
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
        response.setHeader("Pragma", "no-cache");
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.execute(
            url,
            HttpMethod.GET,
            (ClientHttpRequest requestCallback) -> {},
            responseExtractor -> {
                IOUtils.copy(responseExtractor.getBody(), response.getOutputStream());
                return null;
            });
    }

但是没有成功。 有什么建议吗?

java spring mjpeg
1个回答
0
投票

我已成功使用 webflux api 使以下代码正常工作。

bodyToFlux(DataBuffer.class)
将响应主体转换为 DataBuffer 对象的反应式 Flux。在
doOnNext
内,它从每个 DataBuffer 读取数据并将其写入响应的输出流。

需要注意的是,必须调用

DataBufferUtils.release(dataBuffer);
,否则会导致内存泄漏。

private final WebClient webClient = WebClient.builder()
  .baseUrl("baseUrl")
  // .filters(...) // perhaps authentication filters
  .build();

@GetMapping
public void stream(HttpServletResponse response) {
  response.setStatus(HttpServletResponse.SC_OK);
  response.setContentType("multipart/x-mixed-replace; boundary=myboundary");

  try {
    webClient.get()
    .uri("/the-uri.mjpg")
    .accept(MediaType.parseMediaType("multipart/x-mixed-replace; boundary=myboundary"))
    .retrieve()
    .onStatus(HttpStatusCode::isError, clientResponse ->
      clientResponse.bodyToMono(String.class).map(RuntimeException::new))
    .bodyToFlux(DataBuffer.class)
    .doOnNext(dataBuffer -> {
      try (final var input = dataBuffer.asInputStream()) {
        input.transferTo(response.getOutputStream());
        DataBufferUtils.release(dataBuffer);
      } catch (IOException e) {
        DataBufferUtils.release(dataBuffer);
        throw new RuntimeException(e);
      }
    })
    .blockLast();
  } catch (Exception e) {
    // the client has probably disconnected
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.