使用Express 4模块化Socket.io

我试图模块化我的应用程序文件,我有问题与Socket.io 。 我想在我的routes.js使用io。 像这样的东西:

 var router = require('express').Router(); var io = require('./sockets/my-io'); router.get('/', function(req, res) { io.emit('request-detected'); }); module.exports = router; 

但我不能这样做,因为socket.io需要应用程序服务器,而当我位于routes.js文件中时,应用程序服务器不在侦听或正在导出。

你能给我一个解决scheme,或任何其他方法来解决这个问题吗?

这是我的,如果可能的话,我想保持文件结构

app.js

 var app = require('express')(); var routes = require('./routes'); /* ... */ app.use('/contacts', routes); module.exports = app; 

斌/ WWW

 #!/usr/bin/env node var app = require('../wallet'); var server = app.listen(port, function() { debug('Express is listening o port ' + port); }); 

routes.js

 var router = require('express').Router(); router.get('/', function(req, res) { console.log('hey'); }); module.exports = router; 

您可以通过将iovariables传递给路由模块来完成。

斌/ WWW

 #!/usr/bin/env node var app = require('./app'); var server = app.listen(3000, function() { console.log('Express is listening on port 3000'); }); // start the server var socket = require('./socket')(server); // require socket.io code var routes = require('./routes')(socket); // require routes app.use('/', routes); 

app.js

 var express = require('express'); var app = express(); app.use(express.static(__dirname + '/public')); app.set('views engine', 'ejs'); app.set('views', __dirname + '/'); module.exports = app; 

socket.js

 var socketio = require('socket.io'); function init(server) { var io = socketio(server); io.on('connection', function (socket) { console.log("socket connected"); socket.on('newEvent', function (data) { console.log(data); }); }); return io; } module.exports = init; 

routes.js

 var express = require('express'); var route = express.Router(); function init(io) { route.get('/', function (req, res) { res.render('index.ejs', {}); setTimeout(function() {io.emit('newEvent', {message: "Hi from the server"})}, 2000); }); return route; } module.exports = init; 

上面的代码为我工作。 不过,我不确定你为什么要这样做。

在路由器内部,你仍然可以完全控制你想通过html发送给用户的内容,所以你可以直接将数据添加到html。 socket.io的思想是,你可以在客户端和返回之间发送数据,一旦他加载了html,并build立一个连接到你的服务器与socket.io。

正如你可以在routes.js看到的,我必须添加超时发射。 这是因为套接字事件将在浏览器重新加载页面之前发出。 在我的情况下,浏览器logging事件,然后立即刷新,丢失刚刚发送的数据。

另一个问题是,你不知道请求页面的客户端的套接字,因为他还没有连接。 这意味着调用io.emit()将把事件发送到所有连接的套接字。

正如我所说,这实际上取决于你想要做什么。

编辑:

而不是更新您的联系人使用Ajax,你可以用socket.io来做到这一点。

socket.js

 var socketio = require('socket.io'); function init(server) { var io = socketio(server); io.on('connection', function (socket) { console.log("socket connected"); socket.on('newContact', function (data, callback) { // add data.contactName to db // after adding something, you use the callback to // send the added data back to the client // callback(newContact); }); }); return io; } module.exports = init; 

的index.html

 <script type="text/javascript" > var socket = io(); // call this emit when the user wants to add a contact socket.emit('newContact', {contactName: name}, function(newContact) { // here you will get the result from the server and you can // update the html with jquery for example }); </script> 

如果我正确理解你的问题,也许你可以尝试这种方式。

在您的routes.js文件中

 var app = require('./app'); var server = require('http').createServer(app); var io = require('./sockets/my-io')(server); var route = app.Router(); 

在你的app.js文件中

 var port = process.env.PORT || 3000; app.listen(port,function(){ console.log('server on port ' + port) })