DEV Community

Cover image for 淺談即時通訊系統以及Socket.io、Socket、WebSocket 差異
Angus
Angus

Posted on

淺談即時通訊系統以及Socket.io、Socket、WebSocket 差異

先前的專案中使用過 socket.io 實做聊天室功能,當初的概念只有 1. 事件驅動 2. HTTP之外的通訊協議 3. 即時互動,今天就來詳細了解 Websocket 與 HTTP 和網路是什麼關係、最後再來比較 socket.io 與 WebSocket 以及 socket 之間的差別。

在比較三者之間的差別之前必須要先理解為什麼我們不 HTTP 與 Websocket 之間的差別。

從 HTTP 來比對即時通訊系統

傳統的瀏覽器以及 HTTP 早期只能夠從 client 端主動發出請求接著 server 端回應並回覆請求來實現資料互動,不過有許多像是監控、即時線上通訊、即時報價等情境,需要的是將後台發生的變化主動、即時的傳到瀏覽器端,而不是等待用戶手動更新頁面,也因此應運而生了許多方案。

  1. 輪詢 ( polling ):最簡單的方案。用戶端定期發送 AJAX 請求,伺服器再收到請求之後立刻回傳資料。雖然確保了資料的相對即時性也具有良好的瀏覽器相容性也很簡單。不過輪詢的頻率是最致命的缺點,舉例來說:當輪詢頻率太高時,就會產生大量無效請求; 過低時資料的即時性變差,同時,伺服器端壓力變大,進而浪費頻寬流量。

    function polling() {
    console.log("polling");
    }
    setInterval(shortPolling, 1000);

    1. 長輪詢(long-polling) :可想成輪詢的優化版本:用戶端透過 AJAX 發起請 求,伺服器端再接到請求後不馬上回傳,而是保持連接,等待資料更新。一旦有資料需要發送給用戶端時,伺服器端才將目標資料發送給用戶端,傳回請求。用戶端收到回應之後,馬上再發起一個新的請求給伺服器端,持續循環。

雖然能夠有效減少輪詢的次數以及大幅降低延遲,但伺服器需要保持大量的連結,也是會產生一定的消耗。

