简体   繁体   English

Socket.io从Express控制器发出

[英]Socket.io emit from Express controllers

I'm quite new to Node.js / Express, and I'm using it as a backend for an AngularJS app. 我是Node.js / Express的新手,我将它用作AngularJS应用程序的后端。 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. 我已经遍布StackOverflow寻求一些关于我的问题的帮助,但我似乎无法弄清楚如何将建议移植到我的代码中。

My application works as follows: 我的申请表如下:

  • A long running Scala process periodically sends my Node.js application log messages. 长时间运行的Scala进程会定期发送我的Node.js应用程序日志消息。 It does this by posting to an HTTP API 它通过发布到HTTP API来实现
  • When the post is received, my application writes the log message to MongoDB 收到帖子后,我的应用程序将日志消息写入MongoDB
  • The log messages are then sent in real time to the Angular client. 然后将日志消息实时发送到Angular客户端。

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. 我遇到Node的模块问题,因为我无法弄清楚如何引用Express控制器中的套接字实例。

As you can see, in server.js, socket.io is instantiated there. 如您所见,在server.js中,socket.io在那里实例化。 However, I would like the controller itself, logs.js, to be able to emit using the socket.io instance. 但是,我希望控制器本身logs.js能够使用socket.io实例发出。

How can I refer to io in the controller? 如何在控制器中引用io? I'm not sure how to pass the io instance to the controller so I can emit messages? 我不知道如何将io实例传递给控制器​​,以便我可以发出消息?

Here is some of the Node code: 以下是一些Node代码:

server.js 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 routes.js

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

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

logs.js 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)
};

You can use a pattern based on standard JS closures. 您可以使用基于标准JS闭包的模式。 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: logs.js的主要导出不是控制器函数本身,而是一个工厂函数,它将接受所有需要的依赖项,并创建控制器:

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. 由于您在单独的包中设置路由,因此必须在routes.js使用相同的模式 - routes应该接收要用作参数的套接字。

This pattern works well if you want to handle those things with DI later, or test your controllers with mock "sockets". 如果您想稍后使用DI处理这些内容,或者使用模拟“套接字”测试控制器,则此模式很有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM