HTML5之WebSocket(轉自知乎)


在認識websocket之前,我們必須了解的是websocket有什么用? 他能解決我們遇到的什么問題? 如果沒用,那么我們就么有使用它的必要的。 

  websocket就是建立起全雙工協議的,提高了效率,節省了時間。  

 

    什么是WebSocket? WebSocket一種在單個 TCP連接上進行全雙工通訊的協議。即WebSocket是一個協議。 websocket是基於TCP協議的。

  比較通俗的理解,我們可以點擊這里

  推薦文章:

   https://zhuanlan.zhihu.com/p/23467317 (強烈推薦 --- 這篇文章詳盡介紹了websocket的原理以及長輪詢、短輪、commet, 通過鋪墊告訴我們為什么要使用 websocket。對於基本概念的理解可以看這一篇文章 )

 

  http://www.alloyteam.com/2015/04/qian-duan-qiang-hou-duan-fan-wan-node-js-socket-io-zhi-zuo-jian-yi-liao-tian-shi/ (推薦: 這篇文章是騰訊前端團隊的成員所寫,只是其中的例子都已經不能用了,但是這篇文章的思路還是非常清晰的,並且分享了自己在做項目中遇到的一些坑。)

 

  http://www.cnblogs.com/Wayou/p/hichat_built_with_nodejs_socket.html (這是講解文章,非常好。可以參考學習。)

  https://github.com/wayou/HiChat/blob/master/www/scripts/hichat.js (這是是github的源代碼)

  https://hichat.herokuapp.com/ (這個網站是聊天室在PC端的具體實現 。)

    https://www.websocket.org/index.html#  websocket官網

  https://socket.io/demos/chat/ (socket.io提供了聊天室demo) 相關https://socket.io/get-started/chat/教程: 

 

第一部分:WebSocket的特點

  • 通過TCP一次握手就可以建立連接。  而HTTP協議需要三次握手。
  • HTTP中服務器永遠是被動的,即每次只有客戶端發出請求,服務器才會響應。 但是WebSocket協議中,服務器是可以主動的向客戶端傳遞數據。這樣就避免了輪詢的問題。
  • WebSocket需要瀏覽器、服務器同時支持才可以使用,而http協議是普遍支持的。 且WebSocket是一種新的協議,只是目前為了兼容性,必須要建立在http的基礎上發起請求,如只用WebSocket協議名將不再是http:而是ws:。
  • 同樣地,WebSocket也是基於TCP協議的。

websocket 和 http 的區別

  首先要知道的時 websocket 和 http是不同的兩個協議,最大的區別在於---http協議是被動的,而websocket協議是主動的。 所謂被動就是說只有客戶端發起請求服務器端才會給出響應,而websocket顯然就是說可以由服務器端來主動給數據,也許你並沒有請求。

  

客戶端:啦啦啦,我要建立Websocket協議,需要的服務:chat,Websocket協議版本:17(HTTP Request)
服務端:ok,確認,已升級為Websocket協議(HTTP Protocols Switched)
客戶端:麻煩你有信息的時候推送給我噢。。
服務端:ok,有的時候會告訴你的。
服務端:balabalabalabala
服務端:balabalabalabala
服務端:哈哈哈哈哈啊哈哈哈哈
服務端:笑死我了哈哈哈哈哈哈哈


作者:Ovear
鏈接:https://www.zhihu.com/question/20215561/answer/40316953
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 
 
  這樣, 服務器端就可以在有消息的時候再推送消息,那么客戶端就可以減少不必要的ajax輪詢了。

 

 

 

注意: 雖然websocket和http協議是兩個不同的協議,但是我們每次在使用websocket協議時,首先要建立http協議,通過http協議,我們才能進一步升級(upgrade)為websocket協議。

 

 下面這張圖片比較好地解釋了websocket的相關原理。

 

 

相比於傳統 HTTP 的每次“請求-應答”都要 client 與 server 建立連接的模式,WebSocket 是一種長連接的模式。具體什么意思呢?就是一旦 WebSocket 連接建立后,除非 client 或者 server 中有一端主動斷開連接,否則每次數據傳輸之前都不需要 HTTP 那樣請求數據。從上面的圖可以看出,client 第一次需要與 server 建立連接,當 server 確認連接之后,兩者便一直處於連接狀態。直到一方斷開連接,WebSocket 連接才斷開。

 

第二部分: 基礎知識

  當我們獲取了WebSocket連接之后,我們就可以通過send()方法來向服務器發送數據,並通過onmessage事件來接收服務器返回的數據。下面的api用於創建一個Websocket對象。

  var Socket = new WebSocket(url, [protocol]);

  其中第一個參數是需要連接的url,后一個參數是可選的,制定可以接受的子協議。

    

WebSocket相關屬性

  即我們創建了Socket對象之后,它會有一個readyState屬性(這個和xhr的屬性同名),取值如下:

0     表示連接尚未建立

1     表示連接已經建立,可以進行通信

2     表示連接正在進行關閉

3     表示連接已經關閉或者連接不能打開

 

且websocket鏈接一旦建立,那么就可以雙方進行通信了,直到有一方主動提出終止鏈接為止。,

 

 

