有關WebSocket必須瞭解的知識
阿新 • • 發佈:2020-08-01
## 一、前言
最近之前時間正好在學習java知識,所以自個想找個小專案練練手,由於之前的ssm系統已經跑了也有大半年了,雖然稀爛,但是功能還是勉強做到了,所以這次準備重構ssm系統,改名為postCode系統(至於為什麼前者叫ssm,可能是因為後端java用的是ssm框架吧),這次後端將不會開發兩套,而是主要實現之前沒有實現的單聊功能,由於搭建了多個服務,通訊使用的是RabbitMQ,然後把著對訊息通訊的原理研究寫下了這篇水文,後面會單獨淺談一些RabbitMQ。
-----------------------
## 二、TCP/IP模型
tcp/ip模型算是大學計算機學科中必學的一段知識,但長時間不接觸,又都還給老師了。
tcp/ip模型是網際網路的基礎,它是一些列協議的總稱,tcp/ip模型又可以劃分為osi七層模型
### 2.1、UDP的特點
**無連線**
> * UDP無需建立三次握手,而是想要傳送資料的時候就可以直接送
> * 傳送端:將收到應用層的資料增加一個UDP的標識就傳送出去了
> * 接受端:將UDP協議的標識去掉就傳輸給應用層了
**可以單播,多播,廣播**
> UDP支援一對一、一對多、多對多、多對一的傳輸方式。
**不可靠性**
> 通訊不需要建立連線,也不需要管對方有沒有收到,而是想發就發,這樣的連線是不安全的
### 2.2、TCP的特點
> * 面向連線
> * 僅支援單播傳輸
> * 可靠性
**TCP提供全雙工通訊(重點重點)**
> TCP允許通訊雙方的應用程式在任何時候都能傳送資料,因為TCP連線的兩端都設有快取,用來臨時存放雙向通訊的資料。當然,TCP可以立即傳送一個數據段,也可以快取一段時間以便一次傳送更多的資料段(最大的資料段大小取決於MSS)
---------------------
## 三、Socket程式設計
> 在瞭解WebSocket程式設計之前要先了解了解Socket
**什麼是Socket**
* [超詳細文件](http://c.biancheng.net/view/2123.html)
> 起初應用層的資料到達傳輸層後需要依賴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**
* [使用文件](https://www.w3cschool.cn/socket/)
* [原理文件](https://www.jianshu.com/p/4e80b931cdea)
> * 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**
* [使用文件](https://www.cnblogs.com/goloving/p/10746378.html)
> * STOMP是一種基於幀的協議,幀的結構是效仿HTTP報文格式
> * STOMP可以直接使用WebSocket進行連線,也可以使用SockJS進行連線
> * `Stomp.client(url)` 通過WebSocket直接連線
> * `Stomp.over(ws)` 通過sockJS進行連線
> * STOMP更加適合於做於訊息元件,其中的方法設計都是可以配合rabbitMQ使用的,只需要在rabbitMQ中安裝`rabbitmq_web_stomp`和 `rabbitmq_web_stomp_examples`就可以了
**vue-socket**
> * vue-socket和STOMP一樣都是訊息協議,vue-socket底層是基於`socket.io`封裝的js庫,對vue支援會更好。
![](https://img2020.cnblogs.com/blog/1370048/202007/1370048-20200731230600391-1149430
OSI七層模型 | TCP/IP概率模型 | 功能 | TCP/IP協議族 | |
---|---|---|---|---|
應用層 | 應用層 | 檔案傳輸、郵件傳輸 | ftp、smtp | |
表示層 | 資料格式化,程式碼轉換,資料加密 | 沒有協議 | ||
會話層 | 接觸或者建立於別的介面聯絡 | 沒有協議 | ||
傳輸層 | 傳輸層 | 提供端對端的介面 | TCP、UDP | |
網路層 | 網路層 | 為資料包選擇路由 | IP、ICMP、RIP、OSPF | |
資料鏈路層 | 鏈路層 | 傳輸有地址的幀以及錯誤檢查功能 | SLIP、CSLIP、PPP、ARP | |
物理層 | 以二進位制資料形式在物理媒介上傳輸資料 | IS02110 |