ExpressJS – 具有路由分离的Socket.IO

我试图让我的头ExpressJS和Socket.IO。 我有一个单独的文件,我从我的app.js包括我的路线:

var express = require('express') , db = require('./db') , mongoose = require('mongoose') , models = require('./models/device') , http = require('http') , path = require('path') , app = express() , server = http.createServer(app) , io = require('socket.io').listen(server) , routes = require('./routes/myRoutes'); 

但是,当我尝试从我的一个路由发出一个事件,我没有参考socket.io。

 exports.update = function(req, res){ return Item.findById(req.params.id, function(err, item) { // Do some checks and save. socket.emit('updated'); } } 

我明白为什么这可能不可用。 相反,我不明白什么是最好的方式来处理socket.io来自另一个文件,而不是app.js. 我正在看这个问题 (看里卡多的回答),但我还不清楚。 理想情况下,我想避免这样做:

要求(“routes / myRoutes”)(io);

退房express.io

它具有实时请求路由,以及一些其他有用的function。

 app = require('express.io')() app.http().io() app.io.route('example', function(req) { // do something interesting })) app.listen(7076) 

至于绕过必须通过io对象。 你有几个select,根据你的要求,这个选项可能是“最好的”,也可能不是“最好的”。

  • 使ioapp全球。 (有些人吓坏了全局)
  • 使用module.exportsrequire其他文件中的对象。 (如果处理不当,会导致循环依赖问题)

传递io对象可能是最简单的方法,但是你有select。

那么你真的不需要express.io。 最简单的解决scheme是导出一个新的模块,并将其传递给socket.io实例。 所以在你的app.js中你有:

 var express = require('express'), ... , server = http.createServer(app) , io = require('socket.io').listen(server) , routes = require('./routes/myRoutes'); 

现在需要一个新的模块并将其传递给socketio引用。 添加这个新行(在app.js中)是这样做的:

 require('./app/path/to/your/socketio/controller/socketio')(io); 

然后在你的path/to/your/socketio/controller创build一个名为socketio.js的新文件

最后在socketio.js文件中,导出你的新模块:

 module.exports = function(io) { io.sockets.on('connection', function (socket) { socket.on('captain', function(data) { console.log(data); socket.emit('america'); }); }); }; 

你去了!

socket.io不适用于路由,它可以与套接字一起使用。

您将此代码添加到app.js或包含在app.js中的单独文件中:

 io.sockets.on('connection', function (socket) { socket.on('update', function (your_id) { Item.findById(your_id, function(err, item) { socket.emit('send_update', item); } }); }); 

你的更新路由只呈现一个带有javascript的html文档,其中包含:

 <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://localhost'); socket.emit('update', { your_id: '1' }); socket.on('send_update', function (data) { console.log(data); }); </script> 

所以一旦页面呈现完成,client-javascript将打开一个到服务器的套接字并接收额外的数据。

看到更多的例子。

免责声明:代码从头开始编写,未经testing。

最好的方法是使用闭包。 例如:

 exports.update = function(socket){ return function(req, res) { //In here now you can have the reference to the socket io Item.findById(req.params.id, function(err, item) { // Do some checks and save. socket.emit('updated'); } } } 

和:

 app.post('/your_path', update(io)); 

我使用了Expressjs的中间件路由器(我正在使用4.x)。

在外部路由文件中,我把“下一个”对象:

 module.exports = function(app, settings){ app.post('/something', function(req, res, next) { ... next(); } }; 

在主文件中,我写了io.on('connection')中的最后一个路由跳转:

 io.on('connection', function (socket) { // Final route for middlewares who need to interact with socket.io app.post('/something', function (req, res, next) { socket.emit('event', { result: 'ok' }); }); });