Building a chat with socket.io, I came along with a bug that seems to me elementary, but I cannot find an answer.
The number of posted messages after refreshing page is the same with page refreshes (I post only one each time).
I checked similar answers like socket-io-multiple-chats-on-one-page socket-io-multiple-connections-when-refreshing-page node-js-socket-io-page-refresh-multiple-connections The main difference with the above is that the count of connected sockets in console is correct. I also tried the solution of node-js-socket-io-page-refresh-multiple-connections
var socket = io({transports: ['websocket'], upgrade: false});
but no result. I also tried rooms and namespaces.
Tested on Chrome 72, Canary 74.
Here's part of my server
io.sockets.on('connection', function (socket) {
socket.on('subscribe', function(data) { socket.join(room); })
socket.on('unsubscribe', function(data) { socket.leave(room); })
socket.on("newchatsent", function (msg) {
//save chat to mongo
MongoClient.connect(url, {useNewUrlParser: true}, function (err, client) {
if (err) {
console.error('An error occurred connecting to MongoDB: ', err);
} else {
var db = client.db(database);
var collection = db.collection("chat");
collection.updateOne({"cid": cid},{
$push: {"chat": {u: who, c: msg, t: timestamp}},
"$inc": {"total": 1}, "$inc": {[unread]: 1}
}, function (err, result) {
if (err) {
console.log(err);
} else {
//emit data to frontend
socket.emit("newchatreply", msg);
client.close();
}
assert.equal(err, null);
});
}
});
});
});
And here is a part of client
var socket = io({transports: ['websocket'], upgrade: false});
socket.emit("subscribe", room);
$(document).on('keypress', function (e) {
if (e.which == 13 && $("#chatText").is(":focus")) {
var mes = $('#chatText').val().trim();
if (mes != "") {
socket.emit('newchatsent', mes);
$('#chatText').val('');
return false;
}
}
});
socket.on('newchatreply', function(msg){
$( "#chati" ).append( "<div id='chatLine'><p class='triangle-isosceles right'>"+ msg +"</p>" +
"<div class='chatDatetime'>"+date('Y-m-d H:i')+"</div></div>");
});
No case of preventing refresh - the chatbox has to be open through multiple pages. Any thoughts?
Solution
Given by Sriram Kailasam: The problem is that you are registering a new event handler every time the page is reloaded. This causes the data to be sent multiple times. I had the same issue and I solved by using io.once()
instead of io.on()
in the server.