摘要
通过相同的终点发送多个,这不是REST API
个场景.一般来说,我们经常使用长连接来处理这种情况,有很多技术可供 Select ,比如WebSocket、TCP协议、Socket,但它们都太重了,只需向指定主机发送一条消息就可以配置这么多.
解
简而言之,有Server-Sent Events个可以很容易地解决你的问题,我会在 spring 演示这项技术的Bacic演示,你也可以阅读offical spring sse doc
1. set up endpoint in spring
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
@RestController
@RequestMapping("/sse")
public class SseController {
@GetMapping("/events")
public SseEmitter handleSse() {
SseEmitter emitter = new SseEmitter();
// Asynchronous processing to send events
new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
// Send events every 1 second
emitter.send(SseEmitter.event().name("message").data("Event " + i));
Thread.sleep(1000);
}
// Signal the end of the event stream
emitter.complete();
} catch (IOException | InterruptedException e) {
emitter.completeWithError(e);
}
}).start();
return emitter;
}
}
connect endpoint by client side
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE Example</title>
</head>
<body>
<h1>SSE Example</h1>
<div id="sse-events"></div>
<script>
const eventSource = new EventSource('/sse/events');
eventSource.onmessage = function (event) {
const eventsDiv = document.getElementById('sse-events');
eventsDiv.innerHTML += `<p>${event.data}</p>`;
};
eventSource.onerror = function (error) {
console.error('EventSource failed:', error);
eventSource.close();
};
</script>
</body>
</html>
在本例中,SseController中的/SSE/Events端点返回一个SseEmitter,并且使用一个单独的线程来异步发送事件.客户端上的JavaScript代码使用EventSourceAPI来监听事件并更新HTML内容.
请记住使用适当的依赖项配置您的Spring Boot应用程序,并且您可能需要在生产场景中适当地处理异常和清理.
附录
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.2</version> // replace appropriate version , 3.0.0 or else later is ok
</dependency>
你可以在下面的包路径中找到主要类(可能与其他Spring Boot版本不同)
org.springframework.web.servlet.mvc.method.annotation.SseEmitter