Server-sent Event 簡單介紹

如今先後端通信的經常使用的方式有ajax,websocket,還有fetch。可是常常的咱們會接到一些需求,好比說後端要給前端發送一些通知,前端接收到通知以後,作出相應的操做,好比說發說說之類的,當本身的朋友發一個說說的話,他也但願你這邊的界面也要呈現出來,或者說當一個企業的管理員發送一個公告,你再你的電腦上面也要可以及時的響應出來,這樣的需求我相信不少人都碰見過。前端

針對於上面的問題,咱們經常使用的方式就是用setInterval去作輪詢或者是websocket,只是前者setInterval輪詢這個中間的時間間隔須要考慮好,若是事件間隔較短,這對服務器的壓力比較大,若是事件較長,則有些須要當即當即作出響應的方式是作不到的。後者的websocket相對來講技技術要求有點高,實現起來比較複雜。node

因此就有如今的這種方式就是Server-sent Events,也就是說服務器端給前端瀏覽器發送事件的方式。使用Server-sent Events實際上是很是簡單的。咱們只須要須要在服務器端將事件流發送給前端,而後前端接收到後端所傳給的事件流,而後觸發事件,這是事件的捕獲和監聽其實和前端的事件捕獲和觸發是同樣的。因此對於前端人員來講,這種處理方式是很是的簡單的。web

Server-sent Events是包含在EventSoruce對象中。咱們能夠經過建立一個EventSource對象,給對象中傳入一個地址,也就是咱們請求服務器端發送事件的地址,就建立了連接,以下所示:ajax

var evtSource = new EventSource('/sse');

其中 '/sse' 是服務器端給的向前端發送事件的接口地址。經過get方式進行發送事件。json

若是事件發送地址存在跨域問題,則,咱們在建立EvenetSource對象的時候,須要制定具體的地址,好比說:後端

var evtSource = new EventSource('http://www.baidu.com', { withCredentials: true });

這個時候,咱們的事件接收器就算是建立好了,而後經過經過onmessage來接收後臺傳給前端的數據,也能夠經過addEventListener去建立事件的監聽,可是經過addEventListener建立的事件監聽是須要後端的事件發送方發送相對應的事件,纔可以進行觸發的。跨域

var evtSource = new EventSource('/sse');

evtSource.onmessage = function (e) {
  console.log(e.data)
}

也就是當後端發送的內容以後就會進行觸發,而且將data給打印出來,首先要提出的的是,Server-sent Events 所發送的內容都是字符串的流並且是經過utf-8的編碼格式的,若是後端但願給前端發送一串json,也須要將json轉化成相對應的字符串,而後在發送給前端,前端接收以後,再講所發送的字符串轉換成json,而後進行處理。瀏覽器

而後就是監聽後端發送給前端的事件內容,不如說,咱們後端給前端sent一個testEvent事件,前端經過事件接收者,去觸犯相對應的事件監聽,所以就有了下面的工做流程服務器

var evtSource = new EventSource('/sse');

evtSource.addEventListener('testEvent', function (e) {
  console.log(e)
})

上面代碼是前端的接收事件的放,是否是很相似,就像咱們以前用的同樣。websocket

var btn = document.getElementById('button')

btn.addEventListener('click', funciont (e) { 
  console.log(e)
})

咱們看到了前端的處理方案,可是後端應該如何才能給咱們發送事件呢,

首先咱們發送內容是須要給前端設置一個mime爲text/event-stream,而後在進行發送事件的內容,下面是相對應的node代碼

router.get('/sse', (req, res, next)=> {
  res.writeHead(200, {
    'Connection': 'keep-alive',
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache'
  });
  let data = { meg: '這是一個測試SSE的數據內容' };

  setTimeout(() => {
    console.log(JSON.stringify(data));
    res.write('data:' + JSON.stringify(data) + '\n\n');
  }, 2000)
})

這樣就可以發送給前端一條消息,就可以觸發前端的事件內容。

router.get('/sse', (req, res, next)=> {
  res.writeHead(200, {
    'Connection': 'keep-alive',
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache'
  });
  let data = { meg: '這是一個測試SSE的數據內容' };

  setTimeout(() => {
    console.log(JSON.stringify(data));
    res.write('event: testEvent\n\n');
    res.write('data:' + JSON.stringify(data) + '\n\n');
  }, 2000)
})

這個就是給前端發送圖個testEvent,所傳送的數據就是咱們的data內容。

相關文章
相關標籤/搜索