WebSocket protocol 是HTML5一种新的协议,它是实现了浏览器与服务器全双工通信。WebSocket协议解析参考这篇文章http://www.cnblogs.com/chyingp/p/websocket-deep-in.html
一、下载websocketpp、boost、openssl
WebSocketpp只是一个库,本身不需要搭建什么环境,只要新建的项目引入相关的库就行。但是WebSocketpp依赖于boost库和openssl库,这两个库需要编译生成lib库文件,在使用WebSocketpp库的工程中,需要引入boost库和openssl库的头文件和lib文件。openssl库是可选的。
https://github.com/zaphoyd/websocketpp
https://sourceforge.net/projects/boost/files/boost/1.62.0/ 下载boost最新版本1.62.0
https://github.com/openssl/openssl/releases下载openssl1.1.0版本
websocket使用wss协议,使用websocketpp库时,需要使用openssl库支持。
在工程属性中添加openssl头文件目录引用,增加openssl库文件目录引用。
在工程代码中添加对openssl部份引用:
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
二、新建一个vs工程,书写websocket相关代码,配置工程属性。
第一步,把boost的根目录添加到include。
第二步,把websoketpp的子目录添加到include,比如将websocketpp-0.8.1中websoketpp目录拷贝本工程中,同时添加到include
第三步,把boost/stage/lib添加到静态库。
websocketpp-0.8.1中examples目录中有很少实例代码,可以参考。
1、出现错误 C4996 'std::copy::_Unchecked_iterators::_Deprecate': Call to 'std::copy' with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' WebSocketTest c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility 2372
解决方法:添加参数“_SCL_SECURE_NO_WARNINGS”(SCL安全无警告,S代表Safety 安全、C代表Check检查、L代表List清单)到预处理器定义中,不警告这种不安全的操作方式,方法如下:
项目->属性->配置属性->C/C++->预处理器->预处理器定义(末尾加上“_SCL_SECURE_NO_WARNINGS”即可(注意分号隔开))
2、在ie9-ie11浏览器测试成功。在edge浏览器中测试,发现不成功。在chrome浏览器中测试成功。
3、tcp连接建立之后接受数据,解析http请求websocket upgrade命令,成功失败做对应的处理,参考connection_impl.hpp文件
connection_impl.hpp文件的handle_read_http_response函数解析客户端数据。
3.1)http请求是websocket upgrade命令,执行log_open_result
3.1.1)执行open handler回调函数,在此函数函数中可以获取到客户端的请求方法、命令、参数等。
3.1.2)handle_read_frame读取帧数据
3.2)http请求非websocket upgrade命令,返回错误,terminate关闭连接。
三、服务器实例代码
// WebSocketTest.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"#include
#include
#include
#include #include
#include
#include
struct NameAndValue
{std::string strName;std::string strValue;
};
// 字符串分割
int StringSplit(std::vector
//去前后空格
std::string& StringTrim(std::string &str);
//获取请求命令与参数
bool GetReqeustCommandAndParmeter(std::string strUri, std::string & strRequestOperateCommand, std::list
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;// pull out the type of messages sent by our config
typedef server::message_ptr message_ptr;bool validate(server *, websocketpp::connection_hdl) {//sleep(6);return true;
}void on_http(server* s, websocketpp::connection_hdl hdl) {server::connection_ptr con &#61; s->get_con_from_hdl(hdl);std::string res &#61; con->get_request_body();std::stringstream ss;ss <<"got HTTP request with " <
}void on_fail(server* s, websocketpp::connection_hdl hdl) {server::connection_ptr con &#61; s->get_con_from_hdl(hdl);std::cout <<"Fail handler: " <
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {/*hdl.lock().get() 获得连接标识msg->get_payload() 是收到的消息内容msg->get_opcode() 是收到消息的类型 &#xff0c;包含&#xff1a;文本TEXT,二进制BINARY等等*/std::cout <<"on_message called with hdl: " <
int StringSplit(std::vector
{if (src.empty() || separator.empty())return 0;int nCount &#61; 0;std::string temp;size_t pos &#61; 0, offset &#61; 0;// 分割第1~n-1个while ((pos &#61; src.find_first_of(separator, offset)) !&#61; std::string::npos){temp &#61; src.substr(offset, pos - offset);if (temp.length() > 0) {dst.push_back(temp);nCount&#43;&#43;;}offset &#61; pos &#43; 1;}// 分割第n个temp &#61; src.substr(offset, src.length() - offset);if (temp.length() > 0) {dst.push_back(temp);nCount&#43;&#43;;}return nCount;
}
//去前后空格
std::string& StringTrim(std::string &str)
{if (str.empty()) {return str;}str.erase(0, str.find_first_not_of(" "));str.erase(str.find_last_not_of(" ") &#43; 1);return str;
}
//获取请求命令与参数
bool GetReqeustCommandAndParmeter(std::string strUri, std::string & strRequestOperateCommand, std::list
{bool bRet &#61; false;std::vector
}
四、web客户端实例代码
test.html
代码下载
WebSocket在线测试工具&#xff1a;http://ws.douqq.com/