websocket和socket的區別是什麼

2020-12-24 12:01:10

區別:Socket是TCP/IP網路的API,是為了方便使用TCP或UDP而抽象出來的一層,是位於應用層和傳輸控制層之間的一組介面;而WebSocket則是一個典型的應用層協定。

相關推薦:《》

WebSocket介紹與原理

WebSocket protocol 是HTML5一種新的協定。它實現了瀏覽器與伺服器全雙工通訊(full-duplex)。一開始的握手需要藉助HTTP請求完成。

——百度百科

目的:即時通訊,替代輪詢

網站上的即時通訊是很常見的,比如網頁的QQ,聊天系統等。按照以往的技術能力通常是採用輪詢、Comet技術解決。

HTTP協定是非持久化的,單向的網路協定,在建立連線後只允許瀏覽器向伺服器發出請求後,伺服器才能返回相應的資料。當需要即時通訊時,通過輪詢在特定的時間間隔(如1秒),由瀏覽器向伺服器傳送Request請求,然後將最新的資料返回給瀏覽器。這樣的方法最明顯的缺點就是需要不斷的傳送請求,而且通常HTTP request的Header是非常長的,為了傳輸一個很小的資料 需要付出巨大的代價,是很不合算的,佔用了很多的寬頻。

缺點:會導致過多不必要的請求,浪費流量和伺服器資源,每一次請求、應答,都浪費了一定流量在相同的頭部資訊上

然而WebSocket的出現可以彌補這一缺點。在WebSocket中,只需要伺服器和瀏覽器通過HTTP協定進行一個握手的動作,然後單獨建立一條TCP的通訊通道進行資料的傳送。

原理

WebSocket同HTTP一樣也是應用層的協定,但是它是一種雙向通訊協定,是建立在TCP之上的。

連線過程 —— 握手過程

  • 1. 瀏覽器、伺服器建立TCP連線,三次握手。這是通訊的基礎,傳輸控制層,若失敗後續都不執行。
  • 2. TCP連線成功後,瀏覽器通過HTTP協定向伺服器傳送WebSocket支援的版本號等資訊。(開始前的HTTP握手)
  • 3. 伺服器收到使用者端的握手請求後,同樣採用HTTP協定回饋資料。
  • 4. 當收到了連線成功的訊息後,通過TCP通道進行傳輸通訊。

WebSocket與HTTP的關係

相同點

  • 1. 都是一樣基於TCP的,都是可靠性傳輸協定。
  • 2. 都是應用層協定。

不同點

  • 1. WebSocket是雙向通訊協定,模擬Socket協定,可以雙向傳送或接受資訊。HTTP是單向的。
  • 2. WebSocket是需要握手進行建立連線的。

聯絡

WebSocket在建立握手時,資料是通過HTTP傳輸的。但是建立之後,在真正傳輸時候是不需要HTTP協定的。

WebSocket與Socket的關係

Socket其實並不是一個協定,而是為了方便使用TCP或UDP而抽象出來的一層,是位於應用層和傳輸控制層之間的一組介面。

Socket是應用層與TCP/IP協定族通訊的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協定族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協定。

當兩臺主機通訊時,必須通過Socket連線,Socket則利用TCP/IP協定建立TCP連線。TCP連線則更依靠於底層的IP協定,IP協定的連線則依賴於鏈路層等更低層次。

WebSocket則是一個典型的應用層協定。

區別

Socket是傳輸控制層協定,WebSocket是應用層協定。

HTML5與WebSocket的關係

WebSocket API 是 HTML5 標準的一部分, 但這並不代表 WebSocket 一定要用在 HTML 中,或者只能在基於瀏覽器的應用程式中使用。

實際上,許多語言、框架和伺服器都提供了 WebSocket 支援,例如:

  • * 基於 C 的 libwebsocket.org
  • * 基於 Node.js 的 Socket.io
  • * 基於 Python 的 ws4py
  • * 基於 C++ 的 WebSocket++
  • * Apache 對 WebSocket 的支援: Apache Module mod_proxy_wstunnel
  • * Nginx 對 WebSockets 的支援: NGINX as a WebSockets Proxy 、 NGINX Announces Support for WebSocket Protocol 、WebSocket proxying
  • * lighttpd 對 WebSocket 的支援:mod_websocket

