通訊技術:SSE設計方案(一)--- 前端Server-Sent Events概念講解和基礎類庫完善發佈

好了,開篇仍是要扯扯的,不然感受這個技術講的麼有那麼凍人,嗯,這個晚上是有點冷了,秋衣秋褲你們都該加起來了,反正我不幫你買,妹子除外,嘻嘻。html

以前幾篇博客,研究前端通訊技術的第一層ajax技術,從最基礎的東西開始開發兼容,而後到最近的1.6版本吧,前先後後幾乎將ajax的全部能用的技術都研究過一遍了,在github上也獲得了120+的star,在這裏我要感謝你們的支持。主要這裏爲何會這樣說呢,由於以前獲得你們的承認和鼓勵,因此此次將進行前端通訊技術的第二個階段的研究了,也就是前端的服務器推送 --- Server-Sent Events技術的研究。夜深了,不扯太多廢話了,咱們直接進入主題。前端

概念講解:node

  Server-Sent Events:簡稱SSE技術,也是前端es5支持的一種基於http協議的服務器推送技術。git

  EventSource:js中承載SSE技術的主要核心方案和方法github

  單工通道:只能一方面的數據導向,例如,在咱們前端,咱們經過瀏覽器向服務器請求數據,可是服務器不會主動推送數據給咱們,這就是單通道web

  雙工通道:相似webSocket這樣的技術,客戶端能夠推數據給服務器,服務器也能夠推數據給客戶端(下個版本實現)ajax

  定點推送:服務器能夠將數據針對單個客戶端推送(下個版本實現)chrome

  多人推送:服務器能夠將數據一次性推送給全部人(下個版本實現)npm

 

兼容性(看下圖):json

  

 在全部IE系列中都不支持,其餘瀏覽器幾乎均可以實現,因此爲了實現萬惡的IE,會有以下2種方案

  1.  在其餘瀏覽器上使用原生 EventSource 對象,而在 IE 上則使用簡易輪詢或 COMET 技術來實現;
  2.  使用 polyfill 技術,即便用第三方提供的 JavaScript 庫來屏蔽瀏覽器的不一樣。本文使用的是 polyfill 技術,只須要在頁面中加載第三方 JavaScript 庫便可。應用自己的瀏覽器端代碼並不須要進行改動。

  因此,這個方案,我會在最後一個版本和博客專門作兼容,暫時咱們就忽略這個兼容性問題

  

對於其餘通訊技術的比較(也就是何時作這樣的技術選型)

  • sse是基於http協議的,對於現有項目的改造和支持是成本最低的方案。webSocket須要先後端全都換上新的協議支持
  • 對於推送的頻率來講,針對小於1次/1的推送,sse的使用最合適。大於1次的使用不划算,建議webSocket(考慮成本)
  • WebSocket 技術也比較複雜,包括服務器端和瀏覽器端的實現都不一樣於通常的 Web 應用。
  • 對於輪詢來講的話,每次的http協議的建立和銷燬對性能有點要求,何況對這個輪詢的時間點也不是能特別好的把握

  so,sse只是針對在適合他的地方纔是最好的,這些點爲你們作技術選型作些參考。

 

客戶端(瀏覽器)技術講解:

  在客戶端,也就是瀏覽器中,承載這個技術的就是EventSource了,下面直接上代碼吧

// 通用方案
create:function (options) {         // option爲可配置參數
    var param = tool.initParam(options),sendData = '';          // 將用戶參數和默認參數合併

    if (param.data){        // 判斷是否傳遞參數給服務器,作參數處理
        tool.each(param.data, function (item, index) { sendData += (index + "=" + item + "&") }); sendData = sendData.slice(0, -1); } var es = new EventSource(param.url+'?'+sendData);  //建立EventSource連接
 es.addEventListener('open',function (e) {   // 註冊默認open事件
 param.openEvent(e) }); es.addEventListener('message',function (e) {    // 註冊默認message事件,若是服務器不指定回掉,則走這個
 param.messageEvent(e) }); es.addEventListener('error',function (e) {      // 註冊默認error事件
 param.errorEvent(e) }); // 建立用戶自定義事件
    if (param.customEvent.length > 0){ tool.each(param.customEvent,function (item) { es.addEventListener(item.name,item.callback); }) } }

  固然客戶端還有表明連接狀態的參數es.readyState:

    • 至關於常量EventSource.CONNECTING,表示鏈接還未創建,或者鏈接斷線。
    • 至關於常量EventSource.OPEN,表示鏈接已經創建,能夠接受數據。
    • 至關於常量EventSource.CLOSED,表示鏈接已斷,且不會重連。

  message回調的返回值(可本身debugger看):

    data:服務器端傳回的數據(文本格式)。
    origin: 服務器端URL的域名部分,即協議、域名和端口。
    lastEventId:數據的編號,由服務器端發送。若是沒有編號,這個屬性爲空。

  

  簡單解釋下:經過先new EventSource對象,創建鏈接,而後註冊一些默認事件和自定義事件,就結束了,客戶端就這麼簡單。主要在服務端。

 

默認參數以下(有些參數預先定義下個版本使用):

var initParam = { url :'',                                //所連接的服務器地址
    data:'',                                //所發送的客戶端數據
    customEvent:[],                         //自定義事件 格式:[{name:'事件名稱',callback:function(res){}}]
    withCredentials:false,                 //是否發送跨域憑證
    serverTimeout:60000,                    //服務器http默認超時時間 待考慮:客戶端配置服務器時間,不安全
    clientConnection:3000,                  //設置瀏覽器重連時間,瀏覽器默認3s重連,
    openEvent:function () {},              //客戶端開始連接的事件
    messageEvent:function () {},           //客戶端接受到消息的事件(如不自定義系統默認)
    errorEvent:function () {}              //客戶端錯誤事件
}

 

服務器講解:

  對於創建鏈接的服務器,針對連接的客戶端有以下返回參數:

    :這是註釋        單獨一個冒號,表明服務器推送的一個註釋。(這個可解決http中的324,發送心跳包)

    id:11        表明數據標識符,表明當前數據的惟一標識(若是斷線,客戶端會在下次http head中發送這個標識,可作數據傳輸標記)

    data:我是誰    這個數據就是客戶端所接受到的數據(可推送格式化過的json數據)

    event:myEvent    服務器返回客戶端所執行事件(如不定義默認執行message事件)  

    retry:3000      客戶端在http超時斷開後多長時間從新鏈接

 

  對於服務器的這些參數的互相組合,是否是忽然有種腦洞大開的感受,下個版本將在這些參數中作文章,實現開頭所說的各類花樣技術

 

對於作測試中發現的許多問題拋出,可能你也會想到,這些問題都將在下幾個版本作完善

  • 客戶端兼容性問題(這個後面作)
  • 客戶端重連時間中,是否會丟失數據
  • 服務器的http協議超時時間的設置
  • 對於連接中出現的服務器返回超時
  • 如何作到單點推送,羣推送
  • 服務器如何丟棄已斷開的連接
  • .......

 

測試以下(跳過ie系列)

  chrome:

   

  火狐:

  

  opera:

  

  safair:暫時沒有mac支持,淡定

 

全部都上傳github了,可直接拉去github上的東西作測試,地址:https://github.com/GerryIsWarrior/SSE不要忘記點顆star支持我,至少獲得了你的承認,我會繼續研究下去。

  js-ommon:爲通常開發使用,直接引入js文件的

  js-node:爲node代碼,作簡易服務器用的

  js-npm:發的npm打包代碼,可npm i sse-js / yarn add sse-js 安裝

  index.html:爲測試html頁面

 

總結:

這篇博客主要講解sse技術的基礎概念,由於基礎概念比較多,若是和第二版本一塊兒搞上去,博文確定不少不少,沒有耐心看下去了,因此這個博文只是讓你們對這個概念有所瞭解,知道這個東西是什麼,能作什麼,有啥新奇的玩意,能解決項目的什麼問題。固然,我既然研究這個技術,固然爲了保證將這個類庫寫好,至少能夠到生產上使用這個類庫,固然這個路不是那麼好走的,還須要不停的去研究和改正。正如我正在走的開發的路,都要咱們一步一個腳印的去走的,共勉。

夜已深,你們晚安,明天發表這個博客...

相關文章
相關標籤/搜索