以前提到Lua 與nodejs使用socket通訊,但因爲服務端的限制,最終依然選擇了 LuaSocket。php
如今,面對一個全新的項目,我天然而然地選擇了 WebSocket。html
所以,我須要瞭解下面這些問題:html5
可是,目前網上全面介紹這兩種協議的中文文章並很少,或者說不夠全面。我沒法找到一篇文章能解決上面的全部問題。所以,我寫了本文,把找到的 Socket 和 WebSocket 的相關資料作一個梳理,以方便理解。node
本文並不能直接完整回答上面提出的幾個問題,但讀完本文,要理解上面的那些問題,是很容易的事。nginx
因爲能力有限,本文不可能很長。並且,技術細節並不是全部人都願意仔細瞭解。本文包含了大量的外部連接,跟隨這些連接,能夠找到足夠多的細節,知足你/個人求知慾。git
選擇了 WebSocket 技術以後,不可避免的,我要將它和其餘協議以及技術作一下比較。最多見的,就是須要比較 WebSocket 與 HTTP、Socket 技術的異同。github
WebSocket 是爲了知足基於 Web 的日益增加的實時通訊需求而產生的。在傳統的 Web 中,要實現實時通訊,通用的方式是採用 HTTP 協議不斷髮送請求。但這種方式即浪費帶寬(HTTP HEAD 是比較大的),又消耗服務器 CPU 佔用(沒有信息也要接受請求)。(下圖來自 WebSocket.org)web
而是用 WebSocket 技術,則會大幅下降上面提到的消耗:(下圖來自 websocket.org)apache
關於更詳細的描述,尹立的這篇文章講得很是好:WebSocket(2)–爲何引入WebSocket協議 。編程
那麼,WebSocket 到底與 HTTP 協議究竟是一個什麼樣的關係呢?它和 Socket 又有什麼聯繫?這就要講到 OSI 模型和 TCP/IP 協議族。
如下是 維基百科 中關於OSI 模型的說明:
開放式系統互聯通訊參考模型(英語:Open System Interconnection Reference Model,ISO/IEC 7498-1),簡稱爲OSI模型(OSI model),一種概念模型,由國際標準化組織(ISO)提出,一個試圖使各類計算機在世界範圍內互連爲網絡的標準框架。
而 TCP/IP 協議能夠看作是對 OSI 模型的一種簡化(如下內容來自 維基百科):
它將軟件通訊過程抽象化爲四個抽象層,採起協議堆疊的方式,分別實做出不一樣通訊協議。協議套組下的各類協議,依其功能不一樣,被分別歸屬到這四個階層之中7,常被視爲是簡化的七層OSI模型。
這裏有一張圖詳細介紹了 TCP/IP 協議族中的各個協議在 OSI模型 中的分佈,一圖勝千言(下圖來自 科來):
這裏是 PDF 版:
TCP/IP 協議和 OSI 模型的內容,在互聯網上有不少。我沒有必要再次介紹它們。在這裏,咱們只須要知道,HTTP、WebSocket 等協議都是處於 OSI 模型的最高層: 應用層 。而 IP 協議工做在網絡層(第3層),TCP 協議工做在傳輸層(第4層)。
至於 OSI 模型的各個層次都有什麼系統和它們對應,這裏有篇很好的文章能夠知足你們的求知慾:OSI七層模型詳解 。
從上面的圖中能夠看出,HTTP、WebSocket 等應用層協議,都是基於 TCP 協議來傳輸數據的。咱們能夠把這些高級協議理解成對 TCP 的封裝。
既然你們都使用 TCP 協議,那麼你們的鏈接和斷開,都要遵循 TCP 協議中的三次握手和四次握手 ,只是在鏈接以後發送的內容不一樣,或者是斷開的時間不一樣。
更詳細內容可閱讀:wireshark抓包圖解 TCP三次握手/四次揮手詳解
對於 WebSocket 來講,它必須依賴 HTTP 協議進行一次握手 ,握手成功後,數據就直接從 TCP 通道傳輸,與 HTTP 無關了。
Socket 其實並非一個協議。它工做在 OSI 模型會話層(第5層),是爲了方便你們直接使用更底層協議(通常是 TCP 或 UDP )而存在的一個抽象層。
最先的一套 Socket API 是 Berkeley sockets ,採用 C 語言實現。它是 Socket 的事實標準,POSIX sockets 是基於它構建的,多種編程語言都遵循這套 API,在 JAVA、Python 中都能看到這套 API 的影子。
下面摘錄一段更容易理解的文字(來自 http和socket之長鏈接和短鏈接區別):
Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。
主機 A 的應用程序要能和主機 B 的應用程序通訊,必須經過 Socket 創建鏈接,而創建 Socket 鏈接必須須要底層 TCP/IP 協議來創建 TCP 鏈接。創建 TCP 鏈接須要底層 IP 協議來尋址網絡中的主機。咱們知道網絡層使用的 IP 協議能夠幫助咱們根據 IP 地址來找到目標主機,可是一臺主機上可能運行着多個應用程序,如何才能與指定的應用程序通訊就要經過 TCP 或 UPD 的地址也就是端口號來指定。這樣就能夠經過一個 Socket 實例惟一表明一個主機上的一個應用程序的通訊鏈路了。
而 WebSocket 則不一樣,它是一個完整的 應用層協議,包含一套標準的 API 。
因此,從使用上來講,WebSocket 更易用,而 Socket 更靈活。
WebSocket API 是 HTML5 標準的一部分, 但這並不表明 WebSocket 必定要用在 HTML 中,或者只能在基於瀏覽器的應用程序中使用。
實際上,許多語言、框架和服務器都提供了 WebSocket 支持,例如: