最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Socket.io emit from Express controllers - Stack Overflow

programmeradmin1浏览0评论

I'm quite new to Node.js / Express, and I'm using it as a backend for an AngularJS app. I've looked all over StackOverflow for some help on my problem, but I can't seem to figure out how to port the suggestions to my code.

My application works as follows:

  • A long running Scala process periodically sends my Node.js application log messages. It does this by posting to an HTTP API
  • When the post is received, my application writes the log message to MongoDB
  • The log messages are then sent in real time to the Angular client.

I am having a problem with Node's modules, as I can't figure out how to refer to the socket instance in the Express controller.

As you can see, in server.js, socket.io is instantiated there. However, I would like the controller itself, logs.js, to be able to emit using the socket.io instance.

How can I refer to io in the controller? I'm not sure how to pass the io instance to the controller so I can emit messages?

Here is some of the Node code:

server.js

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

require('./lib/config/express')(app);
require('./lib/routes')(app);

server.listen(config.port, config.ip, function() {
  console.log('Express server listening on %s:%d, in %s mode', config.ip, config.port, app.get('env'));
});

io.set('log level', 1); // reduce logging

io.sockets.on('connection', function(socket) {
  console.log('socket connected');
  socket.emit('message', {
    message: 'You are connected to the backend through the socket!'
  });
});

exports = module.exports = app;

routes.js

var logs = require('./controllers/logs'),
  middleware = require('./middleware');

module.exports = function(app) {
  app.route('/logs')
    .post(logs.create);
}

logs.js

exports.create = function(req, res) {
 // write body of api request to mongodb (this is fine)
 // emit log message to angular with socket.io (how do i refer to the io instance in server.js)
};

I'm quite new to Node.js / Express, and I'm using it as a backend for an AngularJS app. I've looked all over StackOverflow for some help on my problem, but I can't seem to figure out how to port the suggestions to my code.

My application works as follows:

  • A long running Scala process periodically sends my Node.js application log messages. It does this by posting to an HTTP API
  • When the post is received, my application writes the log message to MongoDB
  • The log messages are then sent in real time to the Angular client.

I am having a problem with Node's modules, as I can't figure out how to refer to the socket instance in the Express controller.

As you can see, in server.js, socket.io is instantiated there. However, I would like the controller itself, logs.js, to be able to emit using the socket.io instance.

How can I refer to io in the controller? I'm not sure how to pass the io instance to the controller so I can emit messages?

Here is some of the Node code:

server.js

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

require('./lib/config/express')(app);
require('./lib/routes')(app);

server.listen(config.port, config.ip, function() {
  console.log('Express server listening on %s:%d, in %s mode', config.ip, config.port, app.get('env'));
});

io.set('log level', 1); // reduce logging

io.sockets.on('connection', function(socket) {
  console.log('socket connected');
  socket.emit('message', {
    message: 'You are connected to the backend through the socket!'
  });
});

exports = module.exports = app;

routes.js

var logs = require('./controllers/logs'),
  middleware = require('./middleware');

module.exports = function(app) {
  app.route('/logs')
    .post(logs.create);
}

logs.js

exports.create = function(req, res) {
 // write body of api request to mongodb (this is fine)
 // emit log message to angular with socket.io (how do i refer to the io instance in server.js)
};
Share Improve this question asked May 19, 2014 at 11:00 mousetreemousetree 1051 silver badge7 bronze badges 1
  • For this pattern I used a mix between socket.io and Node.js Events. Check this anwser. – J.C. Gras Commented Aug 30, 2018 at 18:52
Add a ment  | 

1 Answer 1

Reset to default 8

You can use a pattern based on standard JS closures. The main export in logs.js will not be the controller function itself, but a factory function that will accept all needed dependencies, and create the controller:

exports.create = function(socket) {
  return function(req, res) {
    // write body of api request to mongodb
    socket.emit();
  }
}

Then, when you want to use it:

app.route('/logs').post(logs.create(socket));

Since you set up your routes in a separate package, you have to use the same pattern in routes.js - routes should receive the socket to use as a parameter.

This pattern works well if you want to handle those things with DI later, or test your controllers with mock "sockets".

发布评论

评论列表(0)

  1. 暂无评论