【发布时间】:2021-12-06 12:34:04
【问题描述】:
我有一个 ssh 管理器来在服务器上执行 (bash) 脚本。它包含一个commandWithContinousRead(String command, Consumer<String> consumer)。每当在 bash 脚本中调用 echo 时,它都会被消费者使用。我想用 Spring Boot 和 HTTP 调用来扩展它。当客户端发送请求时,服务器会在数据准备就绪时从 bash 脚本流式传输数据,客户端可以将其打印出来。
我知道服务器发送事件,但是,我觉得这主要用于事件,并且通常在 API 上使用多个资源。
此外,我尝试搜索流媒体主题,但没有成功。我确实从 Spring 中找到了StreamingResponseBody,但它会收集所有数据,然后一次性发送。
我使用 Postman 进行测试,也许它无法处理流媒体? 但是,我该如何测试呢?
例子:
#/bin/bash
# Scriptname: stream-this.sh
echo "Starting line"
sleep 4
echo "Middle line"
sleep 4
echo "End line"
使用commandWithContinousRead 请求,但在八秒后立即打印所有内容。
@RequestMapping(value = "/stream-this", method = RequestMethod.POST,
produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public ???? streamScript() {
StreamingResponseBody stream = out -> {
sshManager.commandWithContinousRead("bash /scripts/stream-this.sh", echo -> {
try {
byte[] bytes = echo.getBytes(StandardCharsets.UTF_8);
out.write(bytes);
System.out.println(echo);
} catch (IOException e) {
e.printStackTrace();
}
});
};
return new ResponseEntity<>(stream, HttpStatus.OK);
}
commandWithContinousRead函数的实现。
public void commandWithContinousRead(String command, Consumer<String> consumer) {
SSHClient client = buildClient();
try (Session session = client.startSession()) {
Session.Command cmd = session.exec(command);
BufferedReader br = new BufferedReader(new InputStreamReader(cmd.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = br.readLine()) != null) {
consumer.accept(line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
【问题讨论】:
标签: spring-boot spring-restcontroller