2014-05-19 23 views
6

Sono abbastanza nuovo su Node.js/Express e lo sto utilizzando come backend per un'app AngularJS. Ho cercato su StackOverflow per qualche aiuto sul mio problema, ma non riesco a capire come portare i suggerimenti sul mio codice.Socket.io emette dai controller Express

La mia applicazione funziona come segue:

  • Un processo Scala lunga in esecuzione invia periodicamente i miei Node.JS messaggi di log dell'applicazione. Lo fa pubblicando su un'API HTTP
  • Quando il post viene ricevuto, la mia applicazione scrive il messaggio di log su MongoDB
  • I messaggi di log vengono quindi inviati in tempo reale al client Angular.

Sto riscontrando un problema con i moduli di Node, poiché non riesco a capire come fare riferimento all'istanza socket nel controller Express.

Come si può vedere, in server.js viene istanziato socket.io. Tuttavia, vorrei che il controller stesso, logs.js, fosse in grado di emettere usando l'istanza socket.io.

Come posso fare riferimento a io nel controller? Non sono sicuro di come passare l'istanza io al controller in modo da poter emettere i messaggi?

Ecco il codice Node:

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

risposta

7

È possibile utilizzare un modello basato su chiusure JS standard. Il principale prodotto di esportazione in logs.js non sarà la funzione di controller stesso, ma una funzione factory che accetterà tutte le dipendenze necessarie, e creare il controllore:

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

Poi, quando si desidera utilizzarlo:

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

Poiché si impostano i percorsi in un pacchetto separato, è necessario utilizzare lo stesso modello in routes.js - routes dovrebbe ricevere il socket da utilizzare come parametro.

Questo modello funziona bene se si desidera gestire tali elementi con DI in un secondo momento o testare i controller con "prese" fittizie.

+0

Grazie, sei il mio eroe! – mousetree

+0

Come si definisce il socket in routes.js per utilizzarlo nel percorso come illustrato sopra? –

+0

@CoreyQuillen: ecco un esempio dei miei routes.js - https://gist.github.com/mousetree/7585c9d108cfc006a582 – mousetree