11

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.

Şivā SankĂr
  • 1,966
  • 1
  • 18
  • 34
  • It does not look like your router s connected to your server instance at all. – jfriend00 Apr 28 '16 at 02:18
  • This is an sample structure of my code. my router is connecting. Is there way to emit from controller. I will revise my code – Şivā SankĂr Apr 28 '16 at 02:20
  • 1
    If you just want to be able to do `io.emit()` from other modules, then just pass `io` to them in their constructor. Or, make a method on some other module that you can retrieve the `io` variable by `require()` that module and then call a method on it to fetch `io`. – jfriend00 Apr 28 '16 at 02:21
  • @jfriend00, I will try.. – Şivā SankĂr Apr 28 '16 at 02:24
  • I think did we have a function io.emit() on scoket.io. I will find only io.sockets.emit(). Can we pls provide me the doc link. – Şivā SankĂr Apr 28 '16 at 02:25
  • Official doc is not deep enough http://socket.io/docs/ – Şivā SankĂr Apr 28 '16 at 02:26
  • `io.emit()` sends to all connected sockets. Doc is [here](http://socket.io/docs/server-api/#server#emit). It's the same as `io.sockets.emit()`. Yes, socket.io doc is pretty weak. – jfriend00 Apr 28 '16 at 02:28
  • @jfriend00 I revised my code structure – Şivā SankĂr Apr 28 '16 at 02:34
  • I used a mix between **socket.io** and Node.js **Events**. Check [this anwser](https://stackoverflow.com/questions/34596689/using-socket-io-in-express-js-project/52103434#52103434). – J.C. Gras Aug 30 '18 at 18:51

1 Answers1

23

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;
}
Nivesh
  • 2,573
  • 1
  • 20
  • 28