-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Description
You want to:
- report a bug
- request a feature
Current behaviour
Following the #3698 issue, which I'll use as basis for this ticket,
I face ping timeouts from both the server and the client side (around 30 seconds).
Client side
Turns out the Socket.IO C++ client receives the pingTimeout
and pingInterval
upon server handshake,
and starts sending ping
packages to the server, which doesn't handle incoming ping
events and
the C++ drop the connection as timeout due to the missing pong
responses.
However, the C++ client code is clever enough to reset the pong
timeout for every incoming message event,
hence I can workaround and preserve the C++ client connection by sending custom ping
events every pingTimeout / 2
ms.
Server side
Once the C++ client no longer considers the server as being dead, we observe a ping timeout
on the server as well,
because the server sends ping
events at pingInterval
(25s) periods and times out at pingInterval + pingTimeout
(30s).
I managed to keep the server connection alive by having pingInterval
< pingTimeout
,
for example pingInterval
at 20s and pingTimeout
at 30s.
Steps to reproduce (if the current behaviour is a bug)
File test.js
:
"use strict";
// Libraries
const express = require("express");
const http = require("http");
const socketio = require("socket.io");
// Variables
const port = 3000;
const app = express();
const serverHTTP = http.Server(app);
// Server
console.log("[SERVER] Creating Socket.IO@3.0.X Server");
const io = new socketio.Server(serverHTTP, {
pingTimeout: 500, // Default: 5000
pingInterval: 2500, // Default: 25000
});
// Namespace
io.of("/user/").use((socket, next) => {
const data = JSON.stringify(socket.handshake.query);
console.log('[SERVER] Connected ("/user/".use)', data);
socket.on("disconnect", (data) => {
console.log('[SERVER] Disconnect ("/user/".use)', data);
});
next();
});
// Listen
serverHTTP.listen(port, () => {
console.log(`[SERVER] Server listening on http://127.0.0.1:${port}`);
});
File test.cpp
: test.cpp
Compile socket.io-client-cpp
and test
:
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
docker run -i --entrypoint bash --rm -v "$PWD:$PWD" -w "$PWD" node:12-stretch <<EOF
cd ./socket.io-client-cpp/
apt update
apt install -y libboost-all-dev build-essential cmake libssl1.0-dev make
cmake .
make install
cd ../
g++ -std=c++11 -Isocket.io-client-cpp/build/include -lboost_system -lpthread -o test test.cpp ./socket.io-client-cpp/build/lib/Release/libsioclient.a
EOF
Run with socket.io@3.0.2
:
docker run -i --entrypoint bash --rm -v "$PWD:$PWD" -w "$PWD" node:12-stretch <<EOF
apt update
apt install libboost-system1.62.0
npm install express http socket.io@3.0.2
echo ''
{
node ./test.js &
server=${!}
sleep 2
timeout 30 ./test true
kill -9 "${server}"
}
EOF
Results with socket.io@3.0.2
:
[SERVER] Creating Socket.IO@3.0.X Server
[SERVER] Server listening on http://127.0.0.1:3000
[CLIENT] Connecting to http://127.0.0.1:3000...
[2020-11-21 23:15:09] [connect] Successful connection
[CLIENT] Connected
[SERVER] Connected ("/user/".use) {"EIO":"4","transport":"websocket","t":"1606000509","query1":"data1","query2":"data2"}
[2020-11-21 23:15:12] [disconnect] Disconnect close local:[1008,Pong timeout] remote:[1006]
[SERVER] Disconnect ("/user/".use) ping timeout
[2020-11-21 23:15:17] [connect] Successful connection
[CLIENT] Connected
[SERVER] Connected ("/user/".use) {"EIO":"4","transport":"websocket","t":"1606000517","query1":"data1","query2":"data2"}
[2020-11-21 23:15:20] [disconnect] Disconnect close local:[1008,Pong timeout] remote:[1006]
[SERVER] Disconnect ("/user/".use) transport close
[2020-11-21 23:15:25] [connect] Successful connection
[CLIENT] Connected
[SERVER] Connected ("/user/".use) {"EIO":"4","transport":"websocket","t":"1606000525","query1":"data1","query2":"data2"}
[2020-11-21 23:15:28] [disconnect] Disconnect close local:[1008,Pong timeout] remote:[1006]
[SERVER] Disconnect ("/user/".use) ping timeout
[2020-11-21 23:15:33] [connect] Successful connection
[CLIENT] Connected
[SERVER] Connected ("/user/".use) {"EIO":"4","transport":"websocket","t":"1606000533","query1":"data1","query2":"data2"}
[2020-11-21 23:15:36] [disconnect] Disconnect close local:[1008,Pong timeout] remote:[1006]
[SERVER] Disconnect ("/user/".use) ping timeout
[CLIENT] Interrupting...
[CLIENT] State: Disconnected
Expected behaviour
Both detailed behaviours are workarounds for issues that shouldn't happen.
Socket.IO was migrated from 2.3.0 to 3.0.2 and the C++ client remains unchanged.
I resolved support on both ends of the connection with the following changes :
// Server
console.log("[SERVER] Creating Socket.IO@3.0.X Server");
const io = new socketio.Server(serverHTTP, {
- pingTimeout: 500, // Default: 5000
+ pingTimeout: 3000, // Default: 5000
pingInterval: 2500, // Default: 25000
});
// Namespace
io.of("/user/").use((socket, next) => {
+ const ping = setInterval(() => {
+ socket.emit("ping", {});
+ }, io.eio.opts.pingTimeout / 2);
const data = JSON.stringify(socket.handshake.query);
console.log('[SERVER] Connected ("/user/".use)', data);
socket.on("disconnect", (data) => {
+ if (ping) {
+ clearInterval(ping);
+ }
console.log('[SERVER] Disconnect ("/user/".use)', data);
});
[SERVER] Creating Socket.IO@3.0.X Server
[SERVER] Server listening on http://127.0.0.1:3000
[CLIENT] Connecting to http://127.0.0.1:3000...
[2020-11-21 23:21:57] [connect] Successful connection
[CLIENT] Connected
[SERVER] Connected ("/user/".use) {"EIO":"4","transport":"websocket","t":"1606000917","query1":"data1","query2":"data2"}
[CLIENT] Interrupting...
[CLIENT] State: Connected
[CLIENT] Disconnected
[2020-11-21 23:22:27] [disconnect] Disconnect close local:[1000,End by user] remote:[1000,End by user]
[SERVER] Disconnect ("/user/".use) transport close
Setup
- OS: Debian Stretch and CentOS 7
- Node.js : 12.19.1
- socket.io version: 3.0.2
Other information (e.g. stacktraces, related issues, suggestions how to fix)
For CentOS 7 targets, compatibility for socket.io-client-cpp
: socketio/socket.io-client-cpp#271