如何在Java springboot中从一个端点发送多个时间响应?

1hdlvixo  于 2024-01-05  发布在  Spring
关注(0)|答案(2)|浏览(161)

场景:
我有30个端到端流程流的测试用例,包括(调度器,生产者和消费者)。所以,我在java springmvc web应用程序中自动化了30个测试用例。我已经创建了一个端点,它将开始测试,然后它将依次运行30个测试用例,我为每个测试用例创建了30个方法,每个测试用例大约需要5分钟才能完成,因为(必须执行调度程序,生产者和消费者)。所以,在一个测试用例完成后,我想在UI中显示状态和消息,我不想等到所有30个测试用例完成后才显示所有测试用例的状态。如何使用rest endpoint实现这一点?

a11xaf1n

a11xaf1n1#

摘要

通过同一个端点发送多个消息,这不是REST API的情况。通常,我们经常使用长连接来处理这种情况,有很多技术可以选择,如WebSocket,tcp协议,socket,但它们都太重了,只是发送一个消息到指定的主机可能会配置这么多。

解决方案

简而言之,有Server-Sent Events可以很容易地解决你的问题,我会演示bacic demo为这项技术在 Spring ,也可以阅读官方 Spring sse文档

1.在spring中设置endpoint

  1. import org.springframework.web.bind.annotation.GetMapping;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
  5. import java.io.IOException;
  6. @RestController
  7. @RequestMapping("/sse")
  8. public class SseController {
  9. @GetMapping("/events")
  10. public SseEmitter handleSse() {
  11. SseEmitter emitter = new SseEmitter();
  12. // Asynchronous processing to send events
  13. new Thread(() -> {
  14. try {
  15. for (int i = 0; i < 10; i++) {
  16. // Send events every 1 second
  17. emitter.send(SseEmitter.event().name("message").data("Event " + i));
  18. Thread.sleep(1000);
  19. }
  20. // Signal the end of the event stream
  21. emitter.complete();
  22. } catch (IOException | InterruptedException e) {
  23. emitter.completeWithError(e);
  24. }
  25. }).start();
  26. return emitter;
  27. }
  28. }

字符串

客户端连接端点

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>SSE Example</title>
  7. </head>
  8. <body>
  9. <h1>SSE Example</h1>
  10. <div id="sse-events"></div>
  11. <script>
  12. const eventSource = new EventSource('/sse/events');
  13. eventSource.onmessage = function (event) {
  14. const eventsDiv = document.getElementById('sse-events');
  15. eventsDiv.innerHTML += `<p>${event.data}</p>`;
  16. };
  17. eventSource.onerror = function (error) {
  18. console.error('EventSource failed:', error);
  19. eventSource.close();
  20. };
  21. </script>
  22. </body>
  23. </html>


在本例中,SseController中的/sse/events端点返回一个SseEEvent,并使用一个单独的线程异步发送事件。客户端的JavaScript代码使用EventSource API来侦听事件并更新HTML内容。
请记住使用适当的依赖项配置Sping Boot 应用程序,并且您可能需要在生产场景中适当地处理异常和清理。

附录

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. <version>2.4.2</version> // replace appropriate version , 3.0.0 or else later is ok
  5. </dependency>


你可以在下面的包路径中找到主类(可能与其他spring Boot 版本不同)

  1. org.springframework.web.servlet.mvc.method.annotation.SseEmitter

展开查看全部
uujelgoq

uujelgoq2#

为了在Sping Boot 应用程序中实现测试用例状态的实时更新,您需要使用异步通信方法。传统的REST端点是同步的,基于请求-响应,这意味着客户端发出请求并等待响应,这不适合您的需求。这里有一些您可以考虑的方法:

  1. WebSocket:这对于服务器和客户端之间的实时通信是一个很好的选择。Sping Boot 支持WebSocket,它允许双向通信。每次测试用例完成时,您可以向客户端发送消息。
    1.Server-Sent Events(SSE):SSE是WebSockets的一个更简单的替代方案。它允许服务器将数据推送到客户端。它是从服务器到客户端的单向通信。Spring通过SseEmitter类支持SSE。
    1.长轮询:这是另一种方法,客户端向服务器发出请求,服务器保持请求打开,直到有新数据发送回来。它比WebSockets或SSE效率低,但在某些情况下更容易实现。
    1.短信提示:使用像RabbitMQ或Apache Kafka这样的消息代理,您可以将消息(测试用例状态)发布到队列/主题,并且客户端可以订阅这些消息。这可能设置起来更复杂,但功能非常强大且可扩展。
    实现这些功能都需要在服务器端和客户端做一些修改。下面是如何进行的一般想法:
  • 修改端点以异步启动测试用例。您可以在Sping Boot 中使用@Async annotation轻松异步运行方法。
  • 选择实时通信方法(WebSocket、SSE等)。
  • 实现服务器端逻辑以在每个测试用例完成后发送更新。
  • 更新您的客户端应用程序以处理这些实时更新。

请记住,具体的实现将取决于应用程序的特定技术和体系结构。

相关问题