Reputation: 31
I'm writting a simple chat application using node.js and express.js, and feel like I'm doing something wrong. Chat itself works fine on first page load, but on each page reload, I get all messages printed out twice or more (depending on number of page reloads). Looks like I get new listeners created on every page reload. From what I understand, I need to move out listener code (io.socket) from router handler, but I don't understand where to move and how to call it later, alongside with render page on page request. Any help appreciated. Thanks.
Here is my app code:
./app.js
var express = require("express");
var app = express();
var test = require("./routes/test")
var port = 3000;
app.set("port", port);
app.set("views", __dirname + "/views");
app.set("view engine", "jade");
app.get("/test", test.test);
var io = require("socket.io").listen(app.listen(port));
app.set("io", io);
console.log("Listening on port " + port);
and ./routes/test.js
exports.test= function(req, res) {
res.render('test');
var app = req.app;
var io = app.get('io');
io.sockets.on('connection', function (socket) {
socket.emit('message', { message: 'welcome to the chat' });
socket.on('send', function (data) {
io.sockets.emit('message', data);
});
});
}
Upvotes: 2
Views: 589
Reputation: 420
I got this problem before.
Try to move these code outside the callback test.test
io.sockets.on('connection', function (socket) {
socket.emit('message', { message: 'welcome to the chat' });
socket.on('send', function (data) {
io.sockets.emit('message', data);
});
});
Hope this would help
Upvotes: 0
Reputation: 2049
I added a socket.io('disconnect', function () {...}) in test.js as well as adding console.log(...) in the 'connection' and 'disconnect' events. This confirmed that on n-th page refresh the server got n disconnect and n+1 connection events, which is what you say you see.
Your page refresh looks like a disconnection to socket.io and it reconnects to the lost connection, which triggers a connection event. At the same time your socket.io('connection', ...) triggers another connection.
Every refresh you add one more listener for incoming messages, and each one gets the socket.emit('message', ...) message.
I tried some code and your code should run if you change
io.sockets.on('connection', function (socket) {
to
io.sockets.once('connection', function (socket) {
as the latter runs the event handler the first time only.
Upvotes: 1