There used to be a problem that when only one user connected, there appears to be lots of users at the back end.
Before
After
At the beginning I guess the process of generating lots of users might be related with the process of network address translation, and finally all the dead clients should be killed and reach the stable state.
So I tired to find some examples on killing dead clients, thanks Shawn for sharing with me p5 live media server as a good example. Here is how the server side handles that.
There are mainly two parts: 1. tell every client the disconnection event and trigger their client side handler. 2. delete from the array which stores the active clients
socket.on('disconnect', function() {
console.log("Client has disconnected " + socket.id);
if (rooms[socket.room]) { // Check on this
// Tell everyone first
let which = -1;
for (let i = 0; i < rooms[socket.room].length; i++) {
if (rooms[socket.room][i].id != socket.id) {
rooms[socket.room][i].emit('peer_disconnect', socket.id);
} else {
which = i;
}
}
// Now remove from array
if (rooms[socket.room][which].id == socket.id) {
rooms[socket.room].splice(which,1);
}
});
Look back at my project, there are similar things happening.
//Handle the disconnection
client.on("disconnect", () => {
//Delete this client from the object
delete clients[client.id];
//Tell everyone
io.sockets.emit(
"userDisconnected",
io.engine.clientsCount,
client.id,
Object.keys(clients)
);
//database
let today = new Date();
let date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate() + ' ' + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
let datalog =
"User " +
client.id +
" disconnected, there are " +
io.engine.clientsCount +
" clients connected" + " at " + date;
let myState = clients[client.id];
console.log(datalog);
db.insert({ "message": datalog }, function (err, newDocs) {
console.log("err:" + err);
console.log("Disconnect:" + newDocs);
});
});
Then I look on the client side. What the handler from client side does : 1. remove dead clients from array 2. remove from three.js scene 3. remove DOM element, corresponding to what it has done when new user join.
I'm still worried about two problems here: 1. the delete method I used 2. shall I also discard the peer to peer connection with that user. 3. set it to null before remove that from array
After testing I make sure the delete method is working, and from my understanding to webRTC I guess the answer to the second question is no.
Then I start to look into the socket.io issue. After long-time testing I found the problem might be related with node version. Here is a good article for managing node version. After trying I would also recommend updating node with NVM (Node Version Manager), which has detailed documentation in the first article. Also here is another article from digital ocean on how to do that.
After updating node version, I found, that the killing dead clients and socket.io dependency issues got solved at the same time. Still, during this process, I found that the instructions on those two API are worth looking into: Web API RTCPeerConnection and ICE protocol. And also thanks to the class where I learnt that I could also maybe solve this problem by using Docker.