一、前言
最近之前時間正好在學習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_stomp
和rabbitmq_web_stomp_examples
就可以了
vue-socket
- vue-socket和STOMP一樣都是訊息協議,vue-socket底層是基於
socket.io
封裝的js庫,對vue支援會更好。