l4f
l4f

Reputation: 31

How to separate code from request handlers (node.js & express.js)

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

Answers (2)

klchow916
klchow916

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

JohnSz
JohnSz

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

Related Questions