2016-04-28 20 views
2

Ich muss den Socket vom Server von irgendwo auf Server-Code, Router/Controller ausgeben. Ich habe überprüft und einige der Threads und Google aber nichts funktioniert wie erwartet.Socket.IO + Express-Framework | Emit/Fire Von Express Controller & Router

app.js

var app = require('express').createServer(); 
var io = require('socket.io')(app); 

require(./router.js)(app) 
require(./socket.js)(io) 

app.listen(80); 

router.js

module.exports = function (app) { 
app.use('/test', require(./controller.js)); 
return app; 
}; 

socket.js

io.on('connection', function (socket) { 
    socket.emit('news', { hello: 'world' }); 
    socket.on('my other event', function (data) { 
    console.log(data); 
    }); 
}); 

controller.js

var express = require('express'); 
var router = express.Router(); 

router.get('/about', function(req, res) { 
// I need to emit here 

}); 

module.exports = router; 

Dies ist kein Extrakt Code ich verwende. Dies ist eine Struktur, wie ich benutze und wo ich anrufen muss.

+0

Es sieht nicht wie Ihr Router s aktive Verbindung mit der Server-Instanz alle an. – jfriend00

+0

Dies ist eine Beispielstruktur meines Codes.Mein Router verbindet sich. Gibt es eine Möglichkeit, vom Controller zu emittieren. Ich werde meinen Code überarbeiten –

+1

Wenn Sie nur 'io.emit()' von anderen Modulen machen wollen, dann übergeben Sie einfach 'io' an sie in ihrem Konstruktor. Oder machen Sie eine Methode auf einem anderen Modul, das Sie die 'io' Variable durch' require() 'das Modul abrufen können und dann eine Methode aufrufen, um' io' zu holen. – jfriend00

Antwort

3

Sie benötigen das Objekt io, um das Ereignis auszulösen.

Durchfluss 1:vorbei io als global (quick fix)

app.js

var app = require('express').createServer(); 
var io = require('socket.io')(app); 
global.io = io; //added 
require(./socket.js)(io) 

app.listen(80) 

controller.js

router.get('/about', function(req, res) { 
// I need to emit here 
global.io.emit('news', { hello: 'world' }); 
}); 

Hinweise: Soweit das io-Objekt vorbei. Sie haben ein paar Optionen, die vielleicht die beste sein können oder nicht.

  • Machen Sie io global. (Ändern der globalen Bedarfspflege)
  • Verwenden Sie module.exports und fordern Sie das Objekt in den anderen Dateien an. (Kann auf zirkuläre Abhängigkeit Problemen führen, wenn nicht richtig gemacht)

Probably, the cleanest way is to pass is as arguments to the controllers, while requiring them in routes.

Flow 2:vorbei io als Argumente

app.js

var app = require('express').createServer(); 
var io = require('socket.io')(app); 

require(./router.js)(app,io); 
require(./socket.js)(io); 

app.listen(80); 

router .js

/* 
* Contains the routing logic 
*/ 
module.exports = function (app,io) { 
//passing while creating the instance of controller for the first time. 
var controller = require("./controller")(io); 

app.get('/test/about',controller.myAction); 
}; 

controller.js

module.exports = function(io){ 
    var that={}; 
    /* 
    * Private local variable 
    * made const so that 
    * one does not alter it by mistake 
    * later on. 
    */ 
    const _io = io; 

    that.myAction = function(req,res){ 

     _io.emit('news', { hello: 'world' }); 
     res.send('Done'); 
    } 

    // everything attached to that will be exposed 
    // more like making public member functions and properties. 
    return that; 
} 
+0

Lassen Sie mich dies versuchen und Sie wissen lassen –

+0

@SivaSankar - Es ist eine schlechte Praxis, eine globale dafür zu verwenden. Es zerstört die Modularität Ihres Codes und schafft eine Möglichkeit für Namenskonflikte. Besser, es an die Module zu übergeben, die es brauchen. – jfriend00

+0

Ja, das kannst du auch. Es ist nur eine schnelle Arbeit. Aber für Namenskonflikte kann man immer verwenden. global._io = io Art von Dingen. – Nivesh