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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 16:31:39  来源:igfitidea点击:

ExpressJS - Socket.IO with Route Separation

javascriptnode.jssocket.ioexpress

提问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

查看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 ioobject around. You have a few options, which may or may not be "best" depending on who you ask.

至于四处走动,必须绕过io对象。您有几个选择,可能是也可能不是“最佳”,这取决于您问的是谁。

  • Make ioor appglobal. (some people freak out over globals)
  • Use module.exportsand requirethe object in the other file. (can lead to circular dependency issues if not done properly)
  • 制造ioapp全球。(有些人对全局变量感到害怕)
  • 使用module.exportsrequire另一个文件中的对象。(如果做得不好,可能会导致循环依赖问题)

Passing the ioobject 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/controllercalled 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 将打开一个到服务器的套接字并接收额外的数据。

See more examples here.

在此处查看更多示例。

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' });
    });

});