Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket.IO + Express framework | Emit/Fire From Express Controller & Router

I need to emit the socket from the server from anywhere on server code, Router/Controller. I checked and some of the threads and Google but nothings works as expected.

app.js

var app = require('express').createServer();
var io = require('socket.io')(app);

require(./router.js)(app)
require(./socket.js)(io)

app.listen(80);

router.js

module.exports = function (app) {
app.use('/test', require(./controller.js));
return app;
};

socket.js

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

controller.js

var express = require('express');
var router = express.Router();

router.get('/about', function(req, res) {
 // I need to emit here

});

module.exports = router;

This is not a extract code I am using. This is an structure how I am using and where I need to call.

like image 677
Şivā SankĂr Avatar asked Apr 28 '16 02:04

Şivā SankĂr


1 Answers

You will be needing io object to emit the event.

Flow 1: passing io as global (quick fix)

app.js

var app = require('express').createServer();
var io = require('socket.io')(app);
global.io = io; //added
require(./socket.js)(io)

app.listen(80)

controller.js

router.get('/about', function(req, res) {
 // I need to emit here
 global.io.emit('news', { hello: 'world' });
});

Notes: As far as passing the io object around. You have a few options, which may or may not be the best.

  • Make io global. (altering global needs care)
  • Use module.exports and require the object in the other files. (can lead to circular dependency issues if not done properly)

Probably, the cleanest way is to pass is as arguments to the controllers, while requiring them in routes.

Flow 2: passing io as arguments

app.js

var app = require('express').createServer();
var io = require('socket.io')(app);

require(./router.js)(app,io);
require(./socket.js)(io);

app.listen(80);

router.js

/*
 * Contains the routing logic
 */
module.exports = function (app,io) {
//passing while creating the instance of controller for the first time.
var controller = require("./controller")(io);

app.get('/test/about',controller.myAction);
};

controller.js

module.exports = function(io){
    var that={};
    /*
     * Private local variable
     * made const so that 
     * one does not alter it by mistake
     * later on.
     */
    const _io = io; 

    that.myAction = function(req,res){

        _io.emit('news', { hello: 'world' });
        res.send('Done');   
    }

    // everything attached to that will be exposed
    // more like making public member functions and properties.
    return that;
}
like image 112
Nivesh Avatar answered Oct 04 '22 19:10

Nivesh