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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM