有關WebSocket必須瞭解的知識

.~P 發表於 2020-07-31

一、前言

最近之前時間正好在學習java知識,所以自個想找個小專案練練手,由於之前的ssm系統已經跑了也有大半年了,雖然稀爛,但是功能還是勉強做到了,所以這次準備重構ssm系統,改名為postCode系統(至於為什麼前者叫ssm,可能是因為後端java用的是ssm框架吧),這次後端將不會開發兩套,而是主要實現之前沒有實現的單聊功能,由於搭建了多個服務,通訊使用的是RabbitMQ,然後把著對訊息通訊的原理研究寫下了這篇水文,後面會單獨淺談一些RabbitMQ。


二、TCP/IP模型

tcp/ip模型算是大學計算機學科中必學的一段知識,但長時間不接觸,又都還給老師了。

tcp/ip模型是網際網路的基礎,它是一些列協議的總稱,tcp/ip模型又可以劃分為osi七層模型

OSI七層模型 TCP/IP概率模型 功能 TCP/IP協議族
應用層 應用層 檔案傳輸、郵件傳輸 ftp、smtp
表示層 資料格式化,程式碼轉換,資料加密 沒有協議
會話層 接觸或者建立於別的介面聯絡 沒有協議
傳輸層 傳輸層 提供端對端的介面 TCP、UDP
網路層 網路層 為資料包選擇路由 IP、ICMP、RIP、OSPF
資料鏈路層 鏈路層 傳輸有地址的幀以及錯誤檢查功能 SLIP、CSLIP、PPP、ARP
物理層 以二進位制資料形式在物理媒介上傳輸資料 IS02110

2.1、UDP的特點

無連線

  • UDP無需建立三次握手,而是想要傳送資料的時候就可以直接送
  • 傳送端:將收到應用層的資料增加一個UDP的標識就傳送出去了
  • 接受端:將UDP協議的標識去掉就傳輸給應用層了

可以單播,多播,廣播

UDP支援一對一、一對多、多對多、多對一的傳輸方式。

不可靠性

通訊不需要建立連線,也不需要管對方有沒有收到,而是想發就發,這樣的連線是不安全的

2.2、TCP的特點

  • 面向連線
  • 僅支援單播傳輸
  • 可靠性

TCP提供全雙工通訊(重點重點)

TCP允許通訊雙方的應用程式在任何時候都能傳送資料,因為TCP連線的兩端都設有快取,用來臨時存放雙向通訊的資料。當然,TCP可以立即傳送一個資料段,也可以快取一段時間以便一次傳送更多的資料段(最大的資料段大小取決於MSS)


三、Socket程式設計

在瞭解WebSocket程式設計之前要先了解了解Socket

什麼是Socket

起初應用層的資料到達傳輸層後需要依賴tcp/ip協議族建立tcp連線,然後tcp又需要依賴網路層的ip協議等,從而產生了不同資料格式依賴不同協議模型的尷尬局面,導致一些列安全和網路阻塞問題,從而誕生了socket的介面。

  • socket的誕生是為了應用程式能夠更方便的將資料經由傳輸層來傳輸
  • socket本質上就是對TCP/IP 的運用進行了一層封裝
  • socket並不是協議,而是介於應用層和傳輸層之間抽象出來的一層,是一組介面
  • socket建立連線和斷開連線和普通的tcp連線一樣需要進行三次握手和四次揮手
  • socket可以建立長連線和短連線
  • socket主要是應用在C/S(Client/Server)模式裡
  • 所有的連線都需要經過socket介面

最後可以簡單的理解為socket對tcp/ip封裝後向應用層提供一些更加方便傳輸資料的介面。


四、WebSocket

因為socket只能是在C/S架構出現,瀏覽器端操作都處於應用層,所以Html5中提出了WebSocket通訊協議,為了解決真正意義上的全雙工通訊的難題。

  • 建立WebSocket連線前會先傳送一個Header裡面有Upgrade:Websocket的http請求
  • ws和wss都屬於WebSocket的通訊協議,wss和https一樣都只是多了TLS協議

不同網路通訊協議的對應關係

WebSocket XMLHttpRequest
通訊協議 ws http
通訊協議+TLS協議 wss https

4.1、ScokJS/Socket.IO

ScokJS

  • ScokJS是一套基於WebSocket Api封裝的js庫,它在瀏覽器和web伺服器之間建立了一個低延遲、全雙工、跨域通訊通道。
  • Spring框架提供了基於SockJS協議的透明的回退選項;Spring Framework也是SockJS推薦Java Server的實現,同時也提供了Java 的client實現
  • SockJS的一大好處在於提供了瀏覽器相容性。優先使用原生WebSocket,如果在不支援websocket的瀏覽器中,會自動降為輪詢的方式。
  • 因此伺服器如果是spring環境,應該優先使用ScokJS

Socket.IO

  • Socket.io和ScokJS一樣都是基於WebSocket Api封裝的js庫,同樣也是為了解決部分瀏覽器不支援WebSocket而誕生的js庫。
  • Socket.io本身設計就是提供了一套node環境的全雙工連線,所有在node環境作為伺服器使用Socket.io的時候還需要繫結http.Server服務,因為WebSocket協議是構建在HTTP協議之上的
  • 因此伺服器如果是node環境,應該優先使用Socket.io

4.2、STOMP/vue-socket

雖然ScokJS和Socket.IO都解決了瀏覽器相容性問題,但是在進行雙向通訊的過程中是不遵循任何訊息協議的,也就是當訊息到達應用層後就只剩訊息文字本身了,所以不利於跨平臺和多端通訊,於是對應約束訊息格式的訊息協議的就誕生了。

STOMP

  • STOMP是一種基於幀的協議,幀的結構是效仿HTTP報文格式
  • STOMP可以直接使用WebSocket進行連線,也可以使用SockJS進行連線
    • Stomp.client(url) 通過WebSocket直接連線
    • Stomp.over(ws) 通過sockJS進行連線
  • STOMP更加適合於做於訊息元件,其中的方法設計都是可以配合rabbitMQ使用的,只需要在rabbitMQ中安裝rabbitmq_web_stomprabbitmq_web_stomp_examples就可以了

vue-socket

  • vue-socket和STOMP一樣都是訊息協議,vue-socket底層是基於socket.io封裝的js庫,對vue支援會更好。

有關WebSocket必須瞭解的知識