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,根据你的要求,这个选项可能是“最好的”,也可能不是“最好的”。
- 使
io
或app
全球。 (有些人吓坏了全局) - 使用
module.exports
并require
其他文件中的对象。 (如果处理不当,会导致循环依赖问题)
传递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' }); }); });