murat-dogan / node-datachannel

WebRTC For Node.js and Electron. libdatachannel node bindings.
Mozilla Public License 2.0
279 stars 52 forks source link

WebSocket Server Garbage Collected #272

Open murat-dogan opened 5 days ago

murat-dogan commented 5 days ago

https://github.com/murat-dogan/node-datachannel/blob/websocket-examples/examples/client-server/signaling-server.js

In this example after 1 client connection, the garbage collector deletes wsServer.

Workaround; https://github.com/murat-dogan/node-datachannel/blob/c311c111bdd1b3c20d056f6f46a7c3c12610f8ce/examples/client-server/signaling-server.js#L40-L44

Here is the log

murat@murat-ThinkBook:~/js/node-datachannel/examples/client-server$ node --trace-gc signaling-server.js 
2024-07-05 16:49:33.016 DEBUG [612304] [WebSocketServerWrapper::WebSocketServerWrapper@38] Constructor called
2024-07-05 16:49:33.016 DEBUG [612304] [WebSocketServerWrapper::WebSocketServerWrapper@157] Creating a new WebSocketServer
2024-07-05 16:49:33.016 DEBUG [612304] [rtc::impl::Init::doInit@113] Global initialization
2024-07-05 16:49:33.016 DEBUG [612304] [rtc::impl::Init::doInit@123] Spawning 8 threads
2024-07-05 16:49:33.016 DEBUG [612323] [rtc::impl::PollService::runLoop@164] Poll service started
2024-07-05 16:49:33.021 DEBUG [612304] [rtc::impl::TcpServer::TcpServer@25] Initializing TCP server
2024-07-05 16:49:33.021 DEBUG [612304] [rtc::impl::TcpServer::listen@97] Listening on port 8000
2024-07-05 16:49:33.021 DEBUG [612304] [WebSocketServerWrapper::WebSocketServerWrapper@166] WebSocketServer created
2024-07-05 16:49:33.021 DEBUG [612304] [WebSocketServerWrapper::onClient@227] onClient() called
2024-07-05 16:49:33.021 INFO  [612326] [rtc::impl::WebSocketServer::runLoop@72] Starting WebSocketServer
2024-07-05 16:49:38.794 DEBUG [612326] [rtc::impl::TcpTransport::TcpTransport@63] Initializing TCP transport with socket
2024-07-05 16:49:38.794 DEBUG [612326] [rtc::impl::WsTransport::WsTransport@61] Initializing WebSocket transport
2024-07-05 16:49:38.794 DEBUG [612326] [WebSocketServerWrapper::onClient@248] onClient ws received from WebSocketServer
2024-07-05 16:49:38.795 DEBUG [612304] [WebSocketServerWrapper::onClient@251] mOnClientCallback call(1)
2024-07-05 16:49:38.795 DEBUG [612323] [rtc::impl::WsHandshake::parseHttpRequest@152] WebSocket request method="GET", path="/mm2X"
2024-07-05 16:49:38.795 DEBUG [612304] [WebSocketWrapper::WebSocketWrapper@59] Constructor called
2024-07-05 16:49:38.795 DEBUG [612304] [WebSocketWrapper::WebSocketWrapper@66] Using WebSocket got from WebSocketServer
2024-07-05 16:49:38.795 INFO  [612323] [rtc::impl::WsTransport::incoming@135] WebSocket server-side open
2024-07-05 16:49:38.795 DEBUG [612323] [rtc::impl::WsTransport::sendHttpResponse@209] Sending WebSocket HTTP response
2024-07-05 16:49:38.795 DEBUG [612304] [WebSocketServerWrapper::onClient@262] mOnClientCallback call(2)
2024-07-05 16:49:38.795 DEBUG [612323] [rtc::impl::WebSocket::initWsTransport@428] WebSocket open
2024-07-05 16:49:38.896 DEBUG [612304] [WebSocketWrapper::path@508] path() called
New Connection from mm2X
2024-07-05 16:49:38.913 DEBUG [612304] [WebSocketWrapper::onMessage@722] onMessage() called
2024-07-05 16:49:38.913 DEBUG [612304] [WebSocketWrapper::onMessage@741] setting onMessage cb on mWebSocketPtr
2024-07-05 16:49:38.913 DEBUG [612304] [WebSocketWrapper::onClosed@609] onClosed() called
2024-07-05 16:49:38.913 DEBUG [612304] [WebSocketWrapper::onError@646] onError() called
2024-07-05 16:49:48.804 DEBUG [612323] [rtc::impl::WsTransport::recvFrame@302] WebSocket received frame: opcode=9, length=4
2024-07-05 16:49:48.804 DEBUG [612323] [rtc::impl::WsTransport::recvFrame@349] WebSocket received ping, sending pong
2024-07-05 16:49:48.804 DEBUG [612323] [rtc::impl::WsTransport::sendFrame@375] WebSocket sending frame: opcode=10, length=4
[612304:0x70a8cc0]    22192 ms: Mark-Compact (reduce) 4.3 (4.7) -> 3.2 (4.7) MB, 3.63 / 0.03 ms  (+ 2.5 ms in 11 steps since start of marking, biggest step 0.3 ms, walltime since start of marking 7 ms) (average mu = 1.000, current mu = 1.000) finalize incremental marking via task; GC in old space requested
2024-07-05 16:49:55.135 DEBUG [612304] [WebSocketServerWrapper::~WebSocketServerWrapper@172] Destructor called
2024-07-05 16:49:55.135 DEBUG [612304] [WebSocketServerWrapper::doStop@178] doStop() called
2024-07-05 16:49:55.135 DEBUG [612304] [WebSocketServerWrapper::doStop@181] Stopping...
2024-07-05 16:49:55.135 DEBUG [612304] [rtc::impl::WebSocketServer::stop@65] Stopping WebSocketServer thread
2024-07-05 16:49:55.135 DEBUG [612304] [rtc::impl::TcpServer::close@89] Closing TCP server socket
2024-07-05 16:49:55.135 DEBUG [612326] [rtc::impl::TcpServer::accept@82] TCP server closed
2024-07-05 16:49:55.135 INFO  [612326] [rtc::impl::WebSocketServer::runLoop@97] Stopped WebSocketServer

@ptesavol Could you please also check?

paullouisageneau commented 4 days ago

All objects in the wrapper behave like that currently, as soon as they are not reachable anymore they can be garbage collected (even for globals), so you have to keep a reachable reference. Maybe it could be changed.

murat-dogan commented 4 days ago

If I write only 1 line like this

let wsServer = new nodeDataChannel.WebSocketServer({ bindAddress: '127.0.0.1', port: 8000 });

It will be directly deleted by the garbage collector, this is normal. No reference, callback etc.

If I write this line

let peer1 = new nodeDataChannel.PeerConnection('Peer1', { iceServers: ['stun:stun.l.google.com:19302'] });

It will not be deleted by the garbage collector, because we have a callback created here https://github.com/murat-dogan/node-datachannel/blob/63ec3215063931aae772f2acfa2c2199bfeca2b3/src/peer-connection-wrapper.cpp#L252

Here I am setting a callback. Like this

const wsServer = new nodeDataChannel.WebSocketServer({ bindAddress: '127.0.0.1', port: 8000 });

wsServer.onClient((ws) => {
....
}

And it is not garbage collected(because we have a callback), until a client is connected. When a client connects, it is being deleted. I don't see any difference on the binding side.

Do you have any idea?

Msfrhdsa commented 1 day ago

Hopefully this will be fixed soon. Workaround is an eyesore.