2016-06-04 29 views
0

Ich versuche, socket.io an einen Router übergeben und dann einen Anruf von diesem Router, aber es wird nie ausgegeben. Ich vermute ein Problem in socket.io, das an den Router weitergegeben wird.Socket.io nicht von Router

wie app.js Aussehen:

//app.js 
var express = require('express'); 
var app = express(); 
var server = require('http').Server(app); 
var io = require('socket.io')(server); 

var logger = require('morgan'); 
var weather = require('./routes/weather'); 

server.listen(3000, function() { 
    weather.refreshWeather(); 
    console.log('Listening on http://localhost:3000'); 
}); 

app.use(logger('dev')) 
app.use(express.static(__dirname + '/public')) 

app.use('/', weather.router(io)); 
app.set('view engine', 'jade'); 

module.exports = app; 

wie weather.js Aussehen:

//weather.js 
var express = require('express'); 
var router = express.Router(); 

var returnRouter = function (io) { 
    router.get('/weather', function (req, res, next) { 
     console.log('About to emit!'); 
     io.sockets.emit('weather', { 
      temperature : '12' // this is just a test value 
     }); 
     res.render('weatherpage'); 
     next(); 
    }); 
    return router; 
} 

module.exports = { 
router: returnRouter, // exports variable 
refreshWeather : refreshWeather // exports function 
} 

und schließlich, wie Jade aussieht:

//weatherpage.jade 
doctype html 
html 
    head 
    link(rel='stylesheet', href='/css/index.css') 
    title Dashboard 
    body 
    script(src='/socket.io/socket.io.js') 
    script. 
     var socket = io(); 
     socket.on('weather', function(data){ 
     document.getElementById('weather').innerHTML = data.temperature 
     }); 
+0

Es ist wirklich ein Designfehler, zu versuchen, eine Seite zu aktualisieren, die Sie gerade mit socket.io rendern wollen. Sie rendern eine Vorlage, die Seite ist noch nicht geladen oder über socket.io verbunden. Verwenden Sie keine Timer, um dies zu hacken. Fügen Sie einfach die Anfangsdaten IN die Vorlage selbst ein (deshalb verwenden Sie Vorlagen an erster Stelle (so können Sie Daten in diese einfügen). Verwenden Sie socket.io nicht für den Anfangswert der Temperatur. Sie können socket.io für die Aktualisierung verwenden Temperaturen nach dem Laden der Seite – jfriend00

Antwort

1

Socket.io wird fein genannt . Ihr Problem hier ist, dass das Socket-Ereignis ausgegeben wird und Sie dann die Jade-Vorlage rendern! Das Ereignis ist schon lange vorbei, als die Seite gerendert wurde. Wenn Sie die Seite jedoch bereits gerendert haben, z. B. in einem anderen Browserfenster, werden die anderen Seiten wie erwartet aktualisiert.

Wenn Sie die Wetterdaten beim Rendern der Wetterseitenvorlage haben, erstellen Sie sie einfach normal und hören Sie weiterhin Socket-Ereignisse ab, um die Seite nach der Bereitstellung zu aktualisieren.

Der Routen-Handler, der eine Seite mit einem Socket-Listener versorgt, ist fast nie der Ort, an dem Socket-Ereignisse ausgegeben werden, die auf derselben Seite gerendert werden sollen. Ich nehme an, es macht Sinn, wenn Sie alle Ihre Clients aktualisieren wollen, wenn dieser Endpunkt erreicht wird.

Denken Sie darüber nach, was Sie tun. Wo werden die Temperaturdaten geändert? Du sagst jede Minute. Hier können Sie Ihre Socket-Ereignisse ausgeben. Jede gerenderte (bereits gelieferte) Wetterseite in einem Browser wird aktualisiert.

+0

Ich habe mit Timer-Funktion experimentiert und es funktioniert völlig in Ordnung, solange ich es in app.js, mein Problem hier ist, dass ich nicht die Socket.io in Router funktionieren kann. Ich bin auch erfrischendes Wetter jede Minute und ich möchte es auch auf der Website aktualisieren. Ich habe auch versucht, die res.render vor sockets.emit, aber das Ergebnis ist das gleiche. – Shard

+0

@Shard - Eeeck. Do not Verwenden Sie einen Timer.Das ist völlig die falsche Design-Lösung.Sie hacken, anstatt das Problem auf die richtige Weise zu lösen – jfriend00

+0

@Shard Anstatt Io an jede Funktion, wo Sie wollen, zu übergeben, erstellen Sie einfach Wrapper-Modul-Datei für Websocket und wann immer Sie wollen Nachricht senden e durch Socket rufen Sie einfach senden Sie die Funktion dieser Wrapper-Datei. So indem Sie dies Ihre alle Sockets verwandte Funktion wird in einer Datei sein und es wird auch einfach zu verwalten sein. – Sarju

0

nach den Anweisungen des Benutzers Sarju So dieses Bit auf meine app.js Ich habe

module.exports = function socketEmit(id,data){ 
    io.sockets.emit(id,data); 
} 

und dieses Bit auf meine weather.js

require('../app')('weather', { 
     temperature : temperature 
    }); 

Ich bin mir nicht sicher, ob dies ist der beste oder klügste Weg, es zu tun, aber es hat für mich funktioniert. Wenn jemand einen besseren Vorschlag hat, werde ich das gerne als die richtige Antwort bezeichnen.