zoukankan      html  css  js  c++  java
  • 服务器端实时推送技术之SseEmitter的用法

     这是SpringMVC提供的一种技术,可以实现服务端向客户端实时推送数据.用法非常简单,只需要在Controller提供一个接口,创建并返回SseEmitter对象,发送数据可以在另一个接口调用其send方法发送数据.这个SseEmitter对象和DeferredResult有异曲同工之妙,只是SseEmitter可以在一次请求中返回多条数据,而DeferredResult只能返回一条.关于DeferredResult的用法请求参考我的另一篇博客:https://www.cnblogs.com/jun1019/p/10807055.html

     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 }

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

  • 相关阅读:
    [设计模式]<<设计模式之禅>>关于迪米特法则
    [设计模式]<<设计模式之禅>>关于接口隔离原则
    [设计模式]<<设计模式之禅>>关于依赖倒置原则
    /proc/meminfo分析(一)
    Dynamic DMA mapping Guide
    Linux时钟
    Linux系统休眠和设备中断处理
    Linux调度器
    Linux调度器
    Linux标识进程
  • 原文地址:https://www.cnblogs.com/jun1019/p/10886079.html
Copyright © 2011-2022 走看看