原文內容來自於LZ的印象筆記,如出現排版異常或圖片丟失等問題,可查看當前鏈接:https://app.yinxiang.com/fx/cc3b175d-5bdb-4e76-af20-849df705cb5a
開局先上一張圖:(http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html)

當前截圖來自於apache的tomcat官網(問:為什么會是中文?答:因為中文人人都懂,而英文擔心並非所有程序猿都OK撒,所以LZ的截圖為翻譯一下后的截圖);
RFC
由上圖第二列“概觀”可知,Tomcat為RFC 6455所定義的WebSocket提供支持,那么RFC又是什么?先來一段百度百科的標准解釋:
Request For Comments
簡稱RFC,是一系列以編號為排號的文件,文件收集了有關因特網的相關資訊, 以及UNIX和因特網社群的軟件文件, 幾乎所有的因特網通訊協定標准都收錄在RFC文件之中; (具體鏈接看這里:https://baike.baidu.com/item/RFC/1840?fr=aladdin);
簡單點來說RFC所記錄的協議是國際上通用且認可的Internet協議,其中任何一個協議在被創建之初,到被RFC收錄成為成為標准的Internet協議都會被具備一個STD編號,這個編號也就是當前協議在RFC中所記錄內容的唯一標識,所以,此時再看Apache Tomcat中所對應的WebSocket概述便可得知:當前Tomcat中間件所實現的Java的WebSocket協議,是根據RFC_6455所定義的WebSocket協議標准來實現的技術支持;所以,如果你想要了解對應的WebSocket協議的定義和規范,那么你應該訪問的真正網站便是RFC_6455中對應的WebSocket協議的規范和說明(想看的小伙伴,點擊這里:https://tools.ietf.org/html/rfc6455),那么為什么互聯網會產生這么多協議呢,這些協議的目的是什么,產生它的作用是什么呢?想要了解的小伙伴可以點擊這里(開局一張圖 互聯網的硬件機器的交互過程,)
WebSocket
WebSocket簡介:WebSocket協議支持客戶端之間的雙向通信,用於此的模型是常用的基於源的安全模型通過網絡瀏覽器。該協議包括一個開放握手,然后是基本的消息框架,通過TCP分層的目標,這項技術是為基於瀏覽器的機制提供的,需要與服務器進行雙向通信的應用程序不依賴於打開多個HTTP連接(例如,使用XMLHttpRequest或<iframe>和長輪詢)。
上述WebSocket的簡介來源於RFC6455中對WebSocket的定義,通過上述簡介可知,WebSocket的出現就是要為了實現一個雙向的通信協議,用以拋棄基於HTTP輪訓而實現的實時通信的效果;(當然WebSocket協議后續也做了很多優化,包括簡化http的握手認證,以及多路復用等特性,詳情也可以查看RFC中關於WebSocket最新的編碼記載(https://tools.ietf.org/html/rfc8441))
JSR-356
了解RFC以及對應的WebSocket協議說明外,此時可以查看下上述截圖的第三列“應用開發”,其中應用開發這一列所提到,Tomcat實現了JSR-356所定義的Java WebSocket 1.1API,也就是說,當前Tomcat所實現的WebSocket的具體代碼實現,是基於JSR-356所定義的JavaWebSocket API的具體實現;那么?JSR是什么?
如果說RFC是Internet上所有被提案且標准化協議的一個說明外,那么JSR則是Java的規范提案;此處來一個百度百科的具體說明,如下:
JSR是Java Specification Requests的縮寫,意思是Java 規范提案。是指向JCP(Java Community Process)提出新增一個標准化技術規范的正式請求。任何人都可以提交JSR,以向Java平台增添新的API和服務。JSR已成為Java界的一個重要標准。
JAVA有自己的專家組和規范審核組,新增的標准化技術提案和實現則需要進行嚴格的審核后,便將會作為Java的新規范而存在,那么看到這里,應該便是已經清楚了當前WebSocket在Java中的整體應用說明,各容器Tomcat以及Jetty,或者WebLoginc等等,只要是作為Java的容器而存在的項目,則在具體實現WebSocket這個協議的技術時,都必須遵守且依賴於Java自身的WebSocket接口和規范,以此來對接Java的上層應用實現邏輯;
SpringWebSocket, Tomcat WebSocket, Jetty WebSocket, Java-WebSocket.jar 的區別:
Tomcat和Jetty本身作為J2EE的容器而存在,所以Tomcat以及Jetty中對於Websocket協議的支持,都是基於Java自身所定義的接口進行的支持,各容器對WebSocket的具體實現方式不同,但常用的WebSocket接口,如@ServerPoint(定義一個WebSocket接口)等這樣的應用層規范,由於是Java自身已經定義的接口規范,所以在無需了解具體的容器實現時,只需要關注Java自身對於WebSocket的實現即可;(當然在具體使用時,需要確認當前容器的版本是否支持WebSocket以及是否引入的有對應WebSocket jar等,畢竟容器才是對外socket協議的具體實現交互類,由於Tomcat以及Jetty本身的lib下是存在對應的WebSocket具體的實現jar的,所以項目中進行引用的時候,需要設置為非runtime運行時使用的jar,或者直接將對應的容器lib直接引入到項目的librares中即可)
Java-WebSocket.jar具體是做什么?
因為Java-WebSocket.jar是github上關於java websocket的項目start數量最多的一個項目,所以,初次使用或者不熟悉Java WebSocket的同學,一般都會直接按照Java-WebSocket的實例Demo進行socket協議的效果驗證,結果在具體的J2EE web開發中,卻會發現一些莫名的問題,比如:雖然我引用了Java-WebSocket.jar但最終服務跑起來后,感覺和他並沒有神馬關系;反而會出現很多Tomcat容器不兼容等的容器異常;那么此時則必須了解下,對應的Java-WebSocket是做什么滴了,Java-WebSocket是github上一個開源大神寫的關於Java實現WebSocket的一個開源組件,使用它可以做到Java中使用WebSocket協議,但是!具體的J2EE項目中,Tomcat中所實現的WebSocket協議的具體實現,則跟當前的Java-WebSocket.jar沒有一毛錢關系,換句話說,如果你肯定是基於容器去啟動服務的情況下,那么要Java-webSocket.jar於不要這個Jar問題不大,因為Tomcat容器已經幫你實現了一套WebSocket的具體實現了,但是!如果你的服務
不是基於jetty,Tomcat等容器去啟動的話,那么你還想實現WebSocket效果,此時的Java-WebSocket.jar則是最佳的選擇,因為它可以幫你實現Main函數啟動時定義WebSocket端口等一系列事情(具體可參考github地址:https://github.com/TooTallNate/Java-WebSocket)注意:Java-WebSocket.jar對socket協議的具體實現,當然也是基於Java自身的WebSocket API規范來實現的了;
Spring-WebSocket是做什么?
既然容器已經幫我們實現了關於WebSocket協議的具體實現,那么為什么我還要引入Spring-WebSocket?我要它做什么?yes,是的,如果你只是單純的使用Tomcat所實現的WebSocket時,直接使用@ServerPoint定義WebSocket接口,然后直接使用,當然是沒有問題的撒,但是!如果你的項目是基於Spring做的開發,比如你引入了SpringMVC,還引入了SpringSecurity,那么問你個問題,既然Spring已經幫你管理了Controller控制層的訪問(基於請求攔截),也幫你做了SpringSecurity安全請求認證,那么,為什么你定義一個WebSocket接口,Spring就會直接幫你映射到這個WebSocket的控制器上嗎?答案是:當然不會,因為SpringMVC默認是做基於Http的攔截的,如果你想使用WebSocket協議,那么你只需要引入Spring-WebSocket的jar包集就行,它會幫你查找被@ServerPoint所定義的socket接口類,然后將該類定義為Socket的實現類,當然具體的Socket協議的規范實現,還是容器幫你進行實現;除此之外,既然Socket接口也是歸屬於Spring管理的,那么針對Socket協議,Spring-Socket也幫你實現了一整套的安全規范,可以設置攔截,是否允許非指定的域名訪問,等一系列效果;(建議深度使用Spring的項目可以引入Spring-Socket做一整套的控制,因為Spring Socket的確幫你實現了很多一整套的安全認證的功能,容器只是基於WebSocket的具體實現罷了,所以,各自分工不同,各個角色所做的事情,使用socket時,此處需要牢記,只有明白了各個角色所做的解耦合的事情后,出現異常問題,才更加方便和有思緒的進行排查;注:LZ所實現的WebSocket也是基於Spring socket的實現,網上也有一些基於Spring的項目,使用非spring-socket的實現,感興趣的小伙伴可以試一下,Spring本身應該也是支持開啟具體參數后,然后支持socket協議的控制層的直接傳輸,具體沒有做過驗證實現;不想重新搞的小伙伴直接按照上述的思路和角色開發,肯定是沒毛病的; 祝各位寶寶春夢了無痕;