C++跨平臺集成websocketpp

    以前給公司寫了一個用於消息交互的服務器,移植到Linux上以後發現H5-Websocket模塊常常出問題,而該模塊是另外一位已經離職同事編寫的,因此修改和維護都存在必定的困難,索性就直接把這個模塊替換掉。從搜索考察websocket的開源庫,到最終代碼編好替換掉模塊,並穩定運行總共耗時4天左右(使用第三方開源庫確實提高了很是大的開發效率,想當初那個離職同事搞了差很少一個月,還不包括後面的各類Bug修改和功能改進)html

    好了,廢話很少說,最初我在網上找到Websocket的開源庫有好幾個,但最終選擇了Websocketpp這個庫,主要是由於其不須要額外的編譯庫,也就是說不須要再去編什麼lib(Windows)、點a點o(Linux)等庫文件。如下是我具體的集成步驟:git

1. boost安裝

Websocketpp是基於boost::asio開發的一個C++協議庫,你的電腦上須要首先安裝boost::asio,我選擇的是完整安裝boost(主要怕萬一還得用到其餘庫,一次性裝完方便些)。boost版本我選擇的是1.67.0。github

1.1 boost下載

你們能夠在如下網址處,找到1.67.0的Windows和Linux下載連接。web

http://www.boost.org/users/history/version_1_67_0.htmlbootstrap

下載完畢後,就要對boost進行編譯和安裝服務器

1.2 Windows

a. 解壓縮下載好的文件,進入源碼目錄,執行bootstrap.bat批處理文件,結束後會在源碼根目錄下生成b2.exe和bjam.exe兩個文件。websocket

b. 經過命令行執行socket

bjam.exe stage --toolset=msvc-10.0 architecture=x86 address-model=64 link=static --build-type=complete --with-system --with-thread --with-date_time --with-filesystem --with-serialization \函數

--stagedir=庫文件路徑學習

參數解釋:

stage 表示僅生成庫文件,由於源碼下的boost目錄已經包含了完整的頭文件

--toolset 表示使用哪一個版本的vs編譯器來編譯boost,具體vs版本與這裏填寫的數字對應關係,請自行搜索

architecture 表示編譯時基於的處理器平臺,需按照本身的電腦真實配置填寫,但一般都是x86

address-model 表示編譯爲64位仍是32位庫

link 表示連接爲靜態庫(庫文件較大),若是填shared則表示連接爲動態庫(庫文件較小)

--build-type 表示編譯類型,填complete則是完整編譯

--stagedir 表示生成庫文件的保存路徑

c. 等待編譯結束後(大概須要幾分鐘),能夠在庫文件保存路徑下看到不少名字很長的lib文件(共享庫的話,是lib和dll),具體boost庫文件的命名規範

能夠自行搜索學習。

接下來在須要使用到Websocketpp庫的vs工程裏,把boost的頭文件目錄和庫文件目錄配置進來便可。

1.3 Linux

a. 一樣是解壓縮下載好的源碼包,進入源碼目錄,執行

./bootstrap.sh --prefix=/usr/local/boost --with-libraries=all --with-toolset=gcc

執行結束後會生成b2和bjam,上面參數中prefix表示編譯後庫文件和頭文件的安裝目錄,with-libraries表示須要編譯哪些庫(all表示全部庫),with-toolset表示使用的編譯器

這裏boost-1.67在哪些gcc版本下測試經過可運行,須要本身到官網上進行查詢。個人Linux爲CentOS6.6,gcc版本是4.9.4,若是gcc版本不符合的話,建議對gcc進行升級。下面是官網上查到的1.67.0測試經過的一些編譯器以及對應的版本

 

b. 執行 ./b2 toolset=gcc進行編譯,完了以後再執行 ./b2 install進行安裝便可。

c. boost安裝完畢後,須要將boost的頭文件目錄和庫文件目錄添加到環境變量中,頭文件是CPLUS_INCLUDE_PATH和C_INCLUDE_PATH,庫文件是LIBRARY_PATH和LD_LIBRARY_PATH,具體如何添加這裏就不贅述。不過有個地方須要注意,就是boost的頭文件目錄必定要放在系統的頭文件目錄以後,Websocketpp頭文件目錄以前,且不能將boost的頭文件目錄放到系統頭文件目錄之下,可能會致使你的程序在make時報一些對象未定義。

2. Websocketpp安裝

2.1 下載

能夠在Github上找到該項目,我下載的是master版本,若是該項目有更新那麼master對應的版本號可能會有出入。

https://github.com/zaphoyd/websocketpp

2.2 Windows

解壓縮文件後,源碼目錄中的websocketpp下就是咱們須要的全部頭文件,不須要額外的編譯,將其放到合適的位置並引入到vs的工程中便可。

2.3 Linux

解壓縮文件後,將websocketpp放到合適的位置,並添加到兩個頭文件的環境變量中,注意要放在boost的頭文件目錄以後。

3. Websocketpp使用

3.1 總體使用流程

從Websocketpp的例子中,拷貝須要用到的頭文件包含和一些類型重定義

1 #include <websocketpp/config/asio_no_tls.hpp>
2 #include <websocketpp/server.hpp>
3 using websocketpp::connection_hdl;
4 using websocketpp::lib::placeholders::_1;
5 using websocketpp::lib::placeholders::_2;
6 using websocketpp::lib::bind;
7 typedef websocketpp::server<websocketpp::config::asio> server;
8 typedef server::message_ptr message_ptr;

生成server對象

 1 server m_server; 

初始化m_server

1 m_server.set_access_channels(websocketpp::log::alevel::none); // 設置打印的日誌等級
2 
3 m_server.init_asio(); // 初始化asio
4 
5 m_server.set_open_handler(bind(&XXXClass::on_open_func_ptr, this, ::_1)); // 綁定websocket鏈接到來時的回調函數
6 m_server.set_close_handler(bind(&XXXClass::on_close_func_ptr, this, ::_1)); // 綁定websocket鏈接斷開時的回調函數
7 m_server.set_message_handler(bind(&XXXClass::on_message_func_ptr, this, ::_1, ::_2)); // 綁定websocket鏈接有消息到來時的回調函數

上面三個回調函數的原型以下,我是將server對象直接封裝到一個類裏面使用的,所以這裏綁定的回調函數能夠直接使用類的方法。Websocketpp也提供了其餘不少環節上的回調函數設定,可自行查看其源代碼進行了解。

1 class XXXClass
2 {
3 public :
4     void on_open_func_ptr(connection_hdl hdl);
5     void on_close_func_ptr(connection_hdl hdl);
6     void on_message_func_ptr(connection_hdl hdl, message_ptr msg);
7 }

回調參數中的connection_hdl是一個weak_ptr,若是須要將鏈接存到容器中以便管理,則不能使用傳入的hdl,須要使用

1 server::connection_ptr con = m_server.get_con_from_hdl(hdl);

得到的con是個shared_ptr,再調用

1 void *con_ptr = con->get();

能夠獲得這個鏈接的實際對象的地址,但websocketpp對咱們隱藏了其對象的結構,只給了咱們一個void*,不過用於在每次回調時區分不一樣的客戶端足夠了。

當websocket有新消息到來時,咱們能夠經過

1 std::string msg_str = msg->get_payload();

直接獲取到傳輸的內容。

 

 

以上,就是websocketpp集成後的簡單使用流程,server對象其實還提供了不少的使用方法以及回調綁定功能,等有時間我再詳細研究,如今這幾個已經能知足個人需求了。

相關文章
相關標籤/搜索