WebSocket的調研分析

Frankiehp發表於2020-12-16
  1. 簡介
    本文件編寫目的,是為了在現有會控服務http信令的基礎上,為長連線功能的加入提供一個探索和初步設計思路。
  2. WebSocket & Tcp Socket
    2.1 WebSocket介紹
    概述:
    WebSocket同HTTP一樣也是應用層的協議,但是它是一種雙向通訊協議,是建立在TCP之上的。WebSocket在建立握手時,資料是通過HTTP/1.1(注HTTP1.1相比HTTP增加了KeepAlive)傳輸的,準確的將是使用了HTTP Upgrade來將協議更改為websocket,但是建立之後,在真正傳輸時候是不需要HTTP協議的。

由來:
HTTP 協議做不到伺服器主動向客戶端推送資訊。這種單向請求的特點,註定瞭如果伺服器有連續的狀態變化,客戶端要獲知就非常麻煩。我們只能使用"輪詢":每隔一段時候,就發出一個詢問,瞭解伺服器有沒有新的資訊。輪詢的效率低,非常浪費資源(因為必須不停連線,或者 HTTP 連線始終開啟)。因此,工程師們一直在思考,有沒有更好的方法。WebSocket 就是這樣發明的。

補充:
Websocket 協議使用80或者443(執行在TSL之上)
WebSocket通過HTTP1.1協議的101狀態碼進行握手。

握手例項:
在這裡插入圖片描述
在這裡插入圖片描述

欄位說明:
Connection: 客戶端必須設定為Upgrade,表示希望升級協議
Upgrade: 表示希望升級哪個協議
Sec-Websocket-Key:是隨機字串,伺服器端會用這個資料造出一個SHA-1的資訊摘要。把Sec-Websocket-Key加上一個特殊字串,然後進行計算SHA-1摘要,之後進行base64編碼,結果在Sec-Websocket-Accept中返回。

握手完成後的資料包文:
在這裡插入圖片描述

FIN(1bit): 表示資訊是否結束, 如果為1則該訊息為訊息尾部,如果為零則還有後續資料包; 

RSV 1-3(1bit):備用欄位 預設都為 0
Opcode(4bit):訊息型別,訊息型別暫定有15種,其中有幾種是預留設定。
Mask (1bit): 掩碼,是否加密資料,(客戶端傳送給後端時,mask必須為1,否則close連線;伺服器傳送給前端時,mask必須為0,否則斷開連線)
Payload len(7bit): 資料的長度,當這個7 bit的資料 == 126 時,後面的2 個位元組表示資料長度,當它 == 127 時,後面的 8 個位元組表示資料長度
Masking-key(0/32bit): 掩碼值( Mask為1時才有)
Payload data 長度為Payload len的資料,如果有掩碼 需要用mask-Key來異或 才能得到

圖例說明:

在這裡插入圖片描述

優點:
1較少的開銷控制,伺服器和客戶端之間交換資料時,用於控制協議的的頭部相對較小(相比HTTP)
2相比長輪詢更強的實時性,短時間內可以傳遞更多的資料
3保持狀態連線,相比HTTP不用每次都帶狀態資訊,如身份認證

不足:
Websocket在同步接收大量資料時會阻塞。

2.2 Tcp Socket介紹
套接字(socket):應用層通過傳輸層進行資料通訊時,TCP和UDP會遇到同時會多個應用程式程式提供併發服務的問題。區分不同的應用程式程式間的網路通訊和連線,主要有三個引數:通訊的目標IP地址、使用的傳輸層協議(TCP或UDP)、目標埠號,這種組合稱為套接字。
套接字之間的連線分為三個步驟:伺服器監聽、客戶端請求、連線確認。

2.3差別
從上面的介紹,可以很清楚的看出,websocket協議基於的是HTTP1.1的一套協議,傳輸的內容是面向訊息傳輸的,而socket是基於TCP的應用,其面向的位元組傳輸的。對於socket的接收方會出現tcp的粘包,拆包和丟包的情況,而websocket則不會,websocket的協議保障了每次收到的訊息都是傳送放每一次收到的完整的訊息。
Socket的可靠性是基於TCP的協議來保障的,相比websocket是心跳檢測和重連機制以及TCP來保障的。所以websocket的可靠性更好。
同時 由於socket是直接對TCP的封裝,而websocket是基於HTTP協議的,所以socket傳輸效能更高,但是要自己定義一套規則。
下面文章是一個人對websocket和tcp socket的一個簡單效能測試,效能上可以肯定是socket優於websocket,但是不帶websocket的效能舊很差。
https://medium.com/kifi-engineering/websockets-vs-regular-sockets-b3b8e7ea0708

2.4使用建議
如果目前的websocket的效能足夠滿足我們對於未來一段時間內的開發需求,那麼建議不要自己再造一個輪子,避免引入不必要的錯誤。

  1. Websocket效能分析
    3.1當前可以使用的庫(c語言)
    LibHTTP:(MIT)
    LibHTTP is an MIT licensed library written in C implementing a HTTP/HTTPS server with websocket capabilities. The library also includes functionality for client connections to other servers.
    https://www.libhttp.org/
    https://github.com/lammertb/libhttp

Libwebsockets:(MIT)
Libwebsockets (LWS) is a flexible, lightweight pure C library for implementing modern network protocols easily with a tiny footprint, using a nonblocking event loop. It has been developed continuously since 2010 and is used in tens of millions of devices and by thousands of developers around the world.
https://libwebsockets.org/

noPoll:
noPoll is a OpenSource WebSocket implementation (RFC 6455), written in ansi C, that allows building pure WebSocket solutions or to provide WebSocket support to existing TCP oriented applications.
noPoll provides support for WebSocket (ws://) and TLS (secure) WebSocket (wss://), allowing message based (handler notified) programming or stream oriented access.
noPoll was written to have a clean and easy to use library.
http://www.aspl.es/nopoll/index.html
https://github.com/ASPLes/nopoll

這三個庫中前兩兩個是完全開源的,第三個是西班牙一個公司的開源庫,都有人再用。前兩個從更新速度上來講,libwebsocket要由於libHTTP。其他的關於C的websockt,實在是不多。

關於socket的一些封裝庫:https://blog.csdn.net/u014162133/article/details/88578114

3.2其他人分析結果借鑑
此處將引用網上現有的一些效能分析報告來說明websocket的吞吐量,實際生產中需要進一步測試。
文章介紹了現有的幾種非c語言框架對websocket的幾種框架的測試,根據他的結果應該是可以滿足我們目前的需求,關於使用c相關的庫,可能還需要進行進一步測試來對效能進行評估,但相比現行的http長輪詢,效能一定會有所提升。

https://blog.csdn.net/zl1zl2zl3/article/details/84780413

https://medium.com/kifi-engineering/websockets-vs-regular-sockets-b3b8e7ea0708

相關文章