2014-05-19 15 views
6

Jestem całkiem nowy dla Node.js/Express i używam go jako zaplecza dla aplikacji AngularJS. Przeglądałem cały StackOverflow, aby uzyskać pomoc dotyczącą mojego problemu, ale nie potrafię wymyślić, jak przenieść sugestie do mojego kodu.Socket.io emitują z kontrolerów Express

Moja aplikacja działa w następujący sposób:

  • długi uruchomiony proces Scala okresowo wysyła swoje komunikaty dziennika aplikacji node.js. Robi to, publikując do interfejsu API HTTP
  • Po otrzymaniu posta moja aplikacja zapisuje wiadomość dziennika w MongoDB
  • . Wiadomości dziennika są następnie przesyłane w czasie rzeczywistym do klienta Angular.

Mam problem z modułami Node, ponieważ nie mogę dowiedzieć się, jak odwołać się do instancji gniazda w kontrolerze Express.

Jak widać, w serwerze server.js jest tam tworzony plik socket.io. Jednak chciałbym, aby sam kontroler, logs.js, mógł emitować przy użyciu instancji socket.io.

Jak mogę odnieść się do sterownika io io? Nie wiem, jak przekazać instancję io do kontrolera, aby móc emitować wiadomości?

Oto kod węzła:

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

Odpowiedz

7

Można użyć wzoru opartego na standardowych zamknięciach JS. Głównym eksport w logs.js nie będzie sama funkcja regulatora, ale funkcja fabryka, która będzie akceptować wszystkie potrzebne zależności i stworzyć kontroler:

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

Potem, gdy chcesz go używać:

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

Od skonfigurowania tras w oddzielnym pakiecie, musisz użyć tego samego wzorca w routes.js - routes powinien otrzymać gniazdo do użycia jako parametr.

Ten wzór działa dobrze, jeśli chcesz sobie z nimi poradzić z DI później lub przetestować kontrolery z fałszywymi "gniazdami".

+0

Dzięki, jesteś moim bohaterem! – mousetree

+0

Jak zdefiniować gniazdo w routes.js, aby użyć go na trasie, jak pokazano powyżej? –

+0

@CoreyQuillen: oto przykład mojego routes.js - https://gist.github.com/mousetree/7585c9d108cfc006a582 – mousetree