服务器端实时推送技术之SseEmitter的用法

 这是SpringMVC提供的一种技术,能够实现服务端向客户端实时推送数据.用法很是简单,只须要在Controller提供一个接口,建立并返回SseEmitter对象,发送数据能够在另外一个接口调用其send方法发送数据.这个SseEmitter对象和DeferredResult有殊途同归之妙,只是SseEmitter能够在一次请求中返回多条数据,而DeferredResult只能返回一条.关于DeferredResult的用法请求参考个人另外一篇博客:http://www.javashuo.com/article/p-micvnrhk-et.htmlhtml

 1 import org.slf4j.Logger;  2 import org.slf4j.LoggerFactory;  3 import org.springframework.web.bind.annotation.RequestMapping;  4 import org.springframework.web.bind.annotation.RestController;  5 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;  6 
 7 import java.io.IOException;  8 import java.util.Map;  9 import java.util.concurrent.ConcurrentHashMap; 10 
11 /**
12  * 服务器端实时推送技术之 SseEmitter 的用法测试 13  * <p> 14  * 测试步骤: 15  * 1.请求http://localhost:8888/sse/start?clientId=111接口,浏览器会阻塞,等待服务器返回结果; 16  * 2.请求http://localhost:8888/sse/send?clientId=111接口,能够请求屡次,并观察第1步的浏览器返回结果; 17  * 3.请求http://localhost:8888/sse/end?clientId=111接口结束某个请求,第1步的浏览器将结束阻塞; 18  * 其中clientId表明请求的惟一标志; 19  * 20  * @author syj 21  */
22 @RestController 23 @RequestMapping("/sse") 24 public class SseEmitterController { 25     private static final Logger logger = LoggerFactory.getLogger(SseEmitterController.class); 26 
27     // 用于保存每一个请求对应的 SseEmitter
28     private Map<String, Result> sseEmitterMap = new ConcurrentHashMap<>(); 29 
30     /**
31  * 返回SseEmitter对象 32  * 33  * @param clientId 34  * @return
35      */
36     @RequestMapping("/start") 37     public SseEmitter testSseEmitter(String clientId) { 38         // 默认30秒超时,设置为0L则永不超时
39         SseEmitter sseEmitter = new SseEmitter(0L); 40         sseEmitterMap.put(clientId, new Result(clientId, System.currentTimeMillis(), sseEmitter)); 41         return sseEmitter; 42  } 43 
44     /**
45  * 向SseEmitter对象发送数据 46  * 47  * @param clientId 48  * @return
49      */
50     @RequestMapping("/send") 51     public String setSseEmitter(String clientId) { 52         try { 53             Result result = sseEmitterMap.get(clientId); 54             if (result != null && result.sseEmitter != null) { 55                 long timestamp = System.currentTimeMillis(); 56  result.sseEmitter.send(timestamp); 57  } 58         } catch (IOException e) { 59             logger.error("IOException!", e); 60             return "error"; 61  } 62 
63         return "Succeed!"; 64  } 65 
66     /**
67  * 将SseEmitter对象设置成完成 68  * 69  * @param clientId 70  * @return
71      */
72     @RequestMapping("/end") 73     public String completeSseEmitter(String clientId) { 74         Result result = sseEmitterMap.get(clientId); 75         if (result != null) { 76  sseEmitterMap.remove(clientId); 77  result.sseEmitter.complete(); 78  } 79         return "Succeed!"; 80  } 81 
82     private class Result { 83         public String clientId; 84         public long timestamp; 85         public SseEmitter sseEmitter; 86 
87         public Result(String clientId, long timestamp, SseEmitter sseEmitter) { 88             this.clientId = clientId; 89             this.timestamp = timestamp; 90             this.sseEmitter = sseEmitter; 91  } 92  } 93 }

 

这个技术有什么用呢? 就看你的想象力了, 好比能够用于和进度有关的操做: 安装进度, 部署进度, 任务执行进度等等.java

相关文章
相关标签/搜索