前端有个耗时的查询比对任务提交,想实时获取比对进程。一般常规都是轮询、长连接、websocket等,今天查到html5里面有个SSE(Server-sent Events),客户端提交一次请求后,由服务端单向推送数据。不支持一次请求客户端再次通信。
后端
采用已经有的SpringBoot。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @RestController @RequestMapping("sseDemo") public class SseDemoController { @GetMapping(value = "str", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter str() { SseEmitter sseEmitter = new SseEmitter(50000L); sseEmitter.onTimeout(() -> { System.out.println("超时"); }); new Thread(() -> { try { for (int i = 0; i < 10; i++) { sseEmitter.send("data " + i); TimeUnit.SECONDS.sleep(1); } SseEmitter.SseEventBuilder event = SseEmitter.event(); event.name("close"); event.data(new Object(), MediaType.APPLICATION_JSON_UTF8); sseEmitter.send(event); sseEmitter.complete(); } catch (InterruptedException | IOException e) { throw new RuntimeException(e); } }).start(); return sseEmitter; } }
|
此处未处理id等保证数据获取,实际开发过程中可按需要进行处理
前端
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let eventSource = new EventSource('/webApi/sseDemo/str');
eventSource.onmessage = function (event) { console.log(event) }
eventSource.addEventListener('close', (event)=>{ console.log(event) eventSource.close() });
eventSource.onopen = function (event) { console.log(event) }
|
前端如果超时后会默认断开重连,如果未处理好异常情况,会导致一直发送请求。所以需要设定规则关闭连接,如接收到关闭事件,或者多少次重连或者异常后关闭。