WebSocket方法

  WebSocket中只有兩個方法,一個是使用連接發送數據,即Socket.send(),另一個就是關閉連接,即Socket.close()。

  注意:在xhr中是沒有close相關方法的,因為一次請求一次響應的方式使得其無需close。

 

WebSocket 事件

 

  

第三部分:WebSocket實例

  在建立一個WebSocket連接的時候,客戶端瀏覽器首先向服務器發送一個http請求,這個請求和普通的http請求不同,因為在首部字段中包含了Upgrade: WebSocket; 這表明這是一個申請升級為WebSocket協議的http請求, 服務器解析這些附加的頭信息然后產生了應答信息返回給客戶端,客戶端和服務端的WebSocket連接就建立起來了,雙方就可以使用這個連接進行自由的傳遞信息,並且這個連接會持續存在到客戶端或者服務器端的某一方主動的關閉連接。

  

客戶端的HTML和JavaScript

  下面是菜鳥教程上的例子:

  View Code

  但是如果要使用,我們必須安裝 pywebsocket, 安裝過程如下:

https://looly.gitbooks.io/python-basic/100/101.html 這里有python環境的安裝教程。

http://www.runoob.com/html/html5-websocket.html 這里是pywebsocket的安裝過程。

   

 

 

第四部分: http與websocket在報文方面的差異

  這里從報文層面談一下兩者的差異。

  首先,client 發起 WebSocket 連接,報文類似於 HTTP,但主要有幾點不一樣的地方:

  

  • "Upgrade: websocket": 表明這是一個 WebSocket 類型請求,意在告訴 server 需要將通信協議切換到 WebSocket

  • "Sec-WebSocket-Key*": 是 client 發送的一個 base64 編碼的密文,要求 server 必須返回一個對應加密的 "Sec-WebSocket-Accept" 應答,否則 client 會拋出 "Error during WebSocket handshake" 錯誤,並關閉連接

 

 

  server 收到報文后,如果支持 WebSocket 協議,那么就會將自己的通信協議切換到 WebSocket,返回以下信息:

  

  • "HTTP/1.1 101 WebSocket Protocol Handshake":返回的狀態碼為 101,表示同意 client 的協議轉換請求

  • "Upgrade: websocket"

  • "Connection: Upgrade"

  • "Sec-WebSocket-Accept: *"

  • ...

   以上都是利用 HTTP 協議完成的。這樣,經過“請求-相應”的過程, server 與 client 的 WebSocket 連接握手成功,后續便可以進行 TCP 通訊了,也就沒有 HTTP 什么事了。可以查閱WebSocket 協議棧了解 WebSocket 的 client 與 server 更詳細的交互數據格式。

 

 

第五部分: websocket 與 socket的區別

  什么是socket

  網絡應用中,兩個應用程序同時需要向對方發送消息的能力(即全雙工通信),所利用到的技術就是 socket,其能夠提供端對端的通信。對於程序員而言,其需要在 A 端創建一個 socket 實例,並為這個實例提供其所要連接的 B 端的 IP 地址和端口號,而在 B 端創建另一個 socket 實例,並且綁定本地端口號來進行監聽。當 A 和 B 建立連接后,雙方就建立了一個端對端的 TCP 連接,從而可以進行雙向通信。

  進一步解釋: 可以知道socket並不是僅僅針對於網絡的,而是對於任何的雙方之間可以進行全雙工通信,我們就認為這是socket。 而不是說必須是客戶端和服務器端。

  

  WebSocekt 是 HTML5 規范中的一部分,其借鑒了 socket 的思想,為 client 和 server 之間提供了類似的雙向通信機制。同時,WebSocket 又是一種新的應用層協議,包含一套標准的 API;而 socket 並不是一個協議,而是一組接口,其主要方便大家直接使用更底層的協議(比如 TCP 或 UDP)。 

 

  即 websocket是協議,而socket是技術。

 

 

 

第五部分: websocket與socket.io的區別

  

https://socket.io/ 

Socket.IO 是一個封裝了 Websocket、基於 Node 的 JavaScript 框架,包含 client 的 JavaScript 和 server 的 Node其屏蔽了所有底層細節,讓頂層調用非常簡單

另外,Socket.IO 還有一個非常重要的好處。其不僅支持 WebSocket,還支持許多種輪詢機制以及其他實時通信方式,並封裝了通用的接口。這些方式包含 Adobe Flash Socket、Ajax 長輪詢、Ajax multipart streaming 、持久 Iframe、JSONP 輪詢等。換句話說,當 Socket.IO 檢測到當前環境不支持 WebSocket 時,能夠自動地選擇最佳的方式來實現網絡的實時通信。e

也就是說,通過socket.io,我們可以更方便的調用websocket。 比如,對於ajax的封裝就會大大提高我們的效率,而不需要自己創建,考慮兼容性問題等。 

 

 

不難理解,socket.io這個庫是結合了node更方便我們調用socket的方法的庫,更狹隘的說,socket.io是一個websocket庫, 他和express不同,因為express是node的庫,所以兩者是相互獨立的,為了開發的高效性,我們也可以同時使用express和socket.io兩個庫。

  

  

 

 

 

 

 

 

https://www.zhihu.com/question/20215561


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM