SSE
最近尝试了一下服务器端的推送,之前的做法都是客户端轮询,定时向服务器发送请求。但这造成了我的一些困扰:
1:轮询是由客户端发起的,那么在服务端就不能判别我要推送的内容是否已经过期,因为我很难判断某个信息是否已经推送给全部的客户端,那么服务端就需要缓存大量的数据。如果数据保存在数据库,那么还要每次请求都需要查询数据库,这对数据库和系统设计都是一个很大的挑战。
2:请求的频率太高,每次的请求包中含有同样的数据,这对pc来说也许算不得什么,但是对于移动客户端来讲,这应该不是最佳的方案。尤其是遇到还要做权限判断的时候,那么服务端的逻辑和效率也会造成用户体验的降低。
js代码
function listenBack(){ var es = new EventSource("/sprig-blog/mobile/isLogin"); es.addEventListener("message", function(e){ console.log('data ', e.data) var data = JSON.parse(e.data); alert(data.curDate); },false); }
后台代码:
@RequestMapping(value = "/isLogin", method = RequestMethod.GET) public void isLogin(HttpServletRequest request, HttpServletResponse response) { Result result = new Result(); result.setSuccess(true); //this.print(result, response); response.setContentType("text/event-stream"); response.setCharacterEncoding("UTF-8"); PrintWriter out = null; try { out = response.getWriter(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } String eventJson = "{\"curDate\":\"" + new Date() + "\"}"; out.println("data:" + eventJson + "\n\n"); //js页面EventSource接收数据格式:data:数据 + "\r\n" out.flush(); }
返回的信息必须以data开头