websocket 協議

WebSocket 協議和知識


WebSocket是一種在單個TCP連接上進行全雙工通信的協議。WebSocket通信協議於2011年被IETF定爲標準RFC 6455,並由RFC7936補充規範。WebSocket API也被W3C定爲標準。

WebSocket協議是基於TCP的一種新的網絡協議,和http協議一樣屬於應用層協議

WebSocket使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,並進行雙向數據傳輸。


 

爲什麼會有 WebSocket

衆所周知,Web應用的通信過程通常是客戶端通過瀏覽器發出一個請求,服務器端接收請求後進行處理並返回結果給客戶端,客戶端瀏覽器將信息呈現。這種機制對於信息變化不是特別頻繁的應用可以良好支撐,但對於實時要求高、海量併發的應用來說顯得捉襟見肘,尤其在當前業界移動互聯網蓬勃發展的趨勢下,高併發與用戶實時響應是Web應用經常面臨的問題,比如金融證券的實時信息、Web導航應用中的地理位置獲取、社交網絡的實時消息推送等.

傳統的請求-響應模式的Web開發在處理此類業務場景時,通常採用實時通訊方案。比如常見的輪詢方案,其原理簡單易懂,就是客戶端以一定的時間間隔頻繁請求的方式向服務器發送請求,來保持客戶端和服務器端的數據同步。其問題也很明顯:當客戶端以固定頻率向服務器端發送請求時,服務器端的數據可能並沒有更新,帶來很多無謂請求,浪費帶寬,效率低下。

基於Flash,AdobeFlash通過自己的Socket實現完成數據交換,再利用Flash暴露出相應的接口給JavaScript調用,從而達到實時傳輸目的。此方式比輪詢要高效,且因爲Flash安裝率高,應用場景廣泛。然而,移動互聯網終端上Flash的支持並不好:IOS系統中無法支持Flash,Android雖然支持Flash但實際的使用效果差強人意,且對移動設備的硬件配置要求較高。2012年Adobe官方宣佈不再支持Android4.1+系統,宣告了Flash在移動終端上的死亡。

傳統的Web模式在處理高併發及實時性需求的時候,會遇到難以逾越的瓶頸,需要一種高效節能的雙向通信機制來保證數據的實時傳輸。在此背景下,基於HTML5規範的、有Web TCP之稱的 WebSocket應運而生。早期HTML5並沒有形成業界統一的規範,各個瀏覽器和應用服務器廠商有着各異的類似實現,如IBM的MQTT、Comet開源框架等。直到2014年,HTML5終於塵埃落地,正式落實爲實際標準規範,各個應用服務器及瀏覽器廠商逐步開始統一,在 JavaEE7中也實現了WebSocket協議。至此無論是客戶端還是服務端的WebSocket都已完備。用戶可以查閱HTML5規範,熟悉新的HTML協議規範及WebSocket支持

WebSocket協議,能更好的節省服務器資源和帶寬,並且能夠更實時地進行通訊。

 

WebSocket 有什麼優點


開銷少、時時性高、二進制支持完善、支持擴展、壓縮更優。

  • 較少的控制開銷。在連接創建後,服務器和客戶端之間交換數據時,用於協議控制的數據包頭部相對較小。在不包含擴展的情況下,對於服務器到客戶端的內容,此頭部大小隻有2至10字節(和數據包長度有關);對於客戶端到服務器的內容,此頭部還需要加上額外的4字節的掩碼。相對於HTTP請求每次都要攜帶完整的頭部,此項開銷顯著減少了。
  • 更強的實時性。由於協議是全雙工的,所以服務器可以隨時主動給客戶端下發數據。相對於HTTP請求需要等待客戶端發起請求服務端才能響應,延遲明顯更少;即使是和Comet等類似的長輪詢比較,其也能在短時間內更多次地傳遞數據。
  • 保持連接狀態。與HTTP不同的是,Websocket需要先創建連接,這就使得其成爲一種有* 狀態的協議,之後通信時可以省略部分狀態信息。而HTTP請求可能需要在每個請求都攜帶狀態信息(如身份認證等)。
  • 更好的二進制支持。Websocket定義了二進制幀,相對HTTP,可以更輕鬆地處理二進制內容。
  • 可以支持擴展。Websocket定義了擴展,用戶可以擴展協議、實現部分自定義的子協議。如部分瀏覽器支持壓縮等。
  • 更好的壓縮效果。相對於HTTP壓縮,Websocket在適當的擴展支持下,可以沿用之前內容的上下文,在傳遞類似的數據時,可以顯著地提高壓縮率。