WebSocket 機制

以下簡要介紹一下 WebSocket 的原理及執行機制。

WebSocket 是 HTML5 一種新的協定。它實現了瀏覽器與伺服器全雙工通訊,能更好的節省伺服器資源和頻寬並達到實時通訊,它建立在 TCP 之上,同 HTTP 一樣通過 TCP 來傳輸資料,但是它和 HTTP 最大不同是:

  • WebSocket 是一種雙向通訊協定,在建立連線後,WebSocket 伺服器和 Browser/Client Agent 都能主動的向對方傳送或接收資料,就像 Socket 一樣;
  • WebSocket 需要類似 TCP 的使用者端和伺服器端通過握手連線,連線成功後才能相互通訊。

非 WebSocket 模式傳統 HTTP 使用者端與伺服器的互動如下圖所示:

圖 1. 傳統 HTTP 請求響應使用者端伺服器互動圖

圖 1. 傳統 HTTP 請求響應客戶端伺服器互動圖

使用 WebSocket 模式使用者端與伺服器的互動如下圖:

圖 2.WebSocket 請求響應使用者端伺服器互動圖

圖 2.WebSocket 請求響應客戶端伺服器互動圖

上圖對比可以看出,相對於傳統 HTTP 每次請求-應答都需要使用者端與伺服器端建立連線的模式,WebSocket 是類似 Socket 的 TCP 長連線的通訊模式,一旦 WebSocket 連線建立後,後續資料都以幀序列的形式傳輸。在使用者端斷開 WebSocket 連線或 Server 端斷掉連線前,不需要使用者端和伺服器端重新發起連線請求。在海量並行及使用者端與伺服器互動負載流量大的情況下,極大的節省了網路頻寬資源的消耗,有明顯的效能優勢,且使用者端傳送和接受訊息是在同一個持久連線上發起,實時性優勢明顯。

我們再通過使用者端和伺服器端互動的報文看一下 WebSocket 通訊與傳統 HTTP 的不同:

在使用者端,new WebSocket 範例化一個新的 WebSocket 使用者端物件,連線類似 ws://yourdomain:port/path 的伺服器端 WebSocket URL,WebSocket 使用者端物件會自動解析並識別為 WebSocket 請求,從而連線伺服器端埠,執行雙方握手過程,使用者端傳送資料格式類似:

清單 1.WebSocket 使用者端連線報文

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: 
http://localhost
:8080
Sec-WebSocket-Version: 13
http://localhost
:8080
Sec-WebSocket-Version: 13

可以看到,使用者端發起的 WebSocket 連線報文類似傳統 HTTP 報文,」Upgrade:websocket」引數值表明這是 WebSocket 型別請求,「Sec-WebSocket-Key」是 WebSocket 使用者端傳送的一個 base64 編碼的密文,要求伺服器端必須返回一個對應加密的「Sec-WebSocket-Accept」應答,否則使用者端會丟擲「Error during WebSocket handshake」錯誤,並關閉連線。

伺服器端收到報文後返回的資料格式類似:

清單 2.WebSocket 伺服器端響應報文

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

「Sec-WebSocket-Accept」的值是伺服器端採用與使用者端一致的金鑰計算出來後返回使用者端的,「HTTP/1.1 101 Switching Protocols」表示伺服器端接受 WebSocket 協定的使用者端連線,經過這樣的請求-響應處理後,使用者端伺服器端的 WebSocket 連線握手成功, 後續就可以進行 TCP 通訊了。

在開發方面,WebSocket API 也十分簡單,我們只需要範例化 WebSocket,建立連線,然後伺服器端和使用者端就可以相互傳送和響應訊息,在下文 WebSocket 實現及案例分析部分,可以看到詳細的 WebSocket API 及程式碼實現。

WebSocket 實現

