@RestController @RequestMapping("/user") public class UserController { private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>(); @Autowired private UserMapper userMapper; @GetMapping(value = "/get",produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter getAllUsers(){ SseEmitter emitter = new SseEmitter(); this.emitters.add(emitter); emitter.onCompletion(() -> this.emitters.remove(emitter)); emitter.onError((e) -> this.emitters.remove(emitter)); emitter.onTimeout(() -> this.emitters.remove(emitter)); return emitter; } @GetMapping("/add") public void addUser(){ User user = new User(); LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); user.setUsername(formatter.format(now)); user.setPassword(UUID.randomUUID().toString()); userMapper.addUser(user); sendToClients(); }
我这里做的是从数据库查询数据实时推送到前端,你也可以换成任何你喜欢的方式,在下面的方法中
现在,是时候学习一些发送数据的魔法咒语了。每当后端有新的数据更新时,我们就可以调用 sendToClients
方法,让这些数据像小精灵一样飞到每个客户端。
public void sendToClients() { List<User> users = userMapper.getUsers(); for (SseEmitter emitter : emitters) { try { emitter.send(users); } catch (IOException e) { emitter.completeWithError(e); } } }
接下来,在前端的世界里,我们需要打开一个魔法视窗来接收这些数据。这个魔法视窗就是 JavaScript 的 EventSource。
<!DOCTYPE html> <html> <head> <title>SSE Example</title> </head> <body> <div id="sse-data"></div> <script> const sseData = document.getElementById("sse-data"); const eventSource = new EventSource("/user/get"); eventSource.onmessage = (event) => { sseData.innerHTML = event.data; }; eventSource.onerror = (error) => { console.error("SSE Error:", error); }; </script> </body> </html>
最后,让我们把这一切魔法整合在一起。启动你的 SpringBoot 应用,打开你的前端页面,你就会看到数据像水一样流畅地在你眼前流淌。不再是冰冷的静态页面,你的应用现在生动、活泼,充满了魔法的力量!