Boost Beast要點解析(四)

2021-10-08 01:15:30 字數 3432 閱讀 2247

由於http、websocket僅涉及tcp,因此在beast範圍內,也僅涉及tcp協議,beast的網路操作基於asio,但beast的乙個目標似乎是做乙個完整的系統(猜測),因此beast將涉及到的網路資料操作都「重寫」的一遍(一些是簡單包裝,一些是擴充套件),例如asio空間被重新命名為net,對std:bind也擴充套件為bind_handler

和bind_front_handler

template< class protocol, class executor = net::executor,class ratepolicy = unlimited_rate_policy>

class basic_stream

using tcp_stream = basic_stream< net::ip::tcp, net::executor, unlimited_rate_policy >;

從實現上看,beast並沒有利用asio中的streambuf,而是採用其中的概念,與buffer類結合,重新寫了一大套接收/傳送操作,與asio中類似。

在實現websocket時,beast作者試圖體現網路分層的概念,採用get_lowest_layer(),get_next_layer()來獲得更下層的實現類,websocket中的stream定義如下:

template<

class nextlayer,

bool deflatesupported>

class stream

其中deflatesupported是websocket協議擴充套件,表示是否支援報文壓縮,如果定義乙個ws流:

websocket::stream<

boost::beast::tcp_stream > ws(ioc);

則上面那個ws的next layer就是boost::beast::tcp_stream。

同樣,beast重新寫了一大套接收/傳送操作。

實際上,在basic_stream的實現**中也可看到類似layer的身影,但並沒有在文件**現,猜測作者認為還不成熟,暫且在websocket中實驗,估計在以後的版本中,網路分層的概念的會被強化。

bind_handler沒有當內建handler是成員函式時的情況,其他與std:bind似乎沒有什麼區別。

bind_front_handler功能基本同std:bind,所不同的是handler引數的寫法,這裡不能使用std::placeholders

,handler函式所有原來需要std::placeholders的引數只能設計在後面(還是看下面的例子吧,注意兩種方式寫法的不同)。bind_front_handler顯得簡潔一些。

class aa

void trigger(std::functionh)

void run()

};

asio中基本的socket並沒有附帶超時操作(iostream有),但實際的網路操作都不可避免的要設定超時,因此beast在其網路資料流基類basic_stream中提供了超時設定功能:expires_after,expires_at以及expires_never,對於客戶端,顯得十分方便,但對於伺服器,如果有很多連線,設定如此多的定時器,必然會增加機器的負擔,使用時應該權衡。

在beast實現**中,設定了讀和寫兩個定時器,其本意大概是可設定讀超時和寫超時,但卻沒有分開設定的介面,現在使用的方式是在操作之前設定,如在讀操作前設定一次超時,對讀操作有效,在寫操作之前設定一次超時,對寫操作有效。

websocket api比較少,感覺作者的重心不在此處。

websocket通訊是由http通訊「upgrade」而來,因此websocket通訊的第一步依然是構造乙個http request parser,parser檢查到需要upgrade到websocket協議後,構造websocket流,它的定義如下:

websocket::stream< boost::beast::tcp_stream > ws(ioc);
然後,ws接受連線(accept),通過ws接收和傳送資料。

websocket讀寫沒有相應的request/response類,因此與一般的tcp流使用類似,自己寫解析與應答。

websocket採用set_option來進行設定,乙個通常的設定是超時(作者建議採用這種方法,而不用更下層的方法,並且在構造之前需要disable下層設定的超時)。websocke有三個超時:握手時超時,正常通訊時超時,當達到正常通訊時超時半數時是否傳送ping資訊而保持連線。以下是乙個示例(先disable掉tcpstream的超時似乎有點不簡潔)。

tcpstream.expires_never();

websocket::stream< boost::beast::tcp_stream > ws(std::move(tcpstream));

stream_base::timeout opt;

ws.set_option(opt);

1.  beast運用了boost的很多東西,很好地運用了template的特性,但使得學習成本高,看乙個東西牽扯其他很多東西,對庫的開發者來說,這不是問題,但對普通應用者來說,就是大問題。

2. 作為偏向協議解析的庫,beast涉及很多網路操作,反而顯得與協議解析部分繫結的較緊,例如,

read(stream, buffer, request);
這樣的功能感覺上分兩步更靈活:read stream into buffer和 parse buffer into request,其中第一步由asio或其他別的網路庫來完成(以目前的實現,如果不採用asio,真不知如何)。beast中提供的api,涉及網路及相關的操作不算少數,並且提出了next layer, decorator等概念,目標比較巨集大,但卻有點偏離協議解析這個最基本的目標。實際的應用中,離不開諸如url encode,querystring parsing等功能,做web伺服器應用時,還需要url routing,這些實用的功能,beast反而沒有提供,所以有時會迷惑,beast到底定位成什麼庫呢。

3.    tcp資料就是流式資料,無論request還是response都是char序列(流),如果細分,還可以是text流或binary流,接收和傳送由網路庫負責,接收到時,由request解除安裝;傳送前由response裝載,負荷是其他具體型別類(與協議對應)的deserialization /serialization,以上是通常的思路,beast將型別確定提前了,由型別類才能構造出request/response,這種思路是否更好,見仁見智吧,但使用beas寫**時,應該適應這種思路。

4.    beast提供了協議解析的一些新思路,形式的優美與執行的高效之間如何平衡,作為庫作者,一般是強調前者,作為專案的作者,則一般強調後者。希望beast能找到乙個相容的方案。

5.    asio已發展了若干版本,從每次boost版本的更新文件中,都可以看到asio每次不斷的努力,beast定位比較巨集大,感覺還有很長的路走。

Boost Beast要點解析(三)

在beast文件中,專門解釋了是如何構思http request和response類的。request和response的定義如下 templateclass message public header,boost empty value以上的定義與文件中稍有不同,來自於源 文件中說message是...

HTML CSS章節要點解析

1.html中定義 的寬度用80px和80 的區別是px標識畫素,標識整個頁面的寬度百分比 2.css樣式定義優先順序順序 內聯樣式最高優先權,然後是內部樣式,然後才是外部樣式3.div 和 span 元素最大的特點是預設都沒有對元素內的物件進行任何格式化渲染。主要用於應用樣式表 共同點 兩者最明顯...

感測器的設計要點解析

好的感測器 的設計是經驗加技術的結晶。一般理解感測器是將一種物理量經過 電路轉換成一種能以另外一種直觀的可表達的物理量的描述。而下文我們將對感測器的概念 原理特性進行逐一介紹,進而解析感測器的設計的要點。1 感測器的概念 感測器是一種檢測裝置,能感受到被測量的資訊,並能將感受到的資訊,按一定規律變換...