nim_duilib/examples/proto_debuger/websocket_client.cpp

256 lines
10 KiB
C++
Raw Normal View History

2022-03-09 00:28:31 +08:00
#include "websocket_client.h"
2022-02-23 00:13:30 +08:00
2022-02-23 01:35:24 +08:00
// 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.
2022-03-09 00:28:31 +08:00
void on_message(WebsocketClient* c, websocketpp::connection_hdl hdl, message_ptr msg) {
2022-02-23 00:13:30 +08:00
std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message: " << msg->get_payload()
<< std::endl;
websocketpp::lib::error_code ec;
2022-03-09 00:28:31 +08:00
// c->send(hdl, msg->get_payload(), msg->get_opcode(), ec);
2022-02-23 01:35:24 +08:00
if (ec) {
std::cout << "Echo failed because: " << ec.message() << std::endl;
2022-02-23 00:13:30 +08:00
}
2022-03-09 00:28:31 +08:00
if (c->m_onread != nullptr) {
c->m_onread(c,msg->get_payload());
}
2022-02-23 00:13:30 +08:00
}
2022-03-09 00:28:31 +08:00
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;
}
2022-02-23 00:13:30 +08:00
2022-03-09 00:28:31 +08:00
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";
2022-02-23 00:13:30 +08:00
2022-03-09 00:28:31 +08:00
// 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);
}
}
2022-02-23 01:35:24 +08:00
2022-03-09 00:28:31 +08:00
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);
}
}
2022-02-23 00:13:30 +08:00
2022-03-09 00:28:31 +08:00
WebsocketClient::~WebsocketClient(){
2022-02-23 00:13:30 +08:00
2022-03-09 00:28:31 +08:00
this->m_status = WebsocketClient::STOP;
m_client.stop();
m_thread->join();
}
2022-02-23 00:13:30 +08:00
2022-03-09 00:28:31 +08:00
WebsocketClient::WebsocketClient(std::string url,bool tls)
{
m_tls = tls;
m_auto_reconn = false;
m_url = url;
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);
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
));
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
this->m_status = Status::FAIL;
}
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{
// while(this->m_status == WebsocketClient::CONNECTED){
int count_of_handler = this->m_client_tls.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";
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);
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;
}
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.
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";
this->m_on_disconnected(this,WebsocketClient::CloseReason::LOCAL_CLOSED);
});
}
}
2022-02-23 00:13:30 +08:00
2022-03-09 00:28:31 +08:00
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;
}