fix some special case of packet parsing,fully support namespace

This commit is contained in:
melode11 2015-04-02 19:20:39 +08:00
parent 9e718c55f7
commit a94d95ac59
3 changed files with 56 additions and 25 deletions

View File

@ -472,7 +472,16 @@ void set_##__FIELD__(__TYPE__ const& l) \
boost::system::error_code ec; boost::system::error_code ec;
m_connection_timer->expires_from_now(milliseconds(60000), ec); m_connection_timer->expires_from_now(milliseconds(60000), ec);
m_connection_timer->async_wait(lib::bind(&client::impl::__timeout_connection,this,lib::placeholders::_1)); m_connection_timer->async_wait(lib::bind(&client::impl::__timeout_connection,this,lib::placeholders::_1));
if(m_nsp.length()>0)//send connect only if we got nsp, otherwise wait for default one.
{
packet p(packet::type_connect, m_nsp);
m_packet_mgr.encode(p,
[&](bool isBin,shared_ptr<const string> payload)
{
lib::error_code ec;
this->m_client.send(this->m_con, *payload, frame::opcode::text, ec);
});
}
if(m_open_listener)m_open_listener(); if(m_open_listener)m_open_listener();
} }
@ -537,7 +546,10 @@ void set_##__FIELD__(__TYPE__ const& l) \
case packet::type_connect: case packet::type_connect:
{ {
LOG("Received Message type (Connect)"<<std::endl); LOG("Received Message type (Connect)"<<std::endl);
this->on_connected(); if(p.get_nsp() == m_nsp)
{
this->on_connected();
}
break; break;
} }
case packet::type_disconnect: case packet::type_disconnect:
@ -731,7 +743,7 @@ void set_##__FIELD__(__TYPE__ const& l) \
else else
{ {
std::string payload; std::string payload;
packet pack(packet::type_disconnect); packet pack(packet::type_disconnect,m_nsp);
m_packet_mgr.encode(pack, m_packet_mgr.encode(pack,
[&](bool isBin,shared_ptr<const string> payload) [&](bool isBin,shared_ptr<const string> payload)
{ {
@ -804,7 +816,14 @@ void set_##__FIELD__(__TYPE__ const& l) \
{ {
ss<<"ws://"<<uo.get_host()<<":"<<uo.get_port()<<"/socket.io/?EIO=4&transport=websocket&sid="<<m_sid<<"&t="<<time(NULL); ss<<"ws://"<<uo.get_host()<<":"<<uo.get_port()<<"/socket.io/?EIO=4&transport=websocket&sid="<<m_sid<<"&t="<<time(NULL);
} }
if(uo.get_resource()!="/")
{
m_nsp = uo.get_resource();
}
else
{
m_nsp.clear();
}
lib::error_code ec; lib::error_code ec;
client_type::connection_ptr con = m_client.get_connection(ss.str(), ec); client_type::connection_ptr con = m_client.get_connection(ss.str(), ec);
if (ec) { if (ec) {

View File

@ -177,9 +177,10 @@ namespace sio
|| (isAck&&pack_id>=0))); || (isAck&&pack_id>=0)));
} }
packet::packet(type type,message::ptr const& msg): packet::packet(type type,string const& nsp, message::ptr const& msg):
_frame(frame_message), _frame(frame_message),
_type(type), _type(type),
_nsp(nsp),
_message(msg), _message(msg),
_pack_id(-1), _pack_id(-1),
_pending_buffers(0) _pending_buffers(0)
@ -260,36 +261,47 @@ namespace sio
} }
} }
size_t comma_pos = payload_ptr.find_first_of("{[,"); size_t nsp_json_pos = payload_ptr.find_first_of("{[\"/",pos,4);
if( comma_pos!= string::npos && payload_ptr[comma_pos] == ',') if(nsp_json_pos==string::npos)//no namespace and no message,the end.
{ {
_nsp = payload_ptr.substr(pos,comma_pos - pos);
pos = comma_pos+1;
}
if (pos >= payload_ptr.length()) {
//message only have type, maybe with namespace.
return false; return false;
} }
size_t data_pos = payload_ptr.find_first_of("[{", pos, 2); size_t json_pos = nsp_json_pos;
if (data_pos == string::npos) { if(payload_ptr[nsp_json_pos] == '/')//nsp_json_pos is start of nsp
//we have pack id, no message.
_pack_id = stoi(payload_ptr.substr(pos));
return false;
}
else if(data_pos>pos)
{ {
//we have pack id and messages. size_t comma_pos = payload_ptr.find_first_of(",");//end of nsp
_pack_id = stoi(payload_ptr.substr(pos,data_pos - pos)); if(comma_pos == string::npos)//packet end with nsp
{
_nsp = payload_ptr.substr(nsp_json_pos);
return false;
}
else//we have a message, maybe the message have an id.
{
_nsp = payload_ptr.substr(nsp_json_pos,comma_pos - nsp_json_pos);
pos = comma_pos+1;//start of the message
json_pos = payload_ptr.find_first_of("\"[{", pos, 3);//start of the json part of message
if(json_pos == string::npos)
{
//no message,the end
//assume if there's no message, there's no message id.
return false;
}
}
}
if(pos<json_pos)//we've got pack id.
{
_pack_id = stoi(payload_ptr.substr(pos,json_pos - pos));
} }
if (_frame == frame_message && (_type == type_binary_event || _type == type_binary_ack)) { if (_frame == frame_message && (_type == type_binary_event || _type == type_binary_ack)) {
//parse later when all buffers are arrived. //parse later when all buffers are arrived.
_buffers.push_back(make_shared<const string>(payload_ptr.data() + data_pos, payload_ptr.length() - data_pos)); _buffers.push_back(make_shared<const string>(payload_ptr.data() + json_pos, payload_ptr.length() - json_pos));
return true; return true;
} }
else else
{ {
Document doc; Document doc;
doc.Parse<0>(payload_ptr.substr(data_pos).data()); doc.Parse<0>(payload_ptr.data()+json_pos);
_message = from_json(doc, vector<shared_ptr<const string> >()); _message = from_json(doc, vector<shared_ptr<const string> >());
return false; return false;
} }
@ -465,4 +477,4 @@ namespace sio
m_decode_callback(*p); m_decode_callback(*p);
} }
} }
} }

View File

@ -54,7 +54,7 @@ namespace sio
packet(frame_type frame); packet(frame_type frame);
packet(type type,message::ptr const& msg = message::ptr());//other message types constructor. packet(type type,string const& nsp= string(),message::ptr const& msg = message::ptr());//other message types constructor.
//empty constructor for parse. //empty constructor for parse.
packet(); packet();