以前給公司寫了一個用於消息交互的服務器,移植到Linux上以後發現H5-Websocket模塊常常出問題,而該模塊是另外一位已經離職同事編寫的,因此修改和維護都存在必定的困難,索性就直接把這個模塊替換掉。從搜索考察websocket的開源庫,到最終代碼編好替換掉模塊,並穩定運行總共耗時4天左右(使用第三方開源庫確實提高了很是大的開發效率,想當初那個離職同事搞了差很少一個月,還不包括後面的各類Bug修改和功能改進)html
好了,廢話很少說,最初我在網上找到Websocket的開源庫有好幾個,但最終選擇了Websocketpp這個庫,主要是由於其不須要額外的編譯庫,也就是說不須要再去編什麼lib(Windows)、點a點o(Linux)等庫文件。如下是我具體的集成步驟:git
Websocketpp是基於boost::asio開發的一個C++協議庫,你的電腦上須要首先安裝boost::asio,我選擇的是完整安裝boost(主要怕萬一還得用到其餘庫,一次性裝完方便些)。boost版本我選擇的是1.67.0。github
你們能夠在如下網址處,找到1.67.0的Windows和Linux下載連接。web
http://www.boost.org/users/history/version_1_67_0.htmlbootstrap
下載完畢後,就要對boost進行編譯和安裝服務器
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的頭文件目錄和庫文件目錄配置進來便可。
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時報一些對象未定義。
能夠在Github上找到該項目,我下載的是master版本,若是該項目有更新那麼master對應的版本號可能會有出入。
https://github.com/zaphoyd/websocketpp
解壓縮文件後,源碼目錄中的websocketpp下就是咱們須要的全部頭文件,不須要額外的編譯,將其放到合適的位置並引入到vs的工程中便可。
解壓縮文件後,將websocketpp放到合適的位置,並添加到兩個頭文件的環境變量中,注意要放在boost的頭文件目錄以後。
從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對象其實還提供了不少的使用方法以及回調綁定功能,等有時間我再詳細研究,如今這幾個已經能知足個人需求了。