1. 程式人生 > >基於sse的訊息單向推送機制

基於sse的訊息單向推送機制

     訊息推送現在基本上是web應用的標配,在做一個社交類網站時,本人一開始由於對這方面的技術不夠熟練,想採用最新的websocket技術,卻一直失敗,最終採用了最傳統的輪詢方式,十分浪費資源。今天看了spring boot 實戰這本書,裡面介紹了一種我之前從未了解過的技術——伺服器推送事件(Server-sent Events),簡稱SSE,它可以很方便地實現伺服器向客戶端的單向訊息推送,看起來相當簡單,遂動手嘗試了一下,用起來果然十分方便,因此在此作個筆記,以便日後使用。

   在這我就不對這項技術的內部實現進行深入探討了,只談談它如何應用。博主在這裡使用的是java語言,其他語言也類似:

   首先建立一個java web專案,新建一個簡單的首頁,程式碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>測試頁面</title>
<style>
</style>
</head>
<body class="bgBody">
<div id="msgFromPush"></div>
<script		src="<%=request.getContextPath()%>/resources/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
//jsp頁面js指令碼
    var source = new EventSource('push');//傳送訊息
    s = '';
    source.addEventListener('message', function(e) {
      
          s += e.data + "<br/>";
        $("#msgFromPush").html(s);
    },false);//新增客戶端的監聽

    source.addEventListener('open', function(e) {
        console.log("連線開啟");
    }, false);

    source.addEventListener('error',function(e){
        if(e.currentTarget.readyState==EventSource.CLOSED){
            console.log("連線關閉");
        }else{
            console.log(e.currentTarget.readyState);
        }
    });

	
</script>
</body>
</html>
其中最核心的就是EventSource()物件了,物件裡的引數就是伺服器推送的請求路徑了,要注意的是,EventSource目前並不為IE所支援,請在谷歌或火狐等瀏覽器下嘗試。

eventSource最核心的函式有以下幾個:

SSE技術詳解:一種全新的HTML5伺服器推送事件技術_QQ20160526-0.png

我們可以像例項程式碼一樣通過註冊監聽器實現推送接送功能,也可以使用以下這種形式:source.onXXXX=function(e){...}實現。接下來看伺服器端的程式碼:

 * 實現伺服器推送
	 * @param response
	 * @return
	 */
	@RequestMapping(value="push",produces="text/event-stream")
	@ResponseBody
	public String push(HttpServletResponse response){
		Random random=new Random();
	
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	    return "data:Testing 1,2,3"+random.nextInt()+"\n\n";
	}

伺服器端無需要使用第三方jar包,只要修改一下響應頭資訊就可以實現推送功能了。要注意的是,推送的資料格式是有規定的,都是如下格式:

field: value\n
field可以取四個值:“data”, “event”, “id”, or “retry”,也就是說有四類頭資訊。每次HTTP通訊可以包含這四類頭資訊中的一類或多類。\n代表換行符。
以冒號開頭的行,表示註釋。通常,伺服器每隔一段時間就會向瀏覽器傳送一個註釋,保持連線不中斷。
資料內容用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

大家千萬要記得結尾要兩個換行符,否則前端是無法正確處理資料的,博主可是被這個坑了好久。