服务器主动推送技术 SSE

1,698 阅读1分钟

服务器主动发送请求在开发中比较常用,早期使用ajax向服务器轮询消息,但这种方式会增加服务器负担,而且消息返回会有延迟。

  • 解决方案一:websocket

  • 解决方案二:sse

SSE:

原理:浏览器向服务器发送请求后,服务器抓住请求不放,等到数据更新时,服务器再把数据发送给浏览器,浏览器拿到响应后,再向服务器发送请求,如此循环

好处:只使用了一次请求,大大减小了服务器的请求数量,减轻服务器压力,只会在接收到数据更新后才返回响应。

栗子:

服务端 springboot接收请求

@RestController
@Slf4j
public class PushController {
    private int count;
    /**
     * 超时时间设置到最大,避免因为超时导致连接断开
     */
    private SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
    
    @GetMapping(value = "/push")
    public SseEmitter push() throws InterruptedException {
        return emitter;
    }
    
    @GetMapping("/send")
    public String send() {
        try {
            emitter.send("push " + count++);
            return "success";
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "failed";
    }
}

客户端 js监听消息

<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>服务器推送示例</title>
</head>
<body>
<div id="msg"></div>
</body>
<script>
    var source = new EventSource("/springboot/push");

    source.onmessage = function (e) {
        console.info("收到信息");
        document.getElementById("msg").innerHTML += `<p>${e.data}</p>`;
    };

    source.onopen = function (e) {
        console.info("连接打开");
        console.info(e);
    };

    source.onerror = function (e) {
        console.info("连接错误");
        console.info(e);
    };
</script>
</html>

每次访问send,服务器就会向浏览器返回数据

可以看到一个push请求接收了来自服务器的多个数据