no message
parent
cb049223fc
commit
18ef368c38
|
@ -0,0 +1,25 @@
|
||||||
|
cmake_minimum_required(VERSION 3.11)
|
||||||
|
project(websocket_bench)
|
||||||
|
message("cmake module " $ENV{CMAKE_MODULE_PATH})
|
||||||
|
message("project dir " ${PROJECT_SOURCE_DIR})
|
||||||
|
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third/include)
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third/include/boost171)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third/include)
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../obj/inc)
|
||||||
|
|
||||||
|
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../build)
|
||||||
|
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../obj)
|
||||||
|
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/third/lib)
|
||||||
|
|
||||||
|
link_libraries(ws2_32)
|
||||||
|
link_libraries(bcrypt)
|
||||||
|
link_libraries(Iphlpapi.lib ssleay32.lib libeay32.lib Bcrypt.lib )
|
||||||
|
|
||||||
|
add_definitions("-D_WEBSOCKETPP_CPP11_TYPE_TRAITS_ -D_WEBSOCKETPP_CPP11_RANDOM_DEVICE_ -DASIO_STANDALONE")
|
||||||
|
|
||||||
|
add_executable(websocket_bench websocket_bench.cpp websocket_client.cpp)
|
||||||
|
|
||||||
|
target_include_directories(websocket_bench SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../obj/inc/third/include)
|
|
@ -0,0 +1,14 @@
|
||||||
|
# 一个c++ websocket benchmark工具
|
||||||
|
目的: 用于测试websocket服务器的性能
|
||||||
|
|
||||||
|
性能指标:</br>
|
||||||
|
- 每秒吞吐量。
|
||||||
|
- 并发数。
|
||||||
|
- 请求延迟。
|
||||||
|
|
||||||
|
功能:</br>
|
||||||
|
- 自定义数据包。
|
||||||
|
- 报表生成功能。
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,281 @@
|
||||||
|
// #include "websocket_client.h"
|
||||||
|
|
||||||
|
// #include <iostream>
|
||||||
|
|
||||||
|
// int main(int argc,char **argv) {
|
||||||
|
// std::cout<<"dfasdfasd"<<std::endl;
|
||||||
|
|
||||||
|
// for(int i = 0; i < 500;i++) {
|
||||||
|
// WebsocketClient *p = new WebsocketClient(false);
|
||||||
|
// p->Connect("ws://127.0.0.1:9001/ws");
|
||||||
|
|
||||||
|
// }
|
||||||
|
// while(1) {
|
||||||
|
// Sleep(1000);
|
||||||
|
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define BUF_SIZE 4096
|
||||||
|
|
||||||
|
std::wstring String2WString(const std::string& str_in)
|
||||||
|
{
|
||||||
|
if (str_in.empty())
|
||||||
|
{
|
||||||
|
std::cout << "str_in is empty" << std::endl;
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取待转换的数据的长度
|
||||||
|
int len_in = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str_in.c_str(), -1, NULL, 0);
|
||||||
|
if (len_in <= 0)
|
||||||
|
{
|
||||||
|
std::cout << "The result of WideCharToMultiByte is Invalid!" << std::endl;
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为输出数据申请空间
|
||||||
|
std::wstring wstr_out;
|
||||||
|
wstr_out.resize(len_in - 1, L'\0');
|
||||||
|
|
||||||
|
// 数据格式转换
|
||||||
|
int to_result = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str_in.c_str(), -1, (LPWSTR)wstr_out.c_str(), len_in);
|
||||||
|
|
||||||
|
// 判断转换结果
|
||||||
|
if (0 == to_result)
|
||||||
|
{
|
||||||
|
std::cout << "Can't transfer String to WString" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wstr_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> splitString(std::string srcStr, std::string delimStr,bool repeatedCharIgnored)
|
||||||
|
{
|
||||||
|
std::vector<std::string> resultStringVector;
|
||||||
|
std::replace_if(srcStr.begin(), srcStr.end(), [&](const char& c){if(delimStr.find(c)!=std::string::npos){return true;}else{return false;}}/*pred*/, delimStr.at(0));//将出现的所有分隔符都替换成为一个相同的字符(分隔符字符串的第一个)
|
||||||
|
size_t pos=srcStr.find(delimStr.at(0));
|
||||||
|
std::string addedString="";
|
||||||
|
while (pos!=std::string::npos) {
|
||||||
|
addedString=srcStr.substr(0,pos);
|
||||||
|
if (!addedString.empty()||!repeatedCharIgnored) {
|
||||||
|
resultStringVector.push_back(addedString);
|
||||||
|
}
|
||||||
|
srcStr.erase(srcStr.begin(), srcStr.begin()+pos+1);
|
||||||
|
pos=srcStr.find(delimStr.at(0));
|
||||||
|
}
|
||||||
|
addedString=srcStr;
|
||||||
|
if (!addedString.empty()||!repeatedCharIgnored) {
|
||||||
|
resultStringVector.push_back(addedString);
|
||||||
|
}
|
||||||
|
return resultStringVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StartProcessCommand(std::string path)
|
||||||
|
{
|
||||||
|
HANDLE PipeReadHandle;
|
||||||
|
HANDLE PipeWriteHandle;
|
||||||
|
PROCESS_INFORMATION ProcessInfo;
|
||||||
|
SECURITY_ATTRIBUTES SecurityAttributes;
|
||||||
|
STARTUPINFO StartupInfo;
|
||||||
|
BOOL Success;
|
||||||
|
|
||||||
|
auto pos = path.find(".exe");
|
||||||
|
if(pos != std::string::npos)
|
||||||
|
{
|
||||||
|
std::cout << "find it" << std::endl;
|
||||||
|
}else{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tmp = splitString(path,"\\",true);
|
||||||
|
std::string path1;
|
||||||
|
for (auto itr = tmp.begin();itr != tmp.end();itr++){
|
||||||
|
if(itr->find(".exe") == std::string::npos ){
|
||||||
|
path1 += *itr +"\\";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Zero the structures.
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
ZeroMemory( &StartupInfo, sizeof( StartupInfo ));
|
||||||
|
ZeroMemory( &ProcessInfo, sizeof( ProcessInfo ));
|
||||||
|
ZeroMemory( &SecurityAttributes, sizeof( SecurityAttributes ));
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Create a pipe for the child's STDOUT.
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
SecurityAttributes.bInheritHandle = TRUE;
|
||||||
|
SecurityAttributes.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
Success = CreatePipe
|
||||||
|
(
|
||||||
|
&PipeReadHandle, // address of variable for read handle
|
||||||
|
&PipeWriteHandle, // address of variable for write handle
|
||||||
|
&SecurityAttributes, // pointer to security attributes
|
||||||
|
0 // number of bytes reserved for pipe (use default size)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
//ShowLastError(_T("Error creating pipe"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Set up members of STARTUPINFO structure.
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
StartupInfo.cb = sizeof(STARTUPINFO);
|
||||||
|
StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
|
||||||
|
StartupInfo.wShowWindow = SW_HIDE;
|
||||||
|
StartupInfo.hStdOutput = PipeWriteHandle;
|
||||||
|
StartupInfo.hStdError = PipeWriteHandle;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Create the child process.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Success = CreateProcess
|
||||||
|
(
|
||||||
|
NULL, // pointer to name of executable module
|
||||||
|
LPSTR(path.c_str()), // command line
|
||||||
|
NULL, // pointer to process security attributes
|
||||||
|
NULL, // pointer to thread security attributes (use primary thread security attributes)
|
||||||
|
TRUE, // inherit handles
|
||||||
|
0, // creation flags
|
||||||
|
NULL, // pointer to new environment block (use parent's)
|
||||||
|
path1.c_str(), // pointer to current directory name
|
||||||
|
&StartupInfo, // pointer to STARTUPINFO
|
||||||
|
&ProcessInfo // pointer to PROCESS_INFORMATION
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
//ShowLastError(_T("Error creating process"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD BytesLeftThisMessage = 0;
|
||||||
|
DWORD NumBytesRead;
|
||||||
|
TCHAR PipeData[BUF_SIZE] = {0};
|
||||||
|
DWORD TotalBytesAvailable = 0;
|
||||||
|
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
NumBytesRead = 0;
|
||||||
|
|
||||||
|
Success = PeekNamedPipe
|
||||||
|
(
|
||||||
|
PipeReadHandle, // handle to pipe to copy from
|
||||||
|
PipeData, // pointer to data buffer
|
||||||
|
1, // size, in bytes, of data buffer
|
||||||
|
&NumBytesRead, // pointer to number of bytes read
|
||||||
|
&TotalBytesAvailable, // pointer to total number of bytes available
|
||||||
|
&BytesLeftThisMessage // pointer to unread bytes in this message
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( NumBytesRead )
|
||||||
|
{
|
||||||
|
Success = ReadFile
|
||||||
|
(
|
||||||
|
PipeReadHandle, // handle to pipe to copy from
|
||||||
|
PipeData, // address of buffer that receives data
|
||||||
|
BUF_SIZE - 1, // number of bytes to read
|
||||||
|
&NumBytesRead, // address of number of bytes read
|
||||||
|
NULL // address of structure for data for overlapped I/O
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Zero-terminate the data.
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
PipeData[NumBytesRead] = '\0';
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Replace backspaces with spaces.
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
for ( DWORD ii = 0; ii < NumBytesRead; ii++ )
|
||||||
|
{
|
||||||
|
if ( PipeData[ii] == _T('\b') )
|
||||||
|
{
|
||||||
|
PipeData[ii] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// If we're running a batch file that contains a pause command,
|
||||||
|
// assume it is the last output from the batch file and remove it.
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
TCHAR *ptr = _tcsstr(PipeData, _T("Press any key to continue . . ."));
|
||||||
|
if ( ptr )
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// wstring data = String2WString(std::string(PipeData));
|
||||||
|
|
||||||
|
std::cout << (PipeData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// If the child process has completed, break out.
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
if ( WaitForSingleObject(ProcessInfo.hProcess, 0) == WAIT_OBJECT_0 ) //lint !e1924 (warning about C-style cast)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Close handles.
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
Success = CloseHandle(ProcessInfo.hThread);
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = CloseHandle(ProcessInfo.hProcess);
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = CloseHandle(PipeReadHandle);
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = CloseHandle(PipeWriteHandle);
|
||||||
|
if ( !Success )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, wchar_t* argv[])
|
||||||
|
{
|
||||||
|
StartProcessCommand(std::string("G:\\project\\golang\\src\\background\\background.exe"));
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,440 @@
|
||||||
|
#include "websocket_client.h"
|
||||||
|
|
||||||
|
// This message handler will be invoked once for each incoming message. It
|
||||||
|
// prints the message and then sends a copy of the message back to the server.
|
||||||
|
void on_message(WebsocketClient* c, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||||
|
|
||||||
|
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||||
|
<< " and message: " << msg->get_payload()
|
||||||
|
<< std::endl;
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
// c->send(hdl, msg->get_payload(), msg->get_opcode(), ec);
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "Echo failed because: " << ec.message() << std::endl;
|
||||||
|
}
|
||||||
|
if (c->m_onread != nullptr) {
|
||||||
|
c->m_onread(c, msg->get_payload());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WebsocketClient::SendMsg(const char* str, uint32_t len,
|
||||||
|
websocketpp::frame::opcode::value opcode)
|
||||||
|
{
|
||||||
|
if (this->m_status != WebsocketClient::CONNECTED)
|
||||||
|
return -1;
|
||||||
|
if (m_tls) {
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
this->m_client_tls.send(m_conn_tls, str, len, opcode, ec);
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "Echo failed because: " << ec.message() << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
this->m_client.send(m_conn, str, len, opcode, ec);
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "Echo failed because: " << ec.message() << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void on_open(WebsocketClient* c, websocketpp::connection_hdl hdl) {
|
||||||
|
if (c->m_tls) {
|
||||||
|
TlsClient::connection_ptr con = c->m_client_tls.get_con_from_hdl(hdl);
|
||||||
|
uint32_t usocket = con->get_raw_socket().native_handle();
|
||||||
|
auto m_server = con->get_response_header("Server");
|
||||||
|
std::cout << "open from server" << m_server << std::endl;
|
||||||
|
c->m_status = WebsocketClient::CONNECTED;
|
||||||
|
if (c->m_on_connected != nullptr) {
|
||||||
|
c->m_on_connected(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Client::connection_ptr con = c->m_client.get_con_from_hdl(hdl);
|
||||||
|
uint32_t usocket = con->get_raw_socket().native_handle();
|
||||||
|
auto m_server = con->get_response_header("Server");
|
||||||
|
std::cout << "open from server" << m_server << std::endl;
|
||||||
|
c->m_status = WebsocketClient::CONNECTED;
|
||||||
|
if (c->m_on_connected != nullptr) {
|
||||||
|
c->m_on_connected(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void on_close(WebsocketClient* c, websocketpp::connection_hdl hdl) {
|
||||||
|
// m_status = "Open";
|
||||||
|
|
||||||
|
// client::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||||
|
// m_server = con->get_response_header("Server");
|
||||||
|
c->m_status = WebsocketClient::CLOSED;
|
||||||
|
std::cout << "on_close" << std::endl;
|
||||||
|
if (c->m_on_disconnected != nullptr) {
|
||||||
|
c->m_on_disconnected(c, WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_fail(WebsocketClient* c, websocketpp::connection_hdl hdl) {
|
||||||
|
std::cout << "on_fail" << std::endl;
|
||||||
|
Client::connection_ptr con = c->m_client.get_con_from_hdl(hdl);
|
||||||
|
auto state = con->get_state();
|
||||||
|
if (state == websocketpp::session::state::closed)
|
||||||
|
std::cout << state << " on_fail " << std::endl;
|
||||||
|
c->m_status = WebsocketClient::FAIL;
|
||||||
|
if (c->m_on_disconnected != nullptr) {
|
||||||
|
c->m_on_disconnected(c, WebsocketClient::CloseReason::PEER_CLOSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebsocketClient::~WebsocketClient() {
|
||||||
|
|
||||||
|
this->m_status = WebsocketClient::STOP;
|
||||||
|
if(m_tls)
|
||||||
|
m_client_tls.stop();
|
||||||
|
else
|
||||||
|
m_client.stop();
|
||||||
|
m_thread->join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebsocketClient::Close()
|
||||||
|
{
|
||||||
|
this->m_status = STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string WebsocketClient::Url()
|
||||||
|
{
|
||||||
|
return this->m_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebsocketClient::WebsocketClient( bool tls){
|
||||||
|
m_tls = tls;
|
||||||
|
m_auto_reconn = false;
|
||||||
|
this->m_status = WebsocketClient::STOP;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WebsocketClient::WebsocketClient(std::string url, bool tls) {
|
||||||
|
m_tls = tls;
|
||||||
|
m_auto_reconn = false;
|
||||||
|
m_url = url;
|
||||||
|
this->m_status = WebsocketClient::CONNECTING;
|
||||||
|
|
||||||
|
if (m_tls) {
|
||||||
|
// Set logging to be pretty verbose (everything except message payloads)
|
||||||
|
m_client_tls.set_access_channels(websocketpp::log::alevel::all);
|
||||||
|
m_client_tls.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||||
|
m_client_tls.set_tls_init_handler([this](websocketpp::connection_hdl) {
|
||||||
|
return websocketpp::lib::make_shared<asio::ssl::context>(asio::ssl::context::tlsv1);
|
||||||
|
});
|
||||||
|
// Initialize ASIO
|
||||||
|
m_client_tls.init_asio();
|
||||||
|
m_thread = new std::thread([this]() {
|
||||||
|
while (this->m_status != STOP)
|
||||||
|
{
|
||||||
|
m_client_tls.set_message_handler(bind(&on_message, this, ::_1, ::_2));
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
std::cout << "1" << std::endl;
|
||||||
|
m_conn_tls = m_client_tls.get_connection(this->m_url, ec);
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "could not create connection because: " << ec.message() << std::endl;
|
||||||
|
this->m_status = Status::FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_conn_tls->set_open_handler(websocketpp::lib::bind(
|
||||||
|
&on_open,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn_tls->set_fail_handler(websocketpp::lib::bind(
|
||||||
|
&on_fail,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn_tls->set_close_handler(websocketpp::lib::bind(
|
||||||
|
&on_close,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
|
||||||
|
std::cout << "2" << std::endl;
|
||||||
|
// Note that connect here only requests a connection. No network messages are
|
||||||
|
// exchanged until the event loop starts running in the next line.
|
||||||
|
TlsClient::connection_ptr ptr = m_client_tls.connect(m_conn_tls);
|
||||||
|
if (ptr->get_state() != websocketpp::session::state::open)
|
||||||
|
std::cout << ptr->get_state() << " websocketpp::session::state " << std::endl;
|
||||||
|
// Start the ASIO io_service run loop
|
||||||
|
// this will cause a single connection to be made to the server. c.run()
|
||||||
|
// will exit when this connection is closed.
|
||||||
|
std::cout << "3 " << ptr << " " << m_conn_tls << std::endl;
|
||||||
|
this->m_status = WebsocketClient::CONNECTING;
|
||||||
|
while ((this->m_status != WebsocketClient::FAIL) &&
|
||||||
|
(this->m_status != WebsocketClient::CLOSED)
|
||||||
|
&& (this->m_status != WebsocketClient::STOP)
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
int count_of_handler = this->m_client_tls.run();
|
||||||
|
std::cout << "4 " << std::endl;
|
||||||
|
|
||||||
|
// run应该只执行一次就会退出
|
||||||
|
}
|
||||||
|
catch (std::exception e) {
|
||||||
|
std::cout << "run exception" << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
std::cout << "close";
|
||||||
|
if(m_on_disconnected)
|
||||||
|
this->m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Set logging to be pretty verbose (everything except message payloads)
|
||||||
|
m_client.set_access_channels(websocketpp::log::alevel::all);
|
||||||
|
m_client.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||||
|
|
||||||
|
// Initialize ASIO
|
||||||
|
this->m_client.init_asio();
|
||||||
|
m_thread = new std::thread([this]()
|
||||||
|
{
|
||||||
|
while (this->m_status != STOP)
|
||||||
|
{
|
||||||
|
this->m_client.set_message_handler(bind(&on_message, this, ::_1, ::_2));
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
std::cout << "1" << std::endl;
|
||||||
|
m_conn = m_client.get_connection(this->m_url, ec);
|
||||||
|
if (m_conn != nullptr) {
|
||||||
|
m_conn->set_open_handler(websocketpp::lib::bind(
|
||||||
|
&on_open,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn->set_fail_handler(websocketpp::lib::bind(
|
||||||
|
&on_fail,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn->set_close_handler(websocketpp::lib::bind(
|
||||||
|
&on_close,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "could not create connection because: " << ec.message() << std::endl;
|
||||||
|
this->m_status = Status::FAIL;
|
||||||
|
if (m_on_disconnected)
|
||||||
|
m_on_disconnected(this,
|
||||||
|
WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that connect here only requests a connection. No network messages are
|
||||||
|
// exchanged until the event loop starts running in the next line.
|
||||||
|
Client::connection_ptr ptr = this->m_client.connect(m_conn);
|
||||||
|
if (ptr->get_state() != websocketpp::session::state::open)
|
||||||
|
std::cout << ptr->get_state() << " websocketpp::session::state " << std::endl;
|
||||||
|
// Start the ASIO io_service run loop
|
||||||
|
// this will cause a single connection to be made to the server. c.run()
|
||||||
|
// will exit when this connection is closed.
|
||||||
|
std::cout << "3 " << ptr << " " << m_conn_tls << std::endl;
|
||||||
|
this->m_status = WebsocketClient::CONNECTING;
|
||||||
|
while ((this->m_status != WebsocketClient::FAIL) &&
|
||||||
|
(this->m_status != WebsocketClient::CLOSED)
|
||||||
|
&& (this->m_status != WebsocketClient::STOP)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// while(this->m_status == WebsocketClient::CONNECTED){
|
||||||
|
int count_of_handler = this->m_client.run();
|
||||||
|
// std::cout<<"count_of_handler: " << count_of_handler<<std::endl;
|
||||||
|
// }
|
||||||
|
// run应该只执行一次就会退出
|
||||||
|
}
|
||||||
|
catch (std::exception e) {
|
||||||
|
std::cout << "run exception" << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
std::cout << "close";
|
||||||
|
if(m_on_disconnected)
|
||||||
|
m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WebsocketClient::Connect(std::string url) {
|
||||||
|
m_url = url;
|
||||||
|
this->m_status = WebsocketClient::CONNECTING;
|
||||||
|
|
||||||
|
if (m_tls) {
|
||||||
|
// Set logging to be pretty verbose (everything except message payloads)
|
||||||
|
m_client_tls.set_access_channels(websocketpp::log::alevel::all);
|
||||||
|
m_client_tls.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||||
|
m_client_tls.set_tls_init_handler([this](websocketpp::connection_hdl) {
|
||||||
|
return websocketpp::lib::make_shared<asio::ssl::context>(asio::ssl::context::tlsv1);
|
||||||
|
});
|
||||||
|
// Initialize ASIO
|
||||||
|
m_client_tls.init_asio();
|
||||||
|
m_thread = new std::thread([this]() {
|
||||||
|
while (this->m_status != STOP)
|
||||||
|
{
|
||||||
|
m_client_tls.set_message_handler(bind(&on_message, this, ::_1, ::_2));
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
std::cout << "1" << std::endl;
|
||||||
|
m_conn_tls = m_client_tls.get_connection(this->m_url, ec);
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "could not create connection because: " << ec.message() << std::endl;
|
||||||
|
this->m_status = Status::FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_conn_tls->set_open_handler(websocketpp::lib::bind(
|
||||||
|
&on_open,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn_tls->set_fail_handler(websocketpp::lib::bind(
|
||||||
|
&on_fail,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn_tls->set_close_handler(websocketpp::lib::bind(
|
||||||
|
&on_close,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
|
||||||
|
std::cout << "2" << std::endl;
|
||||||
|
// Note that connect here only requests a connection. No network messages are
|
||||||
|
// exchanged until the event loop starts running in the next line.
|
||||||
|
TlsClient::connection_ptr ptr = m_client_tls.connect(m_conn_tls);
|
||||||
|
if (ptr->get_state() != websocketpp::session::state::open)
|
||||||
|
std::cout << ptr->get_state() << " websocketpp::session::state " << std::endl;
|
||||||
|
// Start the ASIO io_service run loop
|
||||||
|
// this will cause a single connection to be made to the server. c.run()
|
||||||
|
// will exit when this connection is closed.
|
||||||
|
std::cout << "3 " << ptr << " " << m_conn_tls << std::endl;
|
||||||
|
this->m_status = WebsocketClient::CONNECTING;
|
||||||
|
while ((this->m_status != WebsocketClient::FAIL) &&
|
||||||
|
(this->m_status != WebsocketClient::CLOSED)
|
||||||
|
&& (this->m_status != WebsocketClient::STOP)
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
int count_of_handler = this->m_client_tls.run();
|
||||||
|
std::cout << "4 " << std::endl;
|
||||||
|
|
||||||
|
// run应该只执行一次就会退出
|
||||||
|
}
|
||||||
|
catch (std::exception e) {
|
||||||
|
std::cout << "run exception" << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
std::cout << "close";
|
||||||
|
if(m_on_disconnected)
|
||||||
|
this->m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Set logging to be pretty verbose (everything except message payloads)
|
||||||
|
m_client.set_access_channels(websocketpp::log::alevel::all);
|
||||||
|
m_client.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||||
|
|
||||||
|
// Initialize ASIO
|
||||||
|
this->m_client.init_asio();
|
||||||
|
m_thread = new std::thread([this]()
|
||||||
|
{
|
||||||
|
while (this->m_status != STOP)
|
||||||
|
{
|
||||||
|
this->m_client.set_message_handler(bind(&on_message, this, ::_1, ::_2));
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
std::cout << "1" << std::endl;
|
||||||
|
m_conn = m_client.get_connection(this->m_url, ec);
|
||||||
|
if (m_conn != nullptr) {
|
||||||
|
m_conn->set_open_handler(websocketpp::lib::bind(
|
||||||
|
&on_open,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn->set_fail_handler(websocketpp::lib::bind(
|
||||||
|
&on_fail,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
m_conn->set_close_handler(websocketpp::lib::bind(
|
||||||
|
&on_close,
|
||||||
|
this,
|
||||||
|
websocketpp::lib::placeholders::_1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "could not create connection because: " << ec.message() << std::endl;
|
||||||
|
this->m_status = Status::FAIL;
|
||||||
|
if (m_on_disconnected)
|
||||||
|
m_on_disconnected(this,
|
||||||
|
WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that connect here only requests a connection. No network messages are
|
||||||
|
// exchanged until the event loop starts running in the next line.
|
||||||
|
Client::connection_ptr ptr = this->m_client.connect(m_conn);
|
||||||
|
if (ptr->get_state() != websocketpp::session::state::open)
|
||||||
|
std::cout << ptr->get_state() << " websocketpp::session::state " << std::endl;
|
||||||
|
// Start the ASIO io_service run loop
|
||||||
|
// this will cause a single connection to be made to the server. c.run()
|
||||||
|
// will exit when this connection is closed.
|
||||||
|
std::cout << "3 " << ptr << " " << m_conn_tls << std::endl;
|
||||||
|
this->m_status = WebsocketClient::CONNECTING;
|
||||||
|
while ((this->m_status != WebsocketClient::FAIL) &&
|
||||||
|
(this->m_status != WebsocketClient::CLOSED)
|
||||||
|
&& (this->m_status != WebsocketClient::STOP)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// while(this->m_status == WebsocketClient::CONNECTED){
|
||||||
|
int count_of_handler = this->m_client.run();
|
||||||
|
// std::cout<<"count_of_handler: " << count_of_handler<<std::endl;
|
||||||
|
// }
|
||||||
|
// run应该只执行一次就会退出
|
||||||
|
}
|
||||||
|
catch (std::exception e) {
|
||||||
|
std::cout << "run exception" << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
std::cout << "close";
|
||||||
|
if(m_on_disconnected)
|
||||||
|
m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WebsocketClient::SetOnConnectedHandler(OnConnectedHandler on_connected) {
|
||||||
|
this->m_on_connected = on_connected;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebsocketClient::SetOnDisConnectedHandler(OnDisConnectedHandler on_disconnected) {
|
||||||
|
this->m_on_disconnected = on_disconnected;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebsocketClient::SetOnReadHandler(OnReadHandler onread) {
|
||||||
|
this->m_onread = onread;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* @Author: your name
|
||||||
|
* @Date: 2022-02-25 22:06:57
|
||||||
|
* @LastEditTime: 2022-03-06 22:42:35
|
||||||
|
* @LastEditors: Please set LastEditors
|
||||||
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
* @FilePath: \test\websocket_client.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <websocketpp/config/asio_client.hpp>
|
||||||
|
#include <websocketpp/config/asio_no_tls_client.hpp>
|
||||||
|
#include <websocketpp/client.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef websocketpp::client<websocketpp::config::asio_client> Client;
|
||||||
|
typedef websocketpp::client<websocketpp::config::asio_tls_client> TlsClient;
|
||||||
|
|
||||||
|
using websocketpp::lib::placeholders::_1;
|
||||||
|
using websocketpp::lib::placeholders::_2;
|
||||||
|
using websocketpp::lib::bind;
|
||||||
|
|
||||||
|
// pull out the type of messages sent by our config
|
||||||
|
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
|
||||||
|
|
||||||
|
class WebsocketClient {
|
||||||
|
public:
|
||||||
|
enum CloseReason{
|
||||||
|
PEER_CLOSED = 1,
|
||||||
|
LOCAL_CLOSED = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::function<void (WebsocketClient *)> OnConnectedHandler;
|
||||||
|
typedef std::function<void (WebsocketClient *,CloseReason)> OnDisConnectedHandler;
|
||||||
|
typedef std::function<void(WebsocketClient *, std::string )> OnReadHandler;
|
||||||
|
|
||||||
|
enum Status
|
||||||
|
{
|
||||||
|
STOP = 0,
|
||||||
|
CONNECTING = 1,
|
||||||
|
CONNECTED = 2,
|
||||||
|
FAIL = 3,
|
||||||
|
CLOSED = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
Status State(){
|
||||||
|
return m_status;
|
||||||
|
}
|
||||||
|
std::string Url();
|
||||||
|
WebsocketClient(bool tls);
|
||||||
|
WebsocketClient(std::string url,bool tls);
|
||||||
|
int Connect(std::string);
|
||||||
|
~WebsocketClient();
|
||||||
|
void Close();
|
||||||
|
int SendMsg(const char * str,uint32_t len,websocketpp::frame::opcode::value);
|
||||||
|
friend void on_fail(WebsocketClient * c, websocketpp::connection_hdl hdl);
|
||||||
|
friend void on_close(WebsocketClient * c, websocketpp::connection_hdl hdl);
|
||||||
|
friend void on_open(WebsocketClient * c, websocketpp::connection_hdl hdl);
|
||||||
|
friend void on_message(WebsocketClient* c, websocketpp::connection_hdl hdl, message_ptr msg);
|
||||||
|
int SetOnConnectedHandler(OnConnectedHandler on_connected);
|
||||||
|
int SetOnDisConnectedHandler(OnDisConnectedHandler on_disconnected);
|
||||||
|
int SetOnReadHandler(OnReadHandler onread);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_socketfd;
|
||||||
|
Status m_status; // 当前服务器状态
|
||||||
|
std::string m_url; // url
|
||||||
|
Client m_client; // 客户端
|
||||||
|
TlsClient m_client_tls;
|
||||||
|
std::thread *m_thread; // 当前活动线程
|
||||||
|
Client::connection_ptr m_conn;
|
||||||
|
TlsClient::connection_ptr m_conn_tls; // 客户端
|
||||||
|
|
||||||
|
bool m_auto_reconn;
|
||||||
|
bool m_tls;
|
||||||
|
OnReadHandler m_onread;
|
||||||
|
OnConnectedHandler m_on_connected;
|
||||||
|
OnDisConnectedHandler m_on_disconnected;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ WebsocketClient::WebsocketClient(std::string url, bool tls) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int WebsocketClient::Connect(std::string url){
|
int WebsocketClient::Connect(std::string url) {
|
||||||
m_url = url;
|
m_url = url;
|
||||||
this->m_status = WebsocketClient::CONNECTING;
|
this->m_status = WebsocketClient::CONNECTING;
|
||||||
|
|
||||||
|
@ -420,7 +420,6 @@ int WebsocketClient::Connect(std::string url){
|
||||||
m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED);
|
m_on_disconnected(this, WebsocketClient::CloseReason::LOCAL_CLOSED);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue