fix connect timeoute introduced by pull request#11

This commit is contained in:
melode11 2015-05-06 23:30:35 +08:00
parent 035ad01cc0
commit df8b2291c8
3 changed files with 55 additions and 48 deletions

View File

@ -19,6 +19,7 @@
#endif #endif
using boost::posix_time::milliseconds; using boost::posix_time::milliseconds;
using namespace std;
namespace sio namespace sio
{ {
@ -60,7 +61,7 @@ namespace sio
sync_close(); sync_close();
} }
void client_impl::connect(const std::string& uri, const std::map<string,string>& query) void client_impl::connect(const string& uri, const map<string,string>& query)
{ {
if(m_reconn_timer) if(m_reconn_timer)
{ {
@ -87,25 +88,25 @@ namespace sio
m_base_url = uri; m_base_url = uri;
m_reconn_made = 0; m_reconn_made = 0;
std::string queryString; string query_str;
for(std::map<std::string,std::string>::const_iterator it=query.begin();it!=query.end();++it){ for(map<string,string>::const_iterator it=query.begin();it!=query.end();++it){
queryString.append("&"); query_str.append("&");
queryString.append(it->first); query_str.append(it->first);
queryString.append("="); query_str.append("=");
queryString.append(it->second); query_str.append(it->second);
} }
m_query_string=queryString; m_query_string=move(query_str);
this->reset_states(); this->reset_states();
m_client.get_io_service().dispatch(lib::bind(&client_impl::connect_impl,this,uri,queryString)); m_client.get_io_service().dispatch(lib::bind(&client_impl::connect_impl,this,uri,m_query_string));
m_network_thread.reset(new std::thread(lib::bind(&client_impl::run_loop,this)));//uri lifecycle? m_network_thread.reset(new thread(lib::bind(&client_impl::run_loop,this)));//uri lifecycle?
} }
socket::ptr const& client_impl::socket(std::string const& nsp) socket::ptr const& client_impl::socket(string const& nsp)
{ {
std::lock_guard<std::mutex> guard(m_socket_mutex); lock_guard<mutex> guard(m_socket_mutex);
std::string aux; string aux;
if(nsp == "") if(nsp == "")
{ {
aux = "/"; aux = "/";
@ -127,7 +128,7 @@ namespace sio
} }
else else
{ {
std::pair<const std::string, socket::ptr> p(aux,std::shared_ptr<sio::socket>(new sio::socket(this,aux))); pair<const string, socket::ptr> p(aux,shared_ptr<sio::socket>(new sio::socket(this,aux)));
return (m_sockets.insert(p).first)->second; return (m_sockets.insert(p).first)->second;
} }
} }
@ -157,9 +158,9 @@ namespace sio
m_packet_mgr.encode(p); m_packet_mgr.encode(p);
} }
void client_impl::remove_socket(std::string const& nsp) void client_impl::remove_socket(string const& nsp)
{ {
std::lock_guard<std::mutex> guard(m_socket_mutex); lock_guard<mutex> guard(m_socket_mutex);
auto it = m_sockets.find(nsp); auto it = m_sockets.find(nsp);
if(it!= m_sockets.end()) if(it!= m_sockets.end())
{ {
@ -172,12 +173,12 @@ namespace sio
return m_client.get_io_service(); return m_client.get_io_service();
} }
void client_impl::on_socket_closed(std::string const& nsp) void client_impl::on_socket_closed(string const& nsp)
{ {
if(m_socket_close_listener)m_socket_close_listener(nsp); if(m_socket_close_listener)m_socket_close_listener(nsp);
} }
void client_impl::on_socket_opened(std::string const& nsp) void client_impl::on_socket_opened(string const& nsp)
{ {
if(m_socket_open_listener)m_socket_open_listener(nsp); if(m_socket_open_listener)m_socket_open_listener(nsp);
} }
@ -192,11 +193,11 @@ namespace sio
"run loop end"); "run loop end");
} }
void client_impl::connect_impl(const std::string& uri, const std::string& queryString) void client_impl::connect_impl(const string& uri, const string& queryString)
{ {
do{ do{
websocketpp::uri uo(uri); websocketpp::uri uo(uri);
std::ostringstream ss; ostringstream ss;
if (m_sid.size()==0) { if (m_sid.size()==0) {
ss<<"ws://"<<uo.get_host()<<":"<<uo.get_port()<<"/socket.io/?EIO=4&transport=websocket&t="<<time(NULL)<<queryString; ss<<"ws://"<<uo.get_host()<<":"<<uo.get_port()<<"/socket.io/?EIO=4&transport=websocket&t="<<time(NULL)<<queryString;
@ -223,9 +224,9 @@ namespace sio
} }
} }
void client_impl::close_impl(close::status::value const& code,std::string const& reason) void client_impl::close_impl(close::status::value const& code,string const& reason)
{ {
LOG("Close by reason:"<<reason << std::endl); LOG("Close by reason:"<<reason << endl);
if(m_reconn_timer) if(m_reconn_timer)
{ {
m_reconn_timer->cancel(); m_reconn_timer->cancel();
@ -233,7 +234,7 @@ namespace sio
} }
if (m_con.expired()) if (m_con.expired())
{ {
std::cerr << "Error: No active session" << std::endl; cerr << "Error: No active session" << endl;
} }
else else
{ {
@ -242,7 +243,7 @@ namespace sio
} }
} }
void client_impl::send_impl(std::shared_ptr<const std::string> const& payload_ptr,frame::opcode::value opcode) void client_impl::send_impl(shared_ptr<const string> const& payload_ptr,frame::opcode::value opcode)
{ {
if(m_con_state == con_opened) if(m_con_state == con_opened)
{ {
@ -257,7 +258,7 @@ namespace sio
m_client.send(m_con,*payload_ptr,opcode,ec); m_client.send(m_con,*payload_ptr,opcode,ec);
if(ec) if(ec)
{ {
std::cerr<<"Send failed,reason:"<< ec.message()<<std::endl; cerr<<"Send failed,reason:"<< ec.message()<<endl;
} }
} }
} }
@ -266,7 +267,7 @@ namespace sio
{ {
if(ec || m_con.expired()) if(ec || m_con.expired())
{ {
LOG("ping exit,con is expired?"<<m_con.expired()<<",ec:"<<ec.message()<<std::endl); LOG("ping exit,con is expired?"<<m_con.expired()<<",ec:"<<ec.message()<<endl);
return; return;
} }
packet p(packet::frame_ping); packet p(packet::frame_ping);
@ -297,7 +298,7 @@ namespace sio
{ {
return; return;
} }
LOG("Pong timeout"<<std::endl); LOG("Pong timeout"<<endl);
m_client.get_io_service().dispatch(lib::bind(&client_impl::close_impl, this,close::status::policy_violation,"Pong timeout")); m_client.get_io_service().dispatch(lib::bind(&client_impl::close_impl, this,close::status::policy_violation,"Pong timeout"));
} }
@ -312,7 +313,7 @@ namespace sio
m_con_state = con_opening; m_con_state = con_opening;
m_reconn_made++; m_reconn_made++;
this->reset_states(); this->reset_states();
LOG("Reconnecting..."<<std::endl); LOG("Reconnecting..."<<endl);
if(m_reconnecting_listener) m_reconnecting_listener(); if(m_reconnecting_listener) m_reconnecting_listener();
m_client.get_io_service().dispatch(lib::bind(&client_impl::connect_impl,this,m_base_url,m_query_string)); m_client.get_io_service().dispatch(lib::bind(&client_impl::connect_impl,this,m_base_url,m_query_string));
} }
@ -324,9 +325,9 @@ namespace sio
return min<unsigned>(static_cast<unsigned>(m_reconn_delay * pow(1.5,m_reconn_made)),m_reconn_delay_max); return min<unsigned>(static_cast<unsigned>(m_reconn_delay * pow(1.5,m_reconn_made)),m_reconn_delay_max);
} }
socket::ptr client_impl::get_socket_locked(std::string const& nsp) socket::ptr client_impl::get_socket_locked(string const& nsp)
{ {
std::lock_guard<std::mutex> guard(m_socket_mutex); lock_guard<mutex> guard(m_socket_mutex);
auto it = m_sockets.find(nsp); auto it = m_sockets.find(nsp);
if(it != m_sockets.end()) if(it != m_sockets.end())
{ {
@ -340,9 +341,9 @@ namespace sio
void client_impl::sockets_invoke_void(void (sio::socket::*fn)(void)) void client_impl::sockets_invoke_void(void (sio::socket::*fn)(void))
{ {
std::map<const std::string,socket::ptr> socks; map<const string,socket::ptr> socks;
{ {
std::lock_guard<std::mutex> guard(m_socket_mutex); lock_guard<mutex> guard(m_socket_mutex);
socks.insert(m_sockets.begin(),m_sockets.end()); socks.insert(m_sockets.begin(),m_sockets.end());
} }
for (auto it = socks.begin(); it!=socks.end(); ++it) { for (auto it = socks.begin(); it!=socks.end(); ++it) {
@ -355,10 +356,10 @@ namespace sio
m_con.reset(); m_con.reset();
m_con_state = con_closed; m_con_state = con_closed;
this->sockets_invoke_void(&sio::socket::on_disconnect); this->sockets_invoke_void(&sio::socket::on_disconnect);
LOG("Connection failed." << std::endl); LOG("Connection failed." << endl);
if(m_reconn_made<m_reconn_attempts) if(m_reconn_made<m_reconn_attempts)
{ {
LOG("Reconnect for attempt:"<<m_reconn_made<<std::endl); LOG("Reconnect for attempt:"<<m_reconn_made<<endl);
unsigned delay = this->next_delay(); unsigned delay = this->next_delay();
if(m_reconnect_listener) m_reconnect_listener(m_reconn_made,delay); if(m_reconnect_listener) m_reconnect_listener(m_reconn_made,delay);
m_reconn_timer.reset(new boost::asio::deadline_timer(m_client.get_io_service())); m_reconn_timer.reset(new boost::asio::deadline_timer(m_client.get_io_service()));
@ -374,23 +375,24 @@ namespace sio
void client_impl::on_open(connection_hdl con) void client_impl::on_open(connection_hdl con)
{ {
LOG("Connected." << std::endl); LOG("Connected." << endl);
m_con_state = con_opened; m_con_state = con_opened;
m_con = con; m_con = con;
m_reconn_made = 0; m_reconn_made = 0;
this->sockets_invoke_void(&sio::socket::on_open); this->sockets_invoke_void(&sio::socket::on_open);
this->socket("");
if(m_open_listener)m_open_listener(); if(m_open_listener)m_open_listener();
} }
void client_impl::on_close(connection_hdl con) void client_impl::on_close(connection_hdl con)
{ {
LOG("Client Disconnected." << std::endl); LOG("Client Disconnected." << endl);
m_con_state = con_closed; m_con_state = con_closed;
lib::error_code ec; lib::error_code ec;
close::status::value code = close::status::normal; close::status::value code = close::status::normal;
client_type::connection_ptr conn_ptr = m_client.get_con_from_hdl(con, ec); client_type::connection_ptr conn_ptr = m_client.get_con_from_hdl(con, ec);
if (ec) { if (ec) {
LOG("OnClose get conn failed"<<ec<<std::endl); LOG("OnClose get conn failed"<<ec<<endl);
} }
else else
{ {
@ -410,7 +412,7 @@ namespace sio
this->sockets_invoke_void(&sio::socket::on_disconnect); this->sockets_invoke_void(&sio::socket::on_disconnect);
if(m_reconn_made<m_reconn_attempts) if(m_reconn_made<m_reconn_attempts)
{ {
LOG("Reconnect for attempt:"<<m_reconn_made<<std::endl); LOG("Reconnect for attempt:"<<m_reconn_made<<endl);
unsigned delay = this->next_delay(); unsigned delay = this->next_delay();
if(m_reconnect_listener) m_reconnect_listener(m_reconn_made,delay); if(m_reconnect_listener) m_reconnect_listener(m_reconn_made,delay);
m_reconn_timer.reset(new boost::asio::deadline_timer(m_client.get_io_service())); m_reconn_timer.reset(new boost::asio::deadline_timer(m_client.get_io_service()));
@ -447,7 +449,7 @@ namespace sio
const map<string,message::ptr>* values = &(obj_ptr->get_map()); const map<string,message::ptr>* values = &(obj_ptr->get_map());
auto it = values->find("sid"); auto it = values->find("sid");
if (it!= values->end()) { if (it!= values->end()) {
m_sid = std::static_pointer_cast<string_message>(it->second)->get_string(); m_sid = static_pointer_cast<string_message>(it->second)->get_string();
} }
else else
{ {
@ -455,7 +457,7 @@ namespace sio
} }
it = values->find("pingInterval"); it = values->find("pingInterval");
if (it!= values->end()&&it->second->get_flag() == message::flag_integer) { if (it!= values->end()&&it->second->get_flag() == message::flag_integer) {
m_ping_interval = (unsigned)std::static_pointer_cast<int_message>(it->second)->get_int(); m_ping_interval = (unsigned)static_pointer_cast<int_message>(it->second)->get_int();
} }
else else
{ {
@ -464,7 +466,7 @@ namespace sio
it = values->find("pingTimeout"); it = values->find("pingTimeout");
if (it!=values->end()&&it->second->get_flag() == message::flag_integer) { if (it!=values->end()&&it->second->get_flag() == message::flag_integer) {
m_ping_timeout = (unsigned) std::static_pointer_cast<int_message>(it->second)->get_int(); m_ping_timeout = (unsigned) static_pointer_cast<int_message>(it->second)->get_int();
} }
else else
{ {
@ -474,9 +476,9 @@ namespace sio
m_ping_timer.reset(new boost::asio::deadline_timer(m_client.get_io_service())); m_ping_timer.reset(new boost::asio::deadline_timer(m_client.get_io_service()));
boost::system::error_code ec; boost::system::error_code ec;
m_ping_timer->expires_from_now(milliseconds(m_ping_interval), ec); m_ping_timer->expires_from_now(milliseconds(m_ping_interval), ec);
if(ec)LOG("ec:"<<ec.message()<<std::endl); if(ec)LOG("ec:"<<ec.message()<<endl);
m_ping_timer->async_wait(lib::bind(&client_impl::ping,this,lib::placeholders::_1)); m_ping_timer->async_wait(lib::bind(&client_impl::ping,this,lib::placeholders::_1));
LOG("On handshake,sid:"<<m_sid<<",ping interval:"<<m_ping_interval<<",ping timeout"<<m_ping_timeout<<std::endl); LOG("On handshake,sid:"<<m_sid<<",ping interval:"<<m_ping_interval<<",ping timeout"<<m_ping_timeout<<endl);
return; return;
} }
failed: failed:
@ -521,13 +523,13 @@ failed:
void client_impl::on_encode(bool isBinary,shared_ptr<const string> const& payload) void client_impl::on_encode(bool isBinary,shared_ptr<const string> const& payload)
{ {
LOG("encoded payload length:"<<payload->length()<<std::endl); LOG("encoded payload length:"<<payload->length()<<endl);
m_client.get_io_service().dispatch(lib::bind(&client_impl::send_impl,this,payload,isBinary?frame::opcode::binary:frame::opcode::text)); m_client.get_io_service().dispatch(lib::bind(&client_impl::send_impl,this,payload,isBinary?frame::opcode::binary:frame::opcode::text));
} }
void client_impl::clear_timers() void client_impl::clear_timers()
{ {
LOG("clear timers"<<std::endl); LOG("clear timers"<<endl);
boost::system::error_code ec; boost::system::error_code ec;
if(m_ping_timeout_timer) if(m_ping_timeout_timer)
{ {

View File

@ -87,7 +87,7 @@ namespace sio
} }
// Client Functions - such as send, etc. // Client Functions - such as send, etc.
void connect(const std::string& uri, const std::map<string, string>& queryString); void connect(const std::string& uri, const std::map<std::string, std::string>& queryString);
sio::socket::ptr const& socket(const std::string& nsp); sio::socket::ptr const& socket(const std::string& nsp);

View File

@ -265,6 +265,10 @@ namespace sio
void socket::impl::send_connect() void socket::impl::send_connect()
{ {
NULL_GUARD(m_client); NULL_GUARD(m_client);
if(m_nsp == "/")
{
return;
}
packet p(packet::type_connect,m_nsp); packet p(packet::type_connect,m_nsp);
m_client->send(p); m_client->send(p);
m_connection_timer.reset(new boost::asio::deadline_timer(m_client->get_io_service())); m_connection_timer.reset(new boost::asio::deadline_timer(m_client->get_io_service()));
@ -469,8 +473,9 @@ namespace sio
return; return;
} }
m_connection_timer.reset(); m_connection_timer.reset();
LOG("Connection timeout"<<std::endl); LOG("Connection timeout,close socket."<<std::endl);
this->on_disconnect(); //Should close socket if no connected message arrive.Otherwise we'll never ask for open again.
this->on_close();
} }
void socket::impl::send_packet(sio::packet &p) void socket::impl::send_packet(sio::packet &p)