javascript ExpressJS - 带有路由分离的 Socket.IO
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12566731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ExpressJS - Socket.IO with Route Separation
提问by backdesk
I'm trying to get my head around ExpressJS and Socket.IO. I've got my routes in a separate file which I include from my app.js:
我正在尝试了解 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');
However when I try and emit an event from one of my routes I have no reference to socket.io.
但是,当我尝试从我的一条路线发出事件时,我没有参考 socket.io。
exports.update = function(req, res){
return Item.findById(req.params.id, function(err, item) {
// Do some checks and save.
socket.emit('updated');
}
}
I understand why this might not be available. Rather I don't understand what the best way to get a handle on socket.io is from another file other than app.js. I was looking at this question(see Ricardo's answer) but I'm still not clear. Ideally I would like to avoid doing this:
我明白为什么这可能不可用。相反,我不明白从 app.js 以外的另一个文件获取 socket.io 句柄的最佳方法是什么。我正在看这个问题(见里卡多的回答),但我仍然不清楚。理想情况下,我想避免这样做:
routes = requires("routes/myRoutes")(io);
routes = requires("routes/myRoutes")(io);
采纳答案by Brad C
Check out express.io
It has routing for realtime requests, and a bunch of other useful features.
它具有用于实时请求的路由以及许多其他有用的功能。
app = require('express.io')()
app.http().io()
app.io.route('example', function(req) {
// do something interesting
}))
app.listen(7076)
As far as getting around having to pass the io
object around. You have a few options, which may or may not be "best" depending on who you ask.
至于四处走动,必须绕过io
对象。您有几个选择,可能是也可能不是“最佳”,这取决于您问的是谁。
- Make
io
orapp
global. (some people freak out over globals) - Use
module.exports
andrequire
the object in the other file. (can lead to circular dependency issues if not done properly)
- 制造
io
或app
全球。(有些人对全局变量感到害怕) - 使用
module.exports
和require
另一个文件中的对象。(如果做得不好,可能会导致循环依赖问题)
Passing the io
object is probably the cleanest simplest way, but you do have options.
传递io
对象可能是最简单的方法,但您确实有选择。
回答by Kamagatos
Well you don't really need express.io for that. The easiest solution would be to export a new module and pass it a reference to socket.io instance. So in your app.js you have :
好吧,您实际上并不需要 express.io。最简单的解决方案是导出一个新模块并将其传递给 socket.io 实例的引用。所以在你的 app.js 你有:
var express = require('express'),
...
, server = http.createServer(app)
, io = require('socket.io').listen(server)
, routes = require('./routes/myRoutes');
Now require a new module and pass it the socketio reference. Add this new line (in app.js) to do so :
现在需要一个新模块并将 socketio 引用传递给它。添加此新行(在 app.js 中)以执行此操作:
require('./app/path/to/your/socketio/controller/socketio')(io);
Then create a new file in your path/to/your/socketio/controller
called socketio.js
然后在你path/to/your/socketio/controller
叫的 socketio.js 中创建一个新文件
And finally in the socketio.js file, export your new module :
最后在 socketio.js 文件中,导出你的新模块:
module.exports = function(io) {
io.sockets.on('connection', function (socket) {
socket.on('captain', function(data) {
console.log(data);
socket.emit('america');
});
});
};
And there you go!
你去吧!
回答by Tuong Le
The best way is to use closure. Ex:
最好的方法是使用闭包。前任:
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');
}
}
}
And:
和:
app.post('/your_path', update(io));
回答by Patrick
socket.io doesn't work with routes, it works with sockets.
socket.io 不适用于路由,它适用于套接字。
You add this code to app.js or a separate file which you include in app.js:
您将此代码添加到 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);
}
});
});
Your update route only renders a html document with javascript, containing:
您的更新路线仅使用 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>
So once the page is rendered and complete, the client-javascript will open a socket to the server and receive additional data.
因此,一旦页面呈现并完成,client-javascript 将打开一个到服务器的套接字并接收额外的数据。
Disclaimer: Code written from scratch and not tested.
免责声明:代码从头开始编写,未经测试。
回答by goliardico
I've used the middleware router of Expressjs(I'm using 4.x).
我使用了Expressjs的中间件路由器(我使用的是 4.x)。
In the external route file I put the "next" object:
在外部路由文件中,我放置了“下一个”对象:
module.exports = function(app, settings){
app.post('/something', function(req, res, next) {
...
next();
}
};
And in the main file I write the last route hop inside the io.on('connection'):
在主文件中,我在 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' });
});
});