murat-dogan / node-datachannel

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

Websocket onClient and onOpen are fired twice if one client tries to connect to the websocket server multiple times. #297

Open Msfrhdsa opened 3 days ago

Msfrhdsa commented 3 days ago

Even though they fire twice, onMessage only fires once for the client. Are all additional connections from a single client always closed? If so, why do clientSocket.onOpen and ws.onClient fire twice?

After starting the server, I start the client with multiple connections. After the client has connected, I kill the nodejs process and start it again. The client reconnects and in the server console I see onClient and onOpen triggering twice.

// server.js
import nodeDataChannel from 'node-datachannel';
const ws = new nodeDataChannel.WebSocketServer({
    bindAddress: '127.0.0.1', port: 2000,
});
ws.onClient((clientSocket) => {
    clientSocket.onOpen(() => { console.log('Client socket opened'); });
    clientSocket.onClosed(() => { console.log('Client socket closed'); });
    clientSocket.onMessage((message) => {
        console.log('Message from client:', message); clientSocket.sendMessage(message);
    });
});
// client.js
let ws_socket;
let ws_attempts = 0;
const ws_reconnections = 2;
function connect() {
    ws_socket = new WebSocket("ws://127.0.0.1:2000");    
    ws_socket.onopen = (event) => { console.log("onopen", event); ws_socket.send("test"); };
    ws_socket.onmessage = (event) => { console.log("onmessage", event.data) };
    ws_socket.onerror = (error) => { console.log("onerror", error); };
    ws_socket.onclose = (event) => {
        console.log("onclose", event)
        if (ws_attempts < ws_reconnections) {
            ++ws_attempts;
            setTimeout(connect, Math.floor(Math.random() * 500));
        } else {
            console.log("max attempts")
        }
    };
};
connect();
connect();
connect();
connect();
connect();

Node.js: v20.18.0 node-datachannel: 0.20.0 os: windows10 x64

paullouisageneau commented 1 day ago

The client creates multiple Websocket connections in parallel which all attempt to reconnect so the onClient and onOpen callbacks will be called multiple times. Note that you only send messages in the last created Websocket.

On server side you don't save clientSocket anywhere so it might be garbage collected at any point after the onClient callback finishes, probably preventing the onMessage callback to be called for all messages.