mirror of
https://github.com/socketio/socket.io-client-cpp.git
synced 2026-05-06 14:02:56 +00:00
feat: add support for Socket.IO v3
See also: - https://github.com/socketio/engine.io-protocol#difference-between-v3-and-v4 - https://github.com/socketio/socket.io-protocol#difference-between-v5-and-v4
This commit is contained in:
parent
b1216ee428
commit
ec4d540ad5
10
README.md
10
README.md
@ -6,16 +6,24 @@ By virtue of being written in C++, this client works in several different platfo
|
||||
|
||||
[](https://github.com/socketio/socket.io-client-cpp/tree/master/examples)
|
||||
|
||||
## Compatibility table
|
||||
|
||||
| C++ Client version | Socket.IO server version |
|
||||
| ------------------- | ------------------------ |
|
||||
| 2.x (`2.x` branch) | 1.x / 2.x |
|
||||
| 3.x (master branch) | 3.x |
|
||||
|
||||
## Features
|
||||
|
||||
- 100% written in modern C++11
|
||||
- Compatible with socket.io 1.0+ protocol
|
||||
- Binary support
|
||||
- Automatic JSON encoding
|
||||
- Multiplex support
|
||||
- Similar API to the Socket.IO JS client
|
||||
- Cross platform
|
||||
|
||||
Note: Only the WebSocket transport is currently implemented (no fallback to HTTP long-polling)
|
||||
|
||||
## Installation alternatives
|
||||
|
||||
* [With CMAKE](./INSTALL.md#with-cmake)
|
||||
|
||||
@ -222,7 +222,7 @@ namespace sio
|
||||
} else {
|
||||
ss<<uo.get_host();
|
||||
}
|
||||
ss<<":"<<uo.get_port()<<"/socket.io/?EIO=3&transport=websocket";
|
||||
ss<<":"<<uo.get_port()<<"/socket.io/?EIO=4&transport=websocket";
|
||||
if(m_sid.size()>0){
|
||||
ss<<"&sid="<<m_sid;
|
||||
}
|
||||
@ -295,12 +295,6 @@ namespace sio
|
||||
lib::error_code ec;
|
||||
this->m_client.send(this->m_con, *payload, frame::opcode::text, ec);
|
||||
});
|
||||
if(m_ping_timer)
|
||||
{
|
||||
asio::error_code e_code;
|
||||
m_ping_timer->expires_from_now(milliseconds(m_ping_interval), e_code);
|
||||
m_ping_timer->async_wait(std::bind(&client_impl::ping,this, std::placeholders::_1));
|
||||
}
|
||||
if(!m_ping_timeout_timer)
|
||||
{
|
||||
m_ping_timeout_timer.reset(new asio::steady_timer(m_client.get_io_service()));
|
||||
@ -497,12 +491,6 @@ namespace sio
|
||||
m_ping_timeout = 60000;
|
||||
}
|
||||
|
||||
m_ping_timer.reset(new asio::steady_timer(m_client.get_io_service()));
|
||||
asio::error_code ec;
|
||||
m_ping_timer->expires_from_now(milliseconds(m_ping_interval), ec);
|
||||
if(ec)LOG("ec:"<<ec.message()<<endl){};
|
||||
m_ping_timer->async_wait(std::bind(&client_impl::ping,this, std::placeholders::_1));
|
||||
LOG("On handshake,sid:"<<m_sid<<",ping interval:"<<m_ping_interval<<",ping timeout"<<m_ping_timeout<<endl);
|
||||
return;
|
||||
}
|
||||
failed:
|
||||
@ -510,8 +498,14 @@ failed:
|
||||
m_client.get_io_service().dispatch(std::bind(&client_impl::close_impl, this,close::status::policy_violation,"Handshake error"));
|
||||
}
|
||||
|
||||
void client_impl::on_pong()
|
||||
void client_impl::on_ping()
|
||||
{
|
||||
packet p(packet::frame_pong);
|
||||
m_packet_mgr.encode(p, [&](bool /*isBin*/,shared_ptr<const string> payload)
|
||||
{
|
||||
this->m_client.send(this->m_con, *payload, frame::opcode::text);
|
||||
});
|
||||
|
||||
if(m_ping_timeout_timer)
|
||||
{
|
||||
m_ping_timeout_timer->cancel();
|
||||
@ -536,8 +530,8 @@ failed:
|
||||
//FIXME how to deal?
|
||||
this->close_impl(close::status::abnormal_close, "End by server");
|
||||
break;
|
||||
case packet::frame_pong:
|
||||
this->on_pong();
|
||||
case packet::frame_ping:
|
||||
this->on_ping();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -560,11 +554,6 @@ failed:
|
||||
m_ping_timeout_timer->cancel(ec);
|
||||
m_ping_timeout_timer.reset();
|
||||
}
|
||||
if(m_ping_timer)
|
||||
{
|
||||
m_ping_timer->cancel(ec);
|
||||
m_ping_timer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void client_impl::reset_states()
|
||||
|
||||
@ -170,7 +170,7 @@ namespace sio
|
||||
//socketio callbacks
|
||||
void on_handshake(message::ptr const& message);
|
||||
|
||||
void on_pong();
|
||||
void on_ping();
|
||||
|
||||
void reset_states();
|
||||
|
||||
@ -201,8 +201,6 @@ namespace sio
|
||||
|
||||
packet_manager m_packet_mgr;
|
||||
|
||||
std::unique_ptr<asio::steady_timer> m_ping_timer;
|
||||
|
||||
std::unique_ptr<asio::steady_timer> m_ping_timeout_timer;
|
||||
|
||||
std::unique_ptr<asio::steady_timer> m_reconn_timer;
|
||||
|
||||
@ -53,13 +53,7 @@ namespace sio
|
||||
Value numVal;
|
||||
numVal.SetInt((int)buffers.size());
|
||||
val.AddMember("num", numVal, doc.GetAllocator());
|
||||
//FIXME can not avoid binary copy here.
|
||||
shared_ptr<string> write_buffer = make_shared<string>();
|
||||
write_buffer->reserve(msg.get_binary()->size()+1);
|
||||
char frame_char = packet::frame_message;
|
||||
write_buffer->append(&frame_char,1);
|
||||
write_buffer->append(*(msg.get_binary()));
|
||||
buffers.push_back(write_buffer);
|
||||
buffers.push_back(msg.get_binary());
|
||||
}
|
||||
|
||||
void accept_array_message(array_message const& msg,Value& val,Document& doc,vector<shared_ptr<const string> >& buffers)
|
||||
@ -253,7 +247,7 @@ namespace sio
|
||||
{
|
||||
if (_pending_buffers > 0) {
|
||||
assert(is_binary_message(buf_payload));//this is ensured by outside.
|
||||
_buffers.push_back(std::make_shared<string>(buf_payload.data()+1,buf_payload.size()-1));
|
||||
_buffers.push_back(std::make_shared<string>(buf_payload.data(),buf_payload.size()));
|
||||
_pending_buffers--;
|
||||
if (_pending_buffers == 0) {
|
||||
|
||||
|
||||
@ -269,10 +269,6 @@ namespace sio
|
||||
void socket::impl::send_connect()
|
||||
{
|
||||
NULL_GUARD(m_client);
|
||||
if(m_nsp == "/")
|
||||
{
|
||||
return;
|
||||
}
|
||||
packet p(packet::type_connect,m_nsp);
|
||||
m_client->send(p);
|
||||
m_connection_timer.reset(new asio::steady_timer(m_client->get_io_service()));
|
||||
|
||||
@ -1,19 +1,17 @@
|
||||
var port = 3000;
|
||||
|
||||
var io = require('socket.io').listen(port);
|
||||
var io = require('socket.io')().listen(port);
|
||||
console.log("Listening on port " + port);
|
||||
|
||||
/* Socket.IO events */
|
||||
io.on("connection", function(socket){
|
||||
console.log("new connection");
|
||||
socket.on('test_text',function()
|
||||
{
|
||||
console.log("test text event received.");
|
||||
socket.on('test_text', (...args) => {
|
||||
console.log("test text event received.", args);
|
||||
});
|
||||
|
||||
socket.on('test_binary',function()
|
||||
{
|
||||
var args =Array.prototype.slice.call(arguments);
|
||||
socket.on('test_binary', (...args) => {
|
||||
console.log("test binary event received", args);
|
||||
if(args[0] instanceof Buffer)
|
||||
{
|
||||
console.log("test binary event received,binary length:"+ args[0].length);
|
||||
|
||||
165
test/echo_server/package-lock.json
generated
Normal file
165
test/echo_server/package-lock.json
generated
Normal file
@ -0,0 +1,165 @@
|
||||
{
|
||||
"name": "echo_server",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/component-emitter": {
|
||||
"version": "1.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
|
||||
"integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
|
||||
},
|
||||
"@types/cors": {
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz",
|
||||
"integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.14.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz",
|
||||
"integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A=="
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"base64-arraybuffer": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
|
||||
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
|
||||
},
|
||||
"base64id": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
},
|
||||
"cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||
"requires": {
|
||||
"object-assign": "^4",
|
||||
"vary": "^1"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.6.tgz",
|
||||
"integrity": "sha512-rf7HAVZpcRrcKEKddgIzYUnwg0g5HE1RvJaTLwkcfJmce4g+po8aMuE6vxzp6JwlK8FEq/vi0KWN6tA585DjaA==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "2.0.0",
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.0",
|
||||
"ws": "~7.4.2"
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.45.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
|
||||
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.28",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
|
||||
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
|
||||
"requires": {
|
||||
"mime-db": "1.45.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.5.tgz",
|
||||
"integrity": "sha512-5yWQ43P/4IttmPCGKDQ3CVocBiJWGpibyhYJxgUhf69EHMzmK8XW0DkmHIoYdLmZaVZJyiEkUqpeC7rSCIqekw==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.0",
|
||||
"@types/cors": "^2.8.8",
|
||||
"@types/node": "^14.14.10",
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io": "~4.0.6",
|
||||
"socket.io-adapter": "~2.0.3",
|
||||
"socket.io-parser": "~4.0.3"
|
||||
}
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz",
|
||||
"integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ=="
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.3.tgz",
|
||||
"integrity": "sha512-m4ybFiP4UYVORRt7jcdqf8UWx+ywVdAqqsJyruXxAdD3Sv6MDemijWij34mOWdMJ55bEdIb9jACBhxUgNK6sxw==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1"
|
||||
}
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
|
||||
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "echo_server",
|
||||
"author":"Melo Yao",
|
||||
"version":"0.0.0",
|
||||
"author": "Melo Yao",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"socket.io": "1.*"
|
||||
}
|
||||
"socket.io": "^3.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
test/sio_test
Executable file
BIN
test/sio_test
Executable file
Binary file not shown.
@ -118,16 +118,16 @@ TEST_CASE( "test_packet_accept_4" )
|
||||
int bin1Num = j["bin1"]["num"].get<int>();
|
||||
char numchar[] = {0,0};
|
||||
numchar[0] = bin1Num+'0';
|
||||
CHECK(buffers[bin1Num]->length()==101);
|
||||
CHECK(buffers[bin1Num]->length()==100);
|
||||
INFO("outputing payload bin1 num:" << numchar)
|
||||
CHECK(buffers[bin1Num]->at(50)==0);
|
||||
CHECK(buffers[bin1Num]->at(0) == packet::frame_message);
|
||||
CHECK(buffers[bin1Num]->at(0) == 0);
|
||||
int bin2Num = j["bin2"]["num"].get<int>();
|
||||
numchar[0] = bin2Num+'0';
|
||||
CHECK(buffers[bin2Num]->length()==51);
|
||||
CHECK(buffers[bin2Num]->length()==50);
|
||||
INFO("outputing payload bin2 num:" << numchar)
|
||||
CHECK(buffers[bin2Num]->at(25)==1);
|
||||
CHECK(buffers[bin2Num]->at(0) == packet::frame_message);
|
||||
CHECK(buffers[bin2Num]->at(0) == 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -209,12 +209,11 @@ TEST_CASE( "test_packet_parse_4" )
|
||||
packet p;
|
||||
bool hasbin = p.parse("452-/nsp,101[\"bin_event\",[{\"_placeholder\":true,\"num\":1},{\"_placeholder\":true,\"num\":0},\"text\"]]");
|
||||
CHECK(hasbin);
|
||||
char buf[101];
|
||||
buf[0] = packet::frame_message;
|
||||
memset(buf+1,0,100);
|
||||
char buf[100];
|
||||
memset(buf,0,100);
|
||||
|
||||
std::string bufstr(buf,101);
|
||||
std::string bufstr2(buf,51);
|
||||
std::string bufstr(buf,100);
|
||||
std::string bufstr2(buf,50);
|
||||
CHECK(p.parse_buffer(bufstr));
|
||||
CHECK(!p.parse_buffer(bufstr2));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user