Reputation: 785
The overview of the project is this:
OK
response when the file is received, but continues to process the file in the background, running tests on the file.So, since the endpoint of the controller has already returned a response, how can I send info from the backend to the frontend outside of using the Controller.
Here is what is running after the Controller returns the response:
CompletableFuture.runAsync(() -> {
int count = 0;
boolean stillProcessing = true;
while (stillProcessing) {
stillProcessing = !test.isTestComplete();
if (test.getNumberOfInstancesComplete() > count) {
count = test.getNumberOfInstancesComplete();
log.info("{}/{} instances completed so far", count, test.getInstances().size());
}
}
});
The log.info
line is what I need to return to the frontend React side of things.
The end goal is to basically have a loading bar shown to users using the values printed in log.info()
.
Upvotes: 1
Views: 2388
Reputation: 150
You can use websockets to notify frontend without a controller. Here is the example code to send a message to the client from backend using STOMP at any time.
@Component
public class PushMessage {
@Autowired
SimpMessagingTemplate simpMessagingTemplate;
public <T> void invokeWebSocketEndpoint(String endpoint, T payload) {
this.simpMessagingTemplate.convertAndSend(endpoint, payload);
}
}
For more info on STOMP websockets, check out this link https://spring.io/guides/gs/messaging-stomp-websocket/
If you do not want bi-directional communication between the client and the server and just want to push messages to client from the server you can also make use of Server sent events. Here's a simple example.
@GetMapping(value = "/test")
public SseEmitter test() {
SseEmitter emitter = new SseEmitter();
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
try {
Process p = Runtime.getRuntime().exec("ping -c 10 www.google.com");
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
emitter.send(line);
}
emitter.complete();
}
} catch (IOException e) {
emitter.completeWithError(e);
e.printStackTrace();
}
});
executorService.shutdown();
return emitter;
}
For more information on Server sent events see this https://www.baeldung.com/spring-server-sent-events
You can consume server sent events from your frontend using the EventSource API https://developer.mozilla.org/en-US/docs/Web/API/EventSource
Upvotes: 1