握手是怎麼回事?


WebSocket 是獨立的、創建在 TCP 上的協議。

Websocket 通過HTTP/1.1 協議的101狀態碼進行握手。

爲了創建Websocket連接,需要通過瀏覽器發出請求,之後服務器進行迴應,這個過程通常稱爲“握手”(handshaking)。

 

WebSocket 協議規範


WebSocket 是一個通信協議,它規定了一些規範和標準。它的協議標準爲 RFC 6455,具體的協議內容可以在tools.ietf.org中查看。

協議共有 14 個部分,其中包括協議背景與介紹、握手、設計理念、術語約定、雙端要求、掩碼以及連接關閉等內容。

 

雙端交互流程


客戶端與服務端交互流程如下:客戶端 - 發起握手請求 - 服務器接到請求後返回信息 - 連接建立成功 - 消息互通

所以,要解決的第一個問題就是握手問題。

握手 - 客戶端


關於握手標準,在協議中有說明:

The opening handshake is intended to be compatible with HTTP-based
server-side software and intermediaries, so that a single port can be
used by both HTTP clients talking to that server and WebSocket
clients talking to that server. To this end, the WebSocket client's
handshake is an HTTP Upgrade request:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13


In compliance with [RFC2616], header fields in the handshake may be
sent by the client in any order, so the order in which different
header fields are received is not significant.

WebSocket 握手時使用的並不是 WebSocket 協議,而是 HTTP 協議,握手時發出的請求可以叫做升級請求。客戶端在握手階段通過:Upgrade: websocket        Connection: Upgrade  2個頭域告知服務端,要求將通信的協議轉換爲 websocket。

其中 Sec-WebSocket-Version、Sec-WebSocket-Protocol 這兩個頭域表明通信版本和協議約定,

Sec-WebSocket-Key 則作爲一個防止無端連接的保障(其實並沒有什麼保障作用,因爲 key 的值完全由客戶端控制,服務端並無驗證機制),其他幾個頭域則與 HTTP協議的作用一致。

握手 - 服務端


剛纔只是客戶端發出一個 HTTP 請求,表明想要握手,服務端需要對信息進行驗證,確認以後纔算握手成功(連接建立成功,可以雙向通信),然後服務端會給客戶端回覆:"小老弟你好,沒有內鬼,連接達成!"

服務端需要回復什麼內容呢?
Status Code: 101 Web Socket Protocol Handshake

Sec-WebSocket-Accept: T5ar3gbl3rZJcRmEmBT8vxKjdDo=

Upgrade: websocket

Connection: Upgrade

首先,服務端會給出狀態碼,

101 狀態碼錶示服務器已經理解了客戶端的請求,

並且回覆 Connection 和 Upgrade 表示已經切換成 websocket 協議。

Sec-WebSocket-Accept 則是經過服務器確認,並且加密過後的 Sec-WebSocket-Key。

這樣,客戶端與服務端就完成了握手操作,達成一致,使用 WebSocket 協議進行通信。

 

你來我往 - 數據交流


雙方握手成功並確認協議後,就可以互相發送信息了。它們的信息是如何發送的呢?難道是:

client: Hello, server boy
server: Hello, client girl


跟我們在微信和 QQ 中發信息是一樣的嗎?

雖然我們看到的信息是這樣的,但是在傳輸過程中可不是這樣子的。傳輸這部也有相應的規定:

In the WebSocket Protocol, data is transmitted using a sequence of
frames. To avoid confusing network intermediaries (such as
intercepting proxies) and for security reasons that are further
discussed in Section 10.3, a client MUST mask all frames that it
sends to the server (see Section 5.3 for further details). (Note
that masking is done whether or not the WebSocket Protocol is running
over TLS.) The server MUST close the connection upon receiving a
frame that is not masked. In this case, a server MAY send a Close
frame with a status code of 1002 (protocol error) as defined in
Section 7.4.1. A server MUST NOT mask any frames that it sends to
the client. A client MUST close a connection if it detects a masked
frame. In this case, it MAY use the status code 1002 (protocol
error) as defined in Section 7.4.1. (These rules might be relaxed in
a future specification.)

The base framing protocol defines a frame type with an opcode, a
payload length, and designated locations for "Extension data" and
"Application data", which together define the "Payload data".
Certain bits and opcodes are reserved for future expansion of the
protocol.

協議中規定傳輸時並不是直接使用 unicode 編碼進行傳輸,而是使用幀(frame),數據幀協議定義了帶有操作碼的幀類型,有效載荷長度,以及“擴展數據”和的指定位置應用程序數據”,它們共同定義“有效載荷數據”。某些位和操作碼保留用於將來的擴展協議

 

websocket協議報文頭格式:

幀由以下幾部分組成:
FIN、RSV1、RSV2、RSV3、opcode、MASK、Payload length、Masking-key、Payload-Data。

它們的含義和作用如下:

1.FIN: 佔 1bit

0:不是消息的最後一個分片
1:是消息的最後一個分片


2.RSV1, RSV2, RSV3:各佔 1bit

一般情況下全爲 0。當客戶端、服務端協商採用 WebSocket 擴展時,這三個標誌位可以非 0,且值的含義由擴展進行定義。如果出現非零的值,且並沒有採用 WebSocket 擴展,連接出錯。

3.Opcode: 4bit

%x0:表示一個延續幀。當 Opcode 爲 0 時,表示本次數據傳輸採用了數據分片,當前收到的數據幀爲其中一個數據分片;
 
%x1:表示這是一個文本幀(text frame);
 
%x2:表示這是一個二進制幀(binary frame);
 
%x3-7:保留的操作代碼,用於後續定義的非控制幀;
 
%x8:表示連接斷開;
 
%x9:表示這是一個心跳請求(ping);
 
%xA:表示這是一個心跳響應(pong);
 
%xB-F:保留的操作代碼,用於後續定義的控制幀。


4.Mask: 1bit

表示是否要對數據載荷進行掩碼異或操作。

0:否
1:是


5.Payload length: 7bit or (7 + 16)bit or (7 + 64)bit

表示數據載荷的長度。

0~126:數據的長度等於該值;
 
126:後續 2 個字節代表一個 16 位的無符號整數,該無符號整數的值爲數據的長度;
 
127:後續 8 個字節代表一個 64 位的無符號整數(最高位爲 0),該無符號整數的值爲數據的長度。


6.Masking-key: 0 or 4bytes

當 Mask 爲 1,則攜帶了 4 字節的 Masking-key;
 
當 Mask 爲 0,則沒有 Masking-key。
 
掩碼算法:按位做循環異或運算,先對該位的索引取模來獲得 Masking-key 中對應的值 x,然後對該位與 x 做異或,從而得到真實的 byte 數據。

注意:掩碼的作用並不是爲了防止數據泄密,而是爲了防止早期版本的協議中存在的代理緩存污染攻擊(proxy cache poisoning attacks)等問題。

7.Payload Data: 載荷數據

雙端接收到數幀之後,就可以根據數據幀各個位置的值進行處理或信息提取。
 

掩碼


這裏要注意的是從客戶端向服務端發送數據時,需要對數據進行掩碼操作;

從服務端向客戶端發送數據時,不需要對數據進行掩碼操作。如果服務端接收到的數據沒有進行過掩碼操作,服務端需要斷開連接。如果Mask是1,那麼在Masking-key中會定義一個掩碼鍵(masking key),並用這個掩碼鍵來對數據載荷進行反掩碼。所有客戶端發送到服務端的數據幀,Mask都是1。

保持連接


剛纔提到 WebSocket 協議是雙向通信的,那麼一旦連接上,就不會斷開了嗎?

事實上確實是這樣,但是服務端不可能讓所有的連接都一直保持,所以服務端通常會在一個定期的時間給客戶端發送一個 ping 幀,而客戶端收到 Ping 幀後則回覆一個 Pong 幀,如果客戶端不響應,那麼服務端就會主動斷開連接。

opcode 幀爲 0x09 則代表這是一個 Ping ,爲 0x0A 則代表這是一個 Pong。
 

 

webSocket和http1.1的區別

 

  • http 只支持客戶端請求服務器響應,websocket 支持服務端請求客戶端響應。http是半雙工,websocket 是全雙工。
  • 效率問題:服務器發送信息到客戶端的時候不必再帶有head的部分信息了。與http的長鏈接通信來比,這種方式不僅能降低服務器的壓力,而且信息當中也減少了部分多餘的信息。

 

http 是基於 tcp 的,當然是雙工。
你應該理解雙工的兩種模式:半雙工(http 1.0/1.1),全雙工(http 2.0)。

半雙工:同一時間內,鏈接上只能有一方發送數據,另一方接受數據。
http 1.0 是短連接模式,每個請求都要建立新的 tcp 連接,然後 C 發送,S 響應,斷開,下一個請求重複此步驟。
http 1.1 是長連接模式,可以多路複用,建立 tcp 連接,資源1 C 發送,S響應,資源2 C發送 S響應,資源3 C發送 S響應,免去了要爲每個資源都建立一次 tcp 的開銷。

全雙工:同一時間內,兩端都可以發送或接受數據
http 2.0 資源1 C發送,不必等待 S響應就可以繼續發送 資源2 的請求,可以併發的發送,一邊發,一邊收。

 

webSocket和http2.0的區別

 

HTTP/2 是什麼

這篇文章講的比較詳細:

  • 它是 google 提出的開源協議,旨在提高網絡傳輸效率

  • 它是二進制協議

  • 它採用多路複用解決 HTTP 1.1 的 head-of-line blocking (HOL Blocking)問題(較慢的請求阻塞其它請求的問題)

  • 它通過壓縮 http 頭提高效率

  • 它支持全雙工,因此可以使用 Server Push 推送到客戶端

與 websocket 的比較

  HTTP/2 WebSocket
Headers 頭 Compressed (HPACK) 請求頭部壓縮 None 無
Binary 二進制 Yes Binary or Textual 二進制或文本都支持
Multiplexing多路複用 Yes Yes
Prioritization優先化 Yes No
Compression壓縮 Yes Yes
Direction 方向 Client/Server + Server Push (Server Push只能瀏覽器消化,不支持API,也就是代碼無法使用) Bidirectional 雙向
Full-duplex全雙工 Yes Yes

問題

  • HTTP/2 Server Push 不能被代碼使用,所以還得配合SSE(Server sent event),無論從coder還是運維的角度來看,這混搭增加了複雜度。
  • IE對http2以及SSE都支持的不好
  • HTTP/2 連接不確定性會永遠保持連接,而websocket有onclose事件,對代碼友好

    HTTP/2 Servers are encouraged to maintain open connections for as long as possible but are permitted to terminate idle connections if necessary. When either endpoint chooses to close the transport-layer TCP connection, the terminating endpoint SHOULD first send a GOAWAY (Section 6.8) frame so that both endpoints can reliably determine whether previously sent frames have been processed and gracefully complete or terminate any necessary remaining tasks.

  • 多個tab頁windows頁可能共用一個HTTP/2連接,你無法知道Server Push來自哪一個
  • 由於多路複用,以前基於HTTP 1.1的網站提速技巧Domain sharding(由於瀏覽器限制同一域名最多連接數)將不再起作用。

實際實現狀態

HTTP2 vs Websocket 顯而易見,http2 在瀏覽器服務器上限制頗多,而 websocket 基本普及。

再來看看SSE, 支持程度仍然不如websocket。

結論:

HTTP/2 完全不能替代websocket,各有各的適用場景。我個人偏好,做app還是偏向於websocket,參看我的另外一博文介紹Meteor.

 

webSocket和socket的區別

 

就像Java和JavaScript,並沒有什麼太大的關係,但又不能說完全沒關係。可以這麼說:

命名方面,Socket是一個深入人心的概念,WebSocket借用了這一概念;
使用方面,完全兩個東西。
總之,可以把WebSocket想象成HTTP,HTTP和Socket什麼關係,WebSocket和Socket就是什麼關係。

 

websocket 原理

http 短連接客戶端請求服務器端的時候,客戶端會啓動一個端口來和服務器交互,服務器響應之後,端口就釋放了。

http 長連接客戶端請求服務器端的時候,客戶端每次會啓動一個新端口來和服務器交互,服務器響應之後,端口就釋放了。

websocket客戶端請求服務器的時候,客戶端會啓動一個端口來和服務器交互,服務器響應之後,端口不釋放。並且可以監聽服務器的請求。

WebSocket模式客戶端與服務器請求響應模式如下圖

這裏寫圖片描述

上圖對比可以看出,相對於傳統HTTP每次請求-應答都需要客戶端與服務端建立連接的模式,WebSocket是類似Socket的TCP長連接通訊模式。一旦WebSocket連接建立後,後續數據都以幀序列的形式傳輸。在客戶端斷開WebSocket連接或Server端中斷連接前,不需要客戶端和服務端重新發起連接請求。在海量併發及客戶端與服務器交互負載流量大的情況下,極大的節省了網絡帶寬資源的消耗,有明顯的性能優勢,且客戶端發送和接受消息是在同一個持久連接上發起,實時性優勢明顯。

相比HTTP長連接,WebSocket有以下特點:

  • 是真正的全雙工方式,建立連接後客戶端與服務器端是完全平等的,可以互相主動請求。而HTTP長連接基於HTTP,是傳統的客戶端對服務器發起請求的模式。
  • HTTP長連接中,每次數據交換除了真正的數據部分外,服務器和客戶端還要大量交換HTTP header,信息交換效率很低。Websocket協議通過第一個request建立了TCP連接之後,之後交換的數據都不需要發送 HTTP header就能交換數據,這顯然和原有的HTTP協議有區別所以它需要對服務器和客戶端都進行升級才能實現(主流瀏覽器都已支持HTML5)。此外還有 multiplexing、不同的URL可以複用同一個WebSocket連接等功能。這些都是HTTP長連接不能做到的。

下面再通過客戶端和服務端交互的報文對比WebSocket通訊與傳統HTTP的不同點:

在客戶端,new WebSocket實例化一個新的WebSocket客戶端對象,請求類似 ws://yourdomain:port/path 的服務端WebSocket URL,客戶端WebSocket對象會自動解析並識別爲WebSocket請求,並連接服務端端口,執行雙方握手過程,客戶端發送數據格式類似:

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: http://localhost:8080
Sec-WebSocket-Version: 13

可以看到,客戶端發起的WebSocket連接報文類似傳統HTTP報文,Upgrade:websocket參數值表明這是WebSocket類型請求,Sec-WebSocket-Key是WebSocket客戶端發送的一個 base64編碼的密文,要求服務端必須返回一個對應加密的Sec-WebSocket-Accept應答,否則客戶端會拋出Error during WebSocket handshake錯誤,並關閉連接。

服務端收到報文後返回的數據格式類似:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

Sec-WebSocket-Accept的值是服務端採用與客戶端一致的密鑰計算出來後返回客戶端的,HTTP/1.1 101 Switching Protocols表示服務端接受WebSocket協議的客戶端連接,經過這樣的請求-響應處理後,兩端的WebSocket連接握手成功, 後續就可以進行TCP通訊了。用戶可以查閱WebSocket協議棧瞭解WebSocket客戶端和服務端更詳細的交互數據格式。

在開發方面,WebSocket API 也十分簡單:只需要實例化 WebSocket,創建連接,然後服務端和客戶端就可以相互發送和響應消息。在WebSocket 實現及案例分析部分可以看到詳細的 WebSocket API 及代碼實現

 

 

 

websocket  不同協議實現之間的區別

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協議的控制層的直接傳輸,具體沒有做過驗證實現;不想重新搞的小夥伴直接按照上述的思路和角色開發,肯定是沒毛病的;    祝各位寶寶春夢了無痕;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了515 篇原創文章 · 獲贊 142 · 訪問量 100萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章