以前给公司写了一个用于消息交互的服务器,移植到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对象其实还提供了不少的使用方法以及回调绑定功能,等有时间我再详细研究,如今这几个已经能知足个人需求了。