Socket.io émettre à partir de contrôleurs Express

Je suis assez nouveau dans Node.js / Express et je l’utilise comme backend pour une application AngularJS. J’ai cherché dans StackOverflow pour résoudre mon problème, mais je n’arrive pas à comprendre comment transférer les suggestions dans mon code.

Mon application fonctionne comme suit:

  • Un processus Scala de longue durée envoie périodiquement les messages de mon journal d’application Node.js. Pour cela, il poste sur une API HTTP.
  • Lorsque le message est reçu, mon application écrit le message du journal à MongoDB.
  • Les messages de journalisation sont ensuite envoyés en temps réel au client Angular.

J’ai un problème avec les modules de Node car je ne vois pas comment faire référence à l’instance de socket dans le contrôleur Express.

Comme vous pouvez le constater, dans server.js, socket.io y est instancié. Cependant, j’aimerais que le contrôleur lui-même, logs.js, puisse émettre à l’aide de l’instance socket.io.

Comment puis-je me référer à io dans le contrôleur? Je ne suis pas sûr de savoir comment passer l’instance io au contrôleur afin de pouvoir émettre des messages?

Voici une partie du code de nœud:

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) }; 

Vous pouvez utiliser un modèle basé sur les fermetures JS standard. L’exportation principale dans logs.js ne sera pas la fonction de contrôleur elle-même, mais une fonction d’usine qui acceptera toutes les dépendances nécessaires et créera le contrôleur:

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

Ensuite, quand vous voulez l’utiliser:

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

Puisque vous configurez vos routes dans un package séparé, vous devez utiliser le même modèle dans routes.jsroutes devrait recevoir le socket à utiliser en tant que paramètre.

Ce modèle fonctionne bien si vous voulez gérer ces choses avec DI ultérieurement, ou tester vos contrôleurs avec des “sockets” fictifs.