大多數時候,網頁必須向服務器發送請求以接收新數據。服務端發送的事件,能夠將消息推送到網頁
本質上,SSE使用戶能夠訂閱實時數據流。 每當此數據流更新時,用戶均可以實時看到新事件。 若是你知道Long-Polling或Web Socket那麼你可能以爲它沒什麼大不了
Websocket是服務器之間的雙向通訊形式。 它一般用於創建聊天室或多人視頻遊戲,由於這些應用程序場景須要服務器和客戶端之間的持續通訊。 你能夠將SSE視爲單向websocket。只有服務器能夠將消息發送到訂閱的客戶端。在許多Web應用程序中,Web套接字可能會過大。 例如,商品的價格不須要雙向通訊。服務器僅須要單向通訊來更新其全部客戶端的價格。 可是在客戶端與服務端須要強交互的場景下,Web Socket還是最佳選擇
長輪詢是一種通訊方法,客戶端按期訪問服務器獲取新數據。 適用於須要通過必定時間的計算或者人工干預的響應 SSE一般用於快速生成事件的應用程序中,即時更新。 長輪訓雖然能夠避免短輪訓形成的服務端過載,但在服務端返回數據後仍須要客戶端主動發起下一個長輪訓請求,等待服務端響應
1.SSE是單向的git
消息數據是從服務器到客戶端,單向傳遞
2.若是不使用HTTP/2會受到最大打開鏈接數的限制web
瀏覽器對每一個域名限制的http鏈接數爲6,這是跨標籤的。HTTP/2默認值是100
瀏覽器EventSource實例將建立一個持久的HTTP鏈接,直到經過調用關閉eventSource.close()。
const es = new EventSource('/v1/index/es') es.onopen = () => { console.log('es open') } es.onerror = (err) => { console.log('err', err) } es.addEventListener('test', (res) => { const { data } = res console.log('來自服端消息:', data) })
發送事件須要使用text/event-stream類型。每一個消息均以文本塊形式發送,並以一對換行符結尾。
1.格式 每條收到的消息都有如下字段的組合瀏覽器
event 標識所描述事件類型的字符串 若是指定了 在瀏覽器上將觸發指定的偵聽器 addEventListener()用於偵聽命名事件。 onmessage則處理未指定事件名稱的消息。 data 消息的數據字段 id 事件ID retry 嘗試發送事件時要使用的從新鏈接時間 必須是整數,以毫秒爲單位
const { Readable } = require('stream') // 寫入數據 const send = (stream, event, data) => { return stream.push(`event:${event}\ndata: ${JSON.stringify(data)}\n\n`) } router.all('/es', async (ctx) => { // 建立流 const reader = new Readable() reader._read = function (data) { console.log('>') } ctx.set({ 'Content-Type': 'text/event-stream', // 響應格式 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }) send(reader, 'test', { data: 111 }) ctx.body = reader let count = 1 // 模擬消息發送 const timer = setInterval(() => { send(reader, 'test', { data: 111, count: count++ }) }, 3000) // 處理鏈接斷開 ctx.req.on('close', () => { console.log('close') clearInterval(timer) reader.destroy() }) })
https://gitee.com/wjj0720/ser...