一、SSE介紹
1.EventSource 對象
SSE 的客戶端 API 部署在EventSource對象上。下面的代碼可以檢測瀏覽器是否支持 SSE。
if (‘EventSource’ in window) {
}
使用 SSE 時,瀏覽器首先生成一個EventSource實例,向服務器發起連接。
var source = new EventSource(url);
上面的url可以與當前網址同域,也可以跨域。跨域時,可以指定第二個參數,打開withCredentials屬性,表示是否一起發送 Cookie。
var source = new EventSource(url, { withCredentials: true });
readyState 屬性
EventSource實例的readyState屬性,表明連接的當前狀態。該屬性只讀,可以取以下值。
0:相當於常量EventSource.CONNECTING,表示連接還未建立,或者斷線正在重連。
1:相當於常量EventSource.OPEN,表示連接已經建立,可以接受數據。
2:相當於常量EventSource.CLOSED,表示連接已斷,且不會重連。
2.url 屬性
EventSource實例的url屬性返回連接的網址,該屬性只讀。
3.withCredentials 屬性
EventSource實例的withCredentials屬性返回一個布爾值,表示當前實例是否開啟 CORS 的withCredentials。該屬性只讀,默認是false。
4.onopen 屬性
連接一旦建立,就會觸發open事件,可以在onopen屬性定義回調函數。
source.onopen = function (event) {
};
或
source.addEventListener(‘open’, function (event) {
}, false);
5.onmessage 屬性
客戶端收到服務器發來的數據,就會觸發message事件,可以在onmessage屬性定義回調函數。
source.onmessage = function (event) {
var data = event.data;
var origin = event.origin;
var lastEventId = event.lastEventId;
};
或
source.addEventListener(‘message’, function (event) {
var data = event.data;
var origin = event.origin;
var lastEventId = event.lastEventId;
}, false);
上面代碼中,參數對象event有如下屬性:
data:服務器端傳回的數據。
origin: 服務器 URL 的域名部分,即協議、域名和端口,表示消息的來源。
lastEventId:數據的編號,由服務器端發送。如果沒有編號,這個屬性為空。
6.onerror 屬性
如果發生通信錯誤(比如連接中斷),就會觸發error事件,可以在onerror屬性定義回調函數。
source.onerror = function (event) {
};
或
source.addEventListener(‘error’, function (event) {
// handle error event
}, false);
7.自定義事件
默認情況下,服務器發來的數據,總是觸發瀏覽器EventSource實例的message事件。開發者還可以自定義 SSE 事件,這種情況下,發送回來的數據不會觸發message事件。
source.addEventListener(‘foo’, function (event) {
var data = event.data;
var origin = event.origin;
var lastEventId = event.lastEventId;
}, false);
8.close() 方法
close方法用於關閉 SSE 連接。
source.close();
二、前端代碼
<!DOCTYPE html> <html> <head> <title>測試頁面</title> <meta name="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="../js/jquery-1.8.3.min.js"></script> <script type="text/javascript">
// 檢查瀏覽器是否支持SSE if ('EventSource' in window) { var source = new EventSource('../com/yh/myServlet/GetSession');
source.onmessage = function(e) { console.log("message1:" + e.data); }; source.onopen = function(e) { console.log("連接打開."); }; source.onerror = function(e) { if (e.readyState == EventSource.CLOSED) { console.log("連接關閉"); } else { console.log("onerror:" + e.readyState); } }; } else { console.log("沒有sse"); } </script> </head> <body> </body> </html>
三、后端代碼
此處在servlet的doGet()方法中進行響應處理
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType("text/event-stream;charset=utf-8"); PrintWriter writer = response.getWriter(); Random r = new Random(); // try { // Thread.sleep(5000); // } catch (InterruptedException e) { // e.printStackTrace(); // } // SSE返回數據格式是固定的以data:開頭,以\n\n結束 writer.print("data:第一段\n\n"); }
部分轉載自:http://www.ruanyifeng.com/blog/2017/05/server-sent_events.html