Websocket需要像TCP Socket那樣進行邏輯數據包的分包與合包嗎?
換句話說,WebSocket的協議標準中處理了以前TCP Socket可能會發生的「粘包」(sticky)與「半包」(half a pack)問題嗎?
RFC6455中規定了,WebSocket協議的數據幀是有FIN-bit的。也就是說是有消息邊界的,是否對這個問題有影響?https://tools.ietf.org/html/rfc6455
經過一段時間的調研,題主來自問自答了。。
RFC規範指出,WebSocket是一個message-based的協議,它可以自動將數據分片,並且自動將分片的數據組裝。
也就是說,WebSocket的RFC標準是不會產生粘包、半包問題的。無需應用層開發人員關心緩存以及手工組裝message。
然而理想與現實的不一致:RFC規範與實現的不一致,現實當中有幾個問題:
1. 每個message可以是一個或多個分片。message不記錄長度,分片才記錄長度。
2. message最大的長度可以達到 9,223,372,036,854,775,807 位元組,是由於Payload的數據長度有63bit的限制。
3. 很多WebSocket的實現其實並不按照標準的RFC實現完全,很多僅僅實現了50%就拿來用了。
這就導致了,在WebSocket實現上的最大長度很難達到這個大小,於是,很多API的實現上是會有限制的,可能會限制你的發送的長度,也可能會把過長的數據直接以流式發送。
結論
WebSocket的RFC標準是不會產生粘包、半包問題的,但是由於現實世界的WebSocket的實現者不同程度的偷懶,不同程度的會有這個問題,特別是當你的數據message特別大的時候(到底是多大是特別大,由具體實現決定)。
儘可能的選擇一個符合自己項目的WebSocket實現,或者自己造一個滿足需要的輪子。
也或者,把WebSocket看做一個有特別大的長度限制「流」協議,然後自己處理buffering的問題。
https://en.wikipedia.org/wiki/WebSocket
https://tools.ietf.org/html/rfc6455
http://www.lenholgate.com/blog/2011/07/websockets-is-a-stream-not-a-message-based-protocol.html
http://lucumr.pocoo.org/2012/9/24/websockets-101/
http://stackoverflow.com/questions/21024173/is-websocket-a-stream-based-or-package-based-protocol
一個Frame會被拆分成幾個數據包,或一個數據包包含幾個Frame,一個Frame的第一個位元組在前一個Frame的數據包最後,這些和WebSocket的協議沒關係,與瀏覽器沒關係,與伺服器也沒關係,TCP有,WebSocket就不能避免,也沒法避免,因為WebSocket是基於TCP的協議。
同一個Message被拆分成幾個Frame來發送的瀏覽器都是良心瀏覽器啊,都是幾M的Frame,伺服器緩存受不了啊。
伺服器端把一個Message分成多少個Frame你都不要管它,因為瀏覽器會自動處理成一個個的message給你,那個事件介面是onmessage,不是onframe。
不用,基於message而不是streaming
測試的chrome瀏覽器,短字串,自動分包,連續發,包不會粘到一起。
對了服務端使用的是 golang,理論上,和伺服器以及客戶端實現都有關係。
在要求不嚴的場合(數據不大,不會長時間連續發送),姑且認為是不用處理分包粘包的吧。
樓主好人
一般不用去處理這種 畢竟HTTP是在應用層實現 而對它數據的一個解析應該比這更高一層 一般來說 不會發生這種分包粘包情況
沒有影響,你依然需要處理分包。
推薦閱讀: