express.js 4 and sockets with express router
One option is to pass it in to req object.
app.js:
var express = require('express');var path = require('path');var logger = require('morgan');var api = require('./routes/api');var app = express();var io = require('socket.io').listen(app.listen(3000));app.use(logger('dev'));app.use(express.static(path.join(__dirname, 'public')));io.sockets.on('connection', function (socket) { console.log('client connect'); socket.on('echo', function (data) { io.sockets.emit('message', data); });});// Make io accessible to our routerapp.use(function(req,res,next){ req.io = io; next();});app.use('/api', api);// error handlers omittedmodule.exports = app;
./routes/api.js:
var express = require('express');var router = express.Router();router.put('/foo', function(req, res) { /* do stuff to update the foo resource ... */ // now broadcast the updated foo.. req.io.sockets.emit('update', foo); });module.exports = router;
I've modified your files a little bit, may you check if it works?
You can pass the io you've defined to your routes like below;
require('./routes/api')(app,io);
I didn't test the Socket.IO parts but there is no syntax error and routes also working.
server.js file:
var express = require('express');var app = express();var path = require('path');var logger = require('morgan');var io = require('socket.io').listen(app.listen(3000)); app.use(logger('dev'));app.use(express.static(path.join(__dirname, 'public'))); io.sockets.on('connection', function (socket) { console.log('client connect'); socket.on('echo', function (data) { io.sockets.emit('message', data); });});require('./routes/api')(app,io); console.log("Server listening at port 3000");
api.js:
module.exports = function(app,io) {app.put('/foo', function(req, res) { /* do stuff to update the foo resource ... */ // now broadcast the updated foo.. console.log("PUT OK!"); io.sockets.emit('update'); // how? res.json({result: "update sent over IO"}); });}
Supposing you want to access the SocketIO from anywhere in your application, not just in the router, you could create a singleton for it. This is what works for me:
//socket-singletion.jsvar socket = require('socket.io');var SocketSingleton = (function() { this.io = null; this.configure = function(server) { this.io = socket(server); } return this;})();module.exports = SocketSingleton;
Then, you need to configure it using your server:
//server config filevar SocketSingleton = require('./socket-singleton');var http = require('http');var server = http.createServer(app);SocketSingleton.configure(server); // <--hereserver.listen('3000');
Finally, use it wherever you want:
//router/index.jsvar express = require('express');var router = express.Router();var SocketSingleton = require('../socket-singleton');/* GET home page. */router.get('/', function(req, res, next) { setTimeout(function(){ SocketSingleton.io.emit('news', {msg: 'success!'}); }, 3000); res.render('index', { title: 'Express' });});module.exports = router;