#include "wsClient.h" #include "constdef.h" #include #include #include namespace YA { const int _LOGIN_SLEEP_TIME_ = 500;//登录前的等待时间(单位:毫秒) const int _OPEN_SOCKET_WAIT_TIME_ = 100;//等待打开socket时间(单位:毫秒) wsClient::wsClient() { __ID = 0; _reset(); } wsClient::~wsClient() { } void wsClient::_reset() { __Connected = false; __SktOpened = false; __Logined = false; } void wsClient::init( int ID, const std::string & uri, const std::map& MsgFuncList ) { __ID = ID; __uri = uri; __MsgFuncList = MsgFuncList; __wsclient.set_reconnect_attempts( 0 ); using std::placeholders::_1; using std::placeholders::_2; using std::placeholders::_3; using std::placeholders::_4; sio::socket::ptr sock = __wsclient.socket(); __wsclient.set_open_listener( std::bind( &wsClient::_on_connected, this ) ); __wsclient.set_close_listener( std::bind( &wsClient::_on_close, this, std::placeholders::_1 ) ); __wsclient.set_reconnect_listener( std::bind( &wsClient::_on_reconnect, this, std::placeholders::_1, std::placeholders::_2 ) ); __wsclient.set_fail_listener( std::bind( &wsClient::_on_fail, this ) ); __wsclient.set_socket_open_listener( std::bind( &wsClient::_on_socket_opened, this ) ); sock->on( JSON_CMD_VALUE_CALL, sio::socket::event_listener_aux( std::bind( &wsClient::_OnCallMessage, this, _1, _2, _3, _4 ) ) ); sock->on( "code", sio::socket::event_listener_aux( std::bind( &wsClient::_OnLoginResponse, this, _1, _2, _3, _4 ) ) ); } std::string wsClient::get_uri() { return __uri; } int wsClient::connect( int time_out ) { if ( __uri.empty() ) { __LastError = "Error, uri is empty."; return -1; } __wsclient.connect( __uri ); std::cv_status status = std::cv_status::timeout; int nRet = -1; __lock.lock(); if ( !IsConnected() ) { status = __cond.wait_for( __lock, std::chrono::seconds( time_out ) ); if ( std::cv_status::timeout == status ) { __LastError = "Failed to connect server."; nRet = -1; } else { nRet = 0; } } else { nRet = 0; } __lock.unlock(); return nRet; } void wsClient::login() { char szError[512] = { 0 }; if ( !IsConnected() ) { __LastError = "please connect server before login!"; return; } //std::cv_status status = std::cv_status::timeout; __lock.lock(); if ( !IsSktOpened() ) { // status = __cond.wait_for( __lock, std::chrono::milliseconds( _OPEN_SOCKET_WAIT_TIME_ ) ); } __lock.unlock(); if ( !IsSktOpened() ) { __LastError = "socket is not opened before login!"; return; } std::this_thread::sleep_for( std::chrono::milliseconds( _LOGIN_SLEEP_TIME_ ) ); int nRet = 0; YA::_JS_LOGIN_ Login; Login.user_name = JSON_VALUE_USERNAME; Login.user_password = JSON_VALUE_PASSWORD; std::string strLogin = __jsBuilder.BuildLogin( Login ); strLogin += "\n"; sio::socket::ptr skt_ptr; skt_ptr = __wsclient.socket(); skt_ptr->emit( JSON_CMD_VALUE_USER, strLogin, [&]( sio::message::list const& msglist ) { sio::message::ptr msg_ptr = msglist[0]; nRet = ( int ) msg_ptr->get_map()["code"]->get_int(); if ( 0 == nRet ) { __Logined = true; } else { __Logined = false; sprintf( szError, "Login failed,code=%d", nRet ); __LastError = szError; } } ); } void wsClient::_on_connected() { __lock.lock(); __cond.notify_all(); __Connected = true; __lock.unlock(); } void wsClient::send( const std::string & Cmd, const std::string & Data ) { std::lock_guard lock( __send_lock ); sio::socket::ptr skt_ptr; skt_ptr = __wsclient.socket(); skt_ptr->emit( Cmd, Data ); } void wsClient::_on_close( sio::client::close_reason const & reason ) { _reset(); } void wsClient::_on_reconnect( unsigned p1, unsigned p2 ) { _reset(); } void wsClient::_on_fail() { _reset(); } void wsClient::_on_socket_opened() { __SktOpened = true; } void wsClient::_OnCallMessage( std::string const& name, sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp ) { if ( data->get_flag() == sio::message::flag_object ) { std::string cmd = data->get_map()[JSON_ROOT_KEY_CMD]->get_string(); std::map::iterator mit_func; mit_func = __MsgFuncList.find( cmd ); if ( mit_func != __MsgFuncList.end() ) { mit_func->second( GetID(), name, data, need_ack, ack_resp ); } } } void wsClient::_OnLoginResponse( std::string const & name, sio::message::ptr const & data, bool need_ack, sio::message::list & ack_resp ) { char szError[512] = { 0 }; int res_code = ( int ) data->get_map()["code"]->get_int(); switch ( res_code ) { case -1: { __Logined = false; sprintf( szError, "Login failed,code=%d", res_code ); __LastError = szError; break; } case 0: { __Logined = true; break; } default: break; } } int wsClient::GetID() { return __ID; } bool wsClient::IsConnected() { return __Connected; } bool wsClient::IsSktOpened() { return __SktOpened; } bool wsClient::IsLogined() { return __Logined; } void wsClient::close() { __wsclient.sync_close(); } std::string wsClient::GetLastError() { return __LastError; } }