C/S框架 st_asio_wrapper 開發教程——宏(2019.10.17更新)

1.全局宏,服務端客戶端均需要:

ST_ASIO_USE_STEADY_TIMER 定時器採用boost::asio::steady_timer來實現。
ST_ASIO_USE_SYSTEM_TIMER 定時器採用boost::asio::system_timer來實現,否則將採用boost::asio::deadline_timer來實現。

ST_ASIO_MAX_SEND_BUF

ST_ASIO_MAX_RECV_BUF

每個socket消息緩存最大字節數(接收和發送緩存共用,所以總的最大數爲兩倍),默認1M。注意這個緩存不會像ST_ASIO_MSG_BUFFER_SIZE一樣預分配,而是用到多少分配多少。
ST_ASIO_ENHANCED_STABILITY 增強的健壯性,如果開啓這個宏,所有service對象都會在最外層(io_service::run)包一層try catch,以增加健壯性(當然,增加try  catch 是會有效率損失的),當捕捉到異常的時候,會回調on_exception虛函數,用戶通過該函數的返回值來控制是否繼續調用io_service::run。
ST_ASIO_PASSIVE_RECV  不主動接收消息,用戶需要顯示調用recv_msg來發起異步數據讀取,如果你想在運行時替換解包器,必須定義該宏,且保證在調用recv_msg之前把解包器替換掉,否則會有race condition。
ST_ASIO_WANT_MSG_SEND_NOTIFY 每次消息發送成功之後(成功送到本地SOCKET緩存),回調on_msg_send虛函數。
ST_ASIO_WANT_ALL_MSG_SEND_NOTIFY 當發送緩存發空了之後,回調on_all_msg_send虛函數。
ST_ASIO_UNIFIED_OUT_BUF_NUM 輸出日誌時用的緩存大小,注意是在棧上分配,注意棧溢出問題,如果你自定義了日誌輸出,該宏顯然無意義。
ST_ASIO_NO_UNIFIED_OUT 讓st_asio_wrapper裏面的所有輸出失效。
ST_ASIO_CUSTOM_LOG 自定義輸出,此時你需要提供5個日誌函數,函數名和簽名參看unified_out類,且要麼是靜態的,要麼是全局的。
ST_ASIO_FULL_STATISTIC 詳細的統計信息,包括時間消耗,如果不定義,所有時間消耗項都被不統計。統計的內容有請參看socket::statistic類的定義。
ST_ASIO_SERVICE_THREAD_NUM IO線程數量,用於運行io_service.run函數,所有回調函數(以on_開頭的虛函數)都將會在這些線程中的某一箇中被回調。
ST_ASIO_MAX_OBJECT_NUM 對象池最多支持的對象數量,默認4096。
ST_ASIO_REUSE_OBJECT 是否開啓對象池,如果開啓,當創建新對象時,將嘗試使用已經被關閉的對象,此時將不會自動定時的釋放被關閉的對象鏈表,請參看ST_ASIO_FREE_OBJECT_INTERVAL宏,默認不開啓本宏。
ST_ASIO_FREE_OBJECT_INTERVAL 說這個宏之前,要說一下object_pool的內部工作原理:當調用del_socket的時候(server_socket_base在on_recv_error裏面的默認行爲),object_pool的作法並不是刪除這個對象,而是把這個對象移動到另外一個鏈表裏面,這個鏈表裏面的對象會被每ST_ASIO_FREE_OBJECT_INTERVAL秒遍歷一次,以找到已經真正關閉了的對象(所謂真正關閉,就是已經被close了,而不僅僅是被shutdown了的對象,且沒有任何未完成的異步調用),然後真正的從內存中釋放它,原因是當del_socket的時候,可能還有其它的異步操作還沒完成,或者完成了,但還在隊列中沒有被分發,如果此時從內存中釋放對象,那麼後面的異步回調的時候,可能會出現內存訪問越界。如果未定義ST_ASIO_REUSE_OBJECT宏,ST_ASIO_FREE_OBJECT_INTERVAL宏會被自動定義(如果未顯示定義的話)。單位爲秒,默認10秒。
ST_ASIO_CLEAR_OBJECT_INTERVAL 定時循環調用clear_obsoleted_object()以清除失效對象(移動到另外一個鏈表裏面),如果在連接斷開時你不方便調用del_socket,則對象池裏面將會累積越來越多的失效對象(如果有連接出錯,或者退出的話),你可以打開這個宏,讓object_pool爲你定時的做這些清除工作;注意,如果對象鏈表非常大,遍歷鏈表是會影響效率的,如果你的連接是短連接,推薦開啓這個功能(那你就不要再任何地方調用del_socket了),這樣一次可清除多條連接,否則不推薦。單位爲秒,該宏默認不開啓。
ST_ASIO_DELAY_CLOSE 關閉連接(shutdown)多少秒鐘之後,可以安全釋放對象或者重用對象(取決於ST_ASIO_REUSE_OBJECT是否被定義,定義了就是重用,否則釋放)。如果定義爲0,則st_asio_wrapper庫將始終保證在沒有任何異步調用之後才釋放或者重用對象(會對效率造成一點點影響)。
ST_ASIO_GRACEFUL_SHUTDOWN_MAX_DURATION 優雅關閉時,最長等待時間,單位爲秒,默認5。
ST_ASIO_INPUT_QUEUE 指定輸入隊列(send_msg用到的隊列),目前有帶鎖和不帶鎖(線程不安全,所以需要你的業務保證線程的安全性)兩種隊列。
ST_ASIO_INPUT_CONTAINER 指定輸入隊列所使用的容器,比如list、deque等,也可以是你自己的容器,只要提供必要的接口。
ST_ASIO_OUTPUT_QUEUE 指定輸出隊列,目前有帶鎖和不帶鎖(線程不安全,所以需要你的業務保證線程的安全性)兩種隊列。
ST_ASIO_OUTPUT_CONTAINER 指定輸出隊列所使用的容器,比如list、deque等,也可以是你自己的容器,只要提供必要的接口。
ST_ASIO_RECV_BUFFER_TYPE 接收緩存的類型,比如它可以是boost::asio::mutable_buffers_1,或者std::vector<boost::asio::mutable_buffers_1>等,可以爲所有asio支持的緩存類型。對於具體使用場合我舉個例子,比如你正在使用ring buffer,那麼一次你可能會提供兩塊非連續的緩存,那這個宏就能派上用場了。
ST_ASIO_HEARTBEAT_INTERVAL 檢測心跳包的頻率,單位爲秒,檢測之前先檢測連接有效性,如果心跳包超時,將斷開連接(UDP不會)並回調on_heartbeat_error()函數,否則將發送一個心跳包。注意:如果從現在開始往前推ST_ASIO_HEARTBEAT_INTERVAL,在這個範圍之內有消息被髮送(接收的不算),則不會發送心跳包。
ST_ASIO_HEARTBEAT_MAX_ABSENCE 如果判斷心跳包超時,單位爲次數,如果心跳包檢測頻度爲5秒,這個值爲3,則15秒後認爲心跳包超時。
ST_ASIO_REUSE_SSL_STREAM 讓ssl支持重用和重連。如果ST_ASIO_REUSE_OBJECT被定義,而ST_ASIO_REUSE_SSL_STREAM沒有,則編譯任何ssl對象時,將報錯。
ST_ASIO_AVOID_AUTO_STOP_SERVICE 用asio::io_service::work (asio::executor_work_guard)包裝io_service以絕對的防止service自動退出(除非是stop_service或者end_service)。
ST_ASIO_DECREASE_THREAD_AT_RUNTIME 支持運行時增減service線程。
ST_ASIO_EXPOSE_SEND_INTERFACE 暴露send_msg接口。


2.tcp客戶端專用宏:

ST_ASIO_SERVER_IP 服務器IP地址,用字符串形式表示,默認"127.0.0.1"
ST_ASIO_SERVER_PORT 服務器端口,默認5050。
ST_ASIO_RECONNECT_INTERVAL 當連接服務器失敗時,延時多長時間重連,負數表示不重連,單位是毫秒,默認500毫秒。


3.tcp服務端專用宏:

ST_ASIO_SERVER_PORT 服務器端口(服務器IP如果要設置的話,只能調用set_server_addr接口,不能通過宏來實現),默認5050。
ST_ASIO_TCP_DEFAULT_IP_VERSION 在不指定服務端IP時,通過這個宏指定IP協議的版本(v4還是v6,取值分別是boost::asio::ip::tcp::v4()和boost::asio::ip::tcp::v6()),如果指定了IP,則版本從IP地址中分析得來。
ST_ASIO_ASYNC_ACCEPT_NUM 最多同時投遞多少個異步accept調用,默認1。
ST_ASIO_NOT_REUSE_ADDRESS 關閉端口重用,udp也用使用此宏


4.udp客戶端專用宏:

ST_ASIO_UDP_DEFAULT_IP_VERSION 在不指定IP時,通過這個宏指定IP協議的版本(v4還是v6,取值分別是boost::asio::ip::udp::v4()和boost::asio::ip::udp::v6()),如果指定了IP,則版本從IP地址中分析得來。


5.打包解包器專用宏(不屬於st_asio_wrapper庫):

ST_ASIO_MSG_BUFFER_SIZE 用於解包的緩存大小,默認4000。它應該大於等於最長的消息包(打包後),拿默認的packer來說,它最大僅支持3998消息長度,因爲還有一個2字節的包頭。對於默認打包解包器,這個值的範圍只能是1至65536,因爲包頭只用了兩個字節來表達長度,如果想要超過這個限制,可定義HUGE_MSG宏。這個緩存越大,那麼一次可接收的消息越多(如果SOCKET的緩存裏面有數據的話),但不是越大越好,因爲每一個解包器裏面都有一個大小固定爲MSG_BUFFER_SIZE的緩存(不管你用到了多少),而每一個tcp::socket_base都會有一個解包器(udp::socket_base類似),所以這個值越大,佔用的內存也就越大。當然,如果你自定義了打包解包器,那上面等於沒說,怎麼控制內存分配由你說了算。
ST_ASIO_DEFAULT_PACKER 自定義打包器,它是一個類名,必須提供默認構造函數(即沒有參數的構造函數)。
ST_ASIO_DEFAULT_UNPACKER 自定義解包器,它是一個類名,必須提供默認構造函數(即沒有參數的構造函數)。
ST_ASIO_HUGE_MSG 開啓大消息支持,默認關閉。注意,大消息會佔用更多內存,請看asio_client這個demo,裏面有演示用法(註釋狀態),以及對於佔用更多內存的解釋。
ST_ASIO_HEAD_TYPE 消息頭數據類型,不可設置,如果定義了ST_ASIO_HUGE_MSG,則爲uint32_t,否則爲uint16_t。
ST_ASIO_HEAD_N2H 網絡序轉主機序,不可設置,如果定義了ST_ASIO_HUGE_MSG,則爲ntohl,否則爲ntohs。
ST_ASIO_HEAD_N2H 主機序轉網絡序,不可設置,如果定義了ST_ASIO_HUGE_MSG,則爲htonl,否則爲htons。
ST_ASIO_SCATTERED_RECV_BUFFER 在接收數據時是否支持scattered緩存(parse_msg之前用的緩存),如果你正在使用ring buffer,你可能會一次提供兩塊不連續的緩存,此時這個宏就有用了。


以上宏都可以按工程爲單位來修改,你只需要在include相應st_asio_wrapper相關頭文件之前定義這些宏即可(但推薦定義在工程屬性裏面,以完全杜絕不同的cpp文件拿到不同的宏定義的情況),具體例子demo裏面都有。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章