圖一、[polling 與 long-polling 差異](https://codeburst.io/polling-vs-sse-vs-websocket-how-to-choose-the-right-one-1859e4e13bd9)

function longPolling() {
  setTimeout(function() {
    console.log("Long Polling");
    longPolling();
  }, 1000);
}
longPolling();
Enter fullscreen mode Exit fullscreen mode
  1. Comet streaming :此技術又被稱作 Forever iframe,需要我們動態載入一個隱藏的 iframe 標籤, iframe 標籤的 src 會指向請求的伺服器位址。同時 client 端會準備好一個處理資料的函式,在伺服器端透過 iframe 標和用戶端通訊時,伺服器端便會傳回 script 標籤的文字,用戶端會將其解析為 JavaScript 指令稿,並呼叫預先準備好的函數,將資料傳遞給 parant window,類似 JSONP 的實現原理,程式如下。

    parant.getData("data from server")

  2. JAX multipart streaming:使用到了 HTTP 1.1 中的 multipart 特性:client 發送請求,server 保持連接,再利用 HTTP 1.1 的 chunked encoding 機制 (分段傳輸編碼 ) 將資料傳遞給用戶端,直到逾時或 client 端手動中斷才停止傳輸。

  • 乍看之下與 WebSocket 功能似乎相同不過由於 HTTP 1.1 中的 multipart 特性並沒有被瀏覽器廣泛支援,此方法並不常見。
  1. WebScoket:是從 HTML 5 開始提供的一種在瀏覽器與伺服器間進行全雙工通訊的網路技術。依靠此技術可以實現 client 端與 server 端的長連接,達到雙向即時通訊的效果。

圖二、[WebSocket 與long-polling ](https://ably.com/blog/websockets-vs-long-polling)差異

從 HTTP 與 WebSocket 的關係 ?

網路七層架構( 日後再寫 )中,HTTP 與 WebSocket 都屬於第七層的應用層協定,且都是以 TCP 為基礎來傳輸資料。 WebSocket 依賴一種升級的 HTTP 進行一次驗證,驗證成功之後資料即可在 TCP 通道中進行傳輸了。

如此一來,連接的發起端始終是 clinet 端,不過一旦WebSocket 連接建立之後,不論是 clinet 端還是 server 端都可以向對方發送資料。

即使 WebSocket 強大,還是錯過了瀏覽器為 HTTP 提供的一些服務,這些服務就需要開發者自行實現,因此 WebSocket 暫時還無法取代 HTTP 。

Socket.io、Socket、WebSocket 差異

講了這麼多終於談到今天的主題了,在進入主題之前TCP/IP 的四個層級介紹可以更了解三者之間的關係。

TCP/IP 的四個層級介紹:

  • 應用層 (Application Layer):網路模型的最上層,也是想要利用網路傳輸資料的程式,能夠直接碰觸到的層級。EX: telnet、FTP、WWW、Email、DNS、socket.io、HTTP、WebSocket、engine.io

  • 傳輸層 (Transport Layer):此層對應用層傳送過來的資料進行處理,建立2台電腦之間可靠的傳輸,在此層常見的2種協定為TCP與UDP。

  • 網路層 (IP Network Layer):網路層能夠提供實體介面網路卡一個邏輯上的位置,也就是我們常聽到的IP位址。

  • 鏈接層 (Network Access Layer):位於整個網路架構的最底層,負責制定資料傳輸的「實體」規格 ,EX:乙太網路的規格等。

圖三、四層架構

Socket 是甚麼 ? 它在哪裡 ?

Socket是應用層與TCP/IP協議通信的中間軟體抽象層,它是一組介面 ( *Socket Interface *)

在設計模式中, Socket其實就是一個門面模式,它把複雜的TCP/IP協議隱藏在Socket介面後面,對用戶來說,一組簡單的介面就是全部,讓Socket去組織數據。

圖三、socket 位於*傳輸層跟應用層之間*

介紹完 socket 後相信讀者對於應用層中的 Socket.io 與 Websocket 又更好奇了

WebSocket

WebSocket 顧名思義,就是為了提升 web 通訊速度而被創造出來的一種「協議」,它的原理是在瀏覽器底層以剛剛提到的「socket」當作通訊介面,通訊協議才是採用它自身的「Websocket協議」。

可以想成協議與介面都裝在瀏覽器上,因此只要瀏覽器支援,就可以使用這個協議透過web來跟伺服器做溝通。

WebSocket 與 HTTP 的關係

我們都清楚要和 server 溝通需要通過 HandShaking ,Websocket 也不例外,而第一次 HandShaking 則是使用「HTTP協議」接下來 HTTP協議就不會再用到囉,而是使用 Websocket 協議。

socket.io && engin.io

那大家最熟悉的 socket.io 又是甚麼呢 ? 解決了甚麼問題呢 ?

與 WebScoket 一樣 socket.io 也是為了解決 web 即時通訊而誕生的,不一樣的是 socket.io 是一個框架而不是協議。

上面有提到要在瀏覽器有支援的前提之下才能使用 WebSocket ,那如果瀏覽器不支援,而程式裡使用了 WebSocket 的技術時怎麼辦呢 ??

socket.io 解決了這個問題,在大部分情況之下 WebSocket 與 socket.io都是使用 WebSocket 協議做即時的通訊,不過當遇到上述情境時,socket.io會改選擇使用傳統的 long-polling ( 長輪詢 ) 方式運作

沒錯!! 就是一開始介紹的那種即時通訊方式。

不過 socket.io 僅僅是在上層做一些介面封裝,真正連線的角色是 engin.io 舉凡通訊相關,連接等等,都是engine.io在實現。

小結:講了這麼多,最後用個表格來簡單區分 WebSocket 與 Socket.io 的主要差別。

Top comments (0)