springboot服务端消息推送(SSE技术)

SSE技术是基于单工通信模式,只是单纯的客户端向服务端发送请求,服务端不会主动发送给客户端。服务端采取的策略是抓住这个请求不放,等数据更新的时候才返回给客户端,当客户端接收到消息后,再向服务端发送请求,周而复始。

注意:因为EventSource对象是SSE的客户端,可能会有浏览器对其不支持,但谷歌、火狐、360是可以的,IE不可以。

另外WebSocket技术是双工模式。

data:数据栏

数据内容用data表示,可以占用一行或多行。每行以data:开始,如果数据只有一行,则像下面这样,以“\n\n”结尾。

data:message\n\n

如果数据有多行,则最后一行用“\n\n”结尾,前面行都用“\n”结尾。

data:begin message\n
data:continue message\n\n

总之,最后一行的data,结尾要用两个换行符号,表示数据结束。

以发送JSON格式的数据为例。

data:{\n
data:"foo": "bar",\n
data:"baz", 555\n
data:}\n\n

id:数据标识符

数据标识符用id表示,相当于每一条数据的编号。

id:msg1\n
data:message\n\n

浏览器用lastEventId属性读取这个值。一旦连接断线,浏览器会发送一个HTTP头,里面包含一个特殊的“Last-Event-ID”头信息,将这个值发送回来,用来帮助服务器端重建连接。因此,这个头信息可以被视为一种同步机制。

@Controller
public class MainController {

    @GetMapping("/")
    public String sse() {
        return "sse";
    }

    @GetMapping(value="push",produces="text/event-stream")
    @ResponseBody
    public String push(){
        System.out.println("push msg..");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //注意:返回数据的格式要严格按照这样写,data:开始 ‘\n\n’结束
        return "data:current time: "+new SimpleDateFormat("YYYY-MM-dd hh:mm:ss").format(new Date())+"\n\n";
    }

}
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>SSE方式消息推送</title>
</head>
<body>

<div id="msgFromPush"></div>

<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
    if(!!window.EventSource){
        var source = new EventSource('push');
        s = '';
        source.addEventListener('message',function(e){
            console.log("get message"+e.data);
            s+=e.data+"<br/>";
            $("#msgFromPush").html(s);
        });

        source.addEventListener('open',function(e){
            console.log("connect is open");
        },false);

        source.addEventListener('error',function(e){
            if(e.readyState == EventSource.CLOSE){
                console.log("connect is close");
            }else{
                console.log(e.readyState);
            }
        },false);
    }else{
        console.log("web is not support");
    }
</script>
</body>
</html>
posted @ 2021-02-22 04:18  dkn  阅读(3010)  评论(0编辑  收藏  举报