--- title: SSE description: 服务端事件 published: true date: 2021-11-01T08:40:22.257Z tags: wg-basic editor: markdown dateCreated: 2021-11-01T08:40:00.487Z --- # 对比WebSocket WebSocet是双通道的,即可以向服务器发送数据,也可以接收服务器数据 ServerSendEvent是单通道的,只能接收服务器数据(服务器主动推送) # Controller 方式1: 利用前端页面的重连机制,sse页面会自动重连(类似ajax的定时连接,意义不大) ```java @RequestMapping(value = "sse", produces = "text/event-stream;charset=UTF-8") @ResponseBody public String push() { return "data:message\n\n"; } ``` 方式2: 服务端主动推送,这里用循环模拟了业务处理 ```java @RequestMapping(value = "sse") @ResponseBody public void push(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/event-stream"); response.setCharacterEncoding(ISystemConstant.CHARSET_UTF8); try { PrintWriter writer = response.getWriter(); for (int i = 0; i < 10; i++) { Thread.sleep(1000); writer.write("data:index:" + i + "\n\n"); writer.flush(); } } catch (InterruptedException | IOException e) { e.printStackTrace(); } } ``` # 页面 > IE不支持EventSource,可以使用WebSocket代替 {.is-warning} ```javascript // 判断是否支持 if ('EventSource' in window) { var source = new EventSource(top.restAjax.path('route/teamtype/sse', [])); source.addEventListener('message', function(e) { console.log(e.data); }); source.addEventListener('open', function(e) { console.log('open'); }, false); // 响应finish事件,主动关闭EventSource source.addEventListener('finish', function(e) { console.log('finish'); source.close(); }, false); // 异常 source.addEventListener('error', function(e) { console.log('error', e); if (e.readyState == EventSource.CLOSED) { console.log("连接关闭"); } }, false); } ```