如上文所述,WebSocket 的實現分為使用者端和伺服器端兩部分,使用者端(通常為瀏覽器)發出 WebSocket 連線請求,伺服器端響應,實現類似 TCP 握手的動作,從而在瀏覽器使用者端和 WebSocket 伺服器端之間形成一條 HTTP 長連線快速通道。兩者之間後續進行直接的資料互相傳送,不再需要發起連線和相應。

以下簡要描述 WebSocket 伺服器端 API 及使用者端 API。

WebSocket 伺服器端 API

WebSocket 伺服器端在各個主流應用伺服器廠商中已基本獲得符合 JEE JSR356 標準規範 API 的支援,以下列舉了部分常見的商用及開源應用伺服器對 WebSocket Server 端的支援情況:

表 1.WebSocket 伺服器端支援

廠商應用伺服器備註
IBMWebSphereWebSphere 8.0 以上版本支援,7.X 之前版本結合 MQTT 支援類似的 HTTP 長連線
甲骨文WebLogicWebLogic 12c 支援,11g 及 10g 版本通過 HTTP Publish 支援類似的 HTTP 長連線
微軟IISIIS 7.0+支援
ApacheTomcatTomcat 7.0.5+支援,7.0.2X 及 7.0.3X 通過自定義 API 支援
JettyJetty 7.0+支援

以下我們使用 Tomcat7.0.5 版本的伺服器端範例程式碼說明 WebSocket 伺服器端的實現:

JSR356 的 WebSocket 規範使用 javax.websocket.*的 API,可以將一個普通 Java 物件(POJO)使用 @ServerEndpoint 註釋作為 WebSocket 伺服器的端點,程式碼範例如下:

清單 3.WebSocket 伺服器端 API 範例

 @ServerEndpoint("/echo")
 public class EchoEndpoint {

 @OnOpen
 public void onOpen(Session session) throws IOException {
 //以下程式碼省略...
 }
 
 @OnMessage
 public String onMessage(String message) {
 //以下程式碼省略...
 }

 @Message(maxMessageSize=6)
 public void receiveMessage(String s) {
 //以下程式碼省略...
 } 

 @OnError
 public void onError(Throwable t) {
 //以下程式碼省略...
 }
 
 @OnClose
 public void onClose(Session session, CloseReason reason) {
 //以下程式碼省略...
 } 
 
 }

程式碼解釋:

上文的簡潔程式碼即建立了一個 WebSocket 的伺服器端,@ServerEndpoint("/echo") 的 annotation 註釋端點表示將 WebSocket 伺服器端執行在 ws://[Server 端 IP 或域名]:[Server 埠]/websockets/echo 的存取端點,使用者端瀏覽器已經可以對 WebSocket 使用者端 API 發起 HTTP 長連線了。

使用 ServerEndpoint 註釋的類必須有一個公共的無引數建構函式,@onMessage 註解的 Java 方法用於接收傳入的 WebSocket 資訊,這個資訊可以是文字格式,也可以是二進位制格式。

OnOpen 在這個端點一個新的連線建立時被呼叫。引數提供了連線的另一端的更多細節。Session 表明兩個 WebSocket 端點對話連線的另一端,可以理解為類似 HTTPSession 的概念。

OnClose 在連線被終止時呼叫。引數 closeReason 可封裝更多細節,如為什麼一個 WebSocket 連線關閉。

更高階的客製化如 @Message 註釋,MaxMessageSize 屬性可以被用來定義訊息位元組最大限制,在範例程式中,如果超過 6 個位元組的資訊被接收,就報告錯誤和連線關閉。

注意:早期不同應用伺服器支援的 WebSocket 方式不盡相同,即使同一廠商,不同版本也有細微差別,如 Tomcat 伺服器 7.0.5 以上的版本都是標準 JSR356 規範實現,而 7.0.2x/7.0.3X 的版本使用自定義 API (WebSocketServlet 和 StreamInbound, 前者是一個容器,用來初始化 WebSocket 環境;後者是用來具體處理 WebSocket 請求和響應,詳見案例分析部分),且 Tomcat7.0.3x 與 7.0.2x 的 createWebSocketInbound 方法的定義不同,增加了一個 HttpServletRequest 引數,使得可以從 request 引數中獲取更多 WebSocket 使用者端的資訊,如下程式碼所示:

