Charles Peterson
Charles Peterson

Reputation: 71

Node.js - Socket.io - Express 3

I'm a noob to Node.js and Express :( I'm having an issue with accessing the socket.io object in other modules. I have created a global variable to hold a socket object however as soon as that user closes the connection the connection isn't available anymore. Technically I guess the connection still lives on but I delete it for resource reasons.

Notice below everytime a connection is made we assign that socket to the global variable which is accessible to all other modules.

// App.js
var io = require('socket.io').listen(server); 
var sessionsConnections = {};

io.sockets.on('connection', function (socket) 
{
     global.socket = socket;
     sessionsConnections[socket.id] = socket;
     .....
}

socket.on("disconnect", function() 
{
    delete sessionsConnections[socket.id];
});

// Match.js
     global.socket.emit('lobby:createMatch', data);

If the connection last assigned to the global closes Match.js will be screwed. At this point Match.js is the only module who will ever need that socket.io reference. Match.js has a bunch of exports for handling events, emitting the changes and rendering the view.

Are there any suggestions to how this is handled? Is it possible to instantiate an initial socket connection to live in App.js for the purpose of being a global reference?

Upvotes: 4

Views: 3395

Answers (2)

Brad C
Brad C

Reputation: 720

You might try express.io,

http://express-io.org/

npm install express.io

It works the same as express, except that it has socket.io integration built-in. It also has basic routing, so that it is a little easier to deal with your issue.

Check out this simple example:

app = require('express.io')()
app.http().io()

app.io.route('some-event', function(req) {
    req.io.broadcast('announce', 'someone triggered some-event')
})

app.listen(7076)

You can also do routing with objects, which makes it more like a traditional controller:

app = require('express.io')()
app.http().io()

app.io.route('posts', {
    create: function(req) {
        // create a post
    },
    remove: function(req) {
        // remove a post
    }
})

app.listen(7076)

Hope that helps!

Upvotes: 0

lortabac
lortabac

Reputation: 599

The socket variable in io.sockets.on('connection', function(socket) {...}) is different for each connection.

Since in your code global.socket is always a reference to the socket relative to the last connected client, it is normal that if this client disconnects, this socket will die.

In any case, I don't see any reason to use a global variable. If you need to send a message to a specific client, you can use the socket variable inside the connection callback:

io.sockets.on('connection', function (socket) 
{
  socket.emit('foo', 'bar');
}

If you need to access the sockets in another module, you can export the sessionsConnections object, and access the socket you need by its id:

//In app.js
exports.connections = sessionsConnections;

//In match.js
var app = require('./app.js');
app.connections[clientId].emit('foo', 'bar');

Of course, you need to keep track of the id's somewhere.

Upvotes: 4

Related Questions