Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExpressJS - Socket.IO with Route Separation

I'm trying to get my head around ExpressJS and Socket.IO. I've got my routes in a separate file which I include from my app.js:

var express = require('express')    
  , db = require('./db')
  , mongoose = require('mongoose')
  , models = require('./models/device')
  , http = require('http')
  , path = require('path')
  , app = express()
  , server = http.createServer(app)
  , io = require('socket.io').listen(server)
  , routes = require('./routes/myRoutes');

However when I try and emit an event from one of my routes I have no reference to socket.io.

exports.update = function(req, res){
    return Item.findById(req.params.id, function(err, item) {
       // Do some checks and save.
       socket.emit('updated');
    }
}

I understand why this might not be available. Rather I don't understand what the best way to get a handle on socket.io is from another file other than app.js. I was looking at this question (see Ricardo's answer) but I'm still not clear. Ideally I would like to avoid doing this:

routes = requires("routes/myRoutes")(io);

like image 270
backdesk Avatar asked Sep 24 '12 14:09

backdesk


2 Answers

Well you don't really need express.io for that. The easiest solution would be to export a new module and pass it a reference to socket.io instance. So in your app.js you have :

var express = require('express'),
  ...
  , server = http.createServer(app)
  , io = require('socket.io').listen(server)
  , routes = require('./routes/myRoutes');

Now require a new module and pass it the socketio reference. Add this new line (in app.js) to do so :

require('./app/path/to/your/socketio/controller/socketio')(io);

Then create a new file in your path/to/your/socketio/controller called socketio.js

And finally in the socketio.js file, export your new module :

module.exports = function(io) {

    io.sockets.on('connection', function (socket) {

        socket.on('captain', function(data) {

            console.log(data);

            socket.emit('america');
        });
    });
};

And there you go!

like image 61
Kamagatos Avatar answered Nov 06 '22 02:11

Kamagatos


Check out express.io

It has routing for realtime requests, and a bunch of other useful features.

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

app.io.route('example', function(req) {
    // do something interesting
}))

app.listen(7076)

As far as getting around having to pass the io object around. You have a few options, which may or may not be "best" depending on who you ask.

  • Make io or app global. (some people freak out over globals)
  • Use module.exports and require the object in the other file. (can lead to circular dependency issues if not done properly)

Passing the io object is probably the cleanest simplest way, but you do have options.

like image 5
Brad C Avatar answered Nov 06 '22 03:11

Brad C