清單 4.Tomcat7.0.3X 版本 WebSocket API

public class EchoServlet extends WebSocketServlet {
@Override
protected StreamInbound createWebSocketInbound(String subProtocol,
HttpServletRequest request) {
 //以下程式碼省略....
return new MessageInbound() {
 //以下程式碼省略....
}
protected void onBinaryMessage(ByteBuffer buffer)
throws IOException {
 //以下程式碼省略...
}
protected void onTextMessage(CharBuffer buffer) throws IOException {
 getWsOutbound().writeTextMessage(buffer);
 //以下程式碼省略...
}
};
}
}

因此選擇 WebSocket 的 Server 端重點需要選擇其版本,通常情況下,更新的版本對 WebSocket 的支援是標準 JSR 規範 API,但也要考慮開發易用性及老版本程式移植性等方面的問題,如下文所述的客戶案例,就是因為客戶要求統一應用伺服器版本所以使用的 Tomcat 7.0.3X 版本的 WebSocketServlet 實現,而不是 JSR356 的 @ServerEndpoint 註釋端點。

WebSocket 使用者端 API

對於 WebSocket 使用者端,主流的瀏覽器(包括 PC 和行動終端)現已都支援標準的 HTML5 的 WebSocket API,這意味著使用者端的 WebSocket JavaScirpt 指令碼具備良好的一致性和跨平臺特性,以下列舉了常見的瀏覽器廠商對 WebSocket 的支援情況:

表 2.WebSocket 使用者端支援

瀏覽器支援情況
ChromeChrome version 4+支援
FirefoxFirefox version 5+支援
IEIE version 10+支援
SafariIOS 5+支援
Android BrowerAndroid 4.5+支援

使用者端 WebSocket API 基本上已經在各個主流瀏覽器廠商中實現了統一,因此使用標準 HTML5 定義的 WebSocket 使用者端的 JavaScript API 即可,當然也可以使用業界滿足 WebSocket 標準規範的開源框架,如 Socket.io。

以下以一段程式碼範例說明 WebSocket 的使用者端實現:

清單 5.WebSocket 使用者端 API 範例

var ws = new WebSocket(「ws://echo.websocket.org」); 
 ws.onopen = function(){ws.send(「Test!」); }; 
 ws.onmessage = function(evt){console.log(evt.data);ws.close();}; 
 ws.onclose = function(evt){console.log(「WebSocketClosed!」);}; 
 ws.onerror = function(evt){console.log(「WebSocketError!」);};

第一行程式碼是在申請一個 WebSocket 物件,引數是需要連線的伺服器端的地址,同 HTTP 協定開頭一樣,WebSocket 協定的 URL 使用 ws://開頭,另外安全的 WebSocket 協定使用 wss://開頭。

第二行到第五行為 WebSocket 物件註冊訊息的處理常式,WebSocket 物件一共支援四個訊息 onopen, onmessage, onclose 和 onerror,有了這 4 個事件,我們就可以很容易很輕鬆的駕馭 WebSocket。

當 Browser 和 WebSocketServer 連線成功後,會觸發 onopen 訊息;如果連線失敗,傳送、接收資料失敗或者處理資料出現錯誤,browser 會觸發 onerror 訊息;當 Browser 接收到 WebSocketServer 傳送過來的資料時,就會觸發 onmessage 訊息,引數 evt 中包含 Server 傳輸過來的資料;當 Browser 接收到 WebSocketServer 端傳送的關閉連線請求時,就會觸發 onclose 訊息。我們可以看出所有的操作都是採用非同步回撥的方式觸發,這樣不會阻塞 UI,可以獲得更快的響應時間,更好的使用者體驗。

想要查閱更多相關文章,請存取!!

以上就是websocket和socket的區別是什麼的詳細內容,更多請關注TW511.COM其它相關文章!