Ilya P
Ilya P

Reputation: 23

Multiply io.on("connection")

After every page updating I have +1 socket connection..

module.exports = function(io, client) {
var GameController = {
   gamePage: function(req, res) {
       client.hget('games', 'game.' + req.params.id, function (err, result) {
           if (err) return result(err);
           var game = JSON.parse(result);

           io.on('connection', function (socket) {
               console.log('send');
               console.log(socket.id);
               io.emit('get_bets', game.players);
           });

           res.render('pages/game', {
               title: 'Game - ' + req.params.id,
               user: req.user,
               game: game
           });
       });
   };
return GameController;
});

route file:

module.exports = function(io, client) {
   var express = require('express');
   var router = express.Router();
   var GameController = require('controllers/GameController')(io, client); 
   router.get('/:id', GameController.gamePage);
   ...
   return router;
};

Client side on react:

var Game = React.createClass({
   getInitialState: function() {
     this.socket = io();

     return {
         bets: null
     }
   },
 socketGetBets: function() {
   var that = this;
   this.socket.on('get_bets', function(data) {
       console.log('get bets');
       that.setState({ bets: data });
   });
   this.socket.on('rand', function(data) {
       console.log(data);
   });
 },
...

But after debug I find what problem not in client side.

app.js file:

var socket_io = require('socket.io');

var io = socket_io();
app.io = io;
//route
var game = require('./routes/games')(io, client);

bin/www file:

var server = http.createServer(app);

var io     = app.io;
io.attach( server );

After page updating, io.on("connection") event show me "send" message in console, after second page updating, I have "send" "send", third update - "send" "send" "send" etc. Than Memory leak warning appeared. Console log socked.id show the same value many time.

Upvotes: 2

Views: 429

Answers (1)

azium
azium

Reputation: 20614

Every time you call on, whether it's io.on or socket.on, you are registering an event handler. This being the case, you probably don't want to be calling io.on('connection') inside of a route, as you will register a new connection handler every time that route is accessed. This is why you are seeing cumulative messages being logged in the console.

In fact, you probably don't want to mix express routing with socket functions at all, as they are different protocols and will work independent of each other.

// server side

// this should only be called once per connection.
io.on('connection', function (socket) {
  // handle socket protocol stuff.. fetching server data, sending data
  socket.on('fetch bets', function() {
    // get game.players from server       

    // updating other sockets
    io.emit('get_bets', game.players);
  })
})

app.get('/route', function (req, res) {
  // handle http protocol stuff.. fetching server data, sending data

  // send data back to caller
  res.json(data)
})

The same applies to socket.on in your client side. It looks like you're adding a new 'get_bets' event handler everytime you call socketGetBets.

Instead you probably want to register that event handler one single time, likely in componentDidMount or componentWillMount. Also, because a socket connection can be considered global for your application, you can create the connection above your app.

// client side

var socket = io()

var Game = React.createClass({
  getInitialState: function() {
    return {
      bets: null
    }
  },
  componentWillMount: function() {
    var that = this
    socket.on('get_bets', function(data) {
      that.setState({ bets: data })
    })
  }
...

Upvotes: 2

Related Questions