Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从Express 4路由中使用socket.io向连接的套接字发送事件?_Javascript_Node.js_Express_Socket.io 1.0 - Fatal编程技术网

Javascript 如何从Express 4路由中使用socket.io向连接的套接字发送事件?

Javascript 如何从Express 4路由中使用socket.io向连接的套接字发送事件?,javascript,node.js,express,socket.io-1.0,Javascript,Node.js,Express,Socket.io 1.0,这是其他人提出的问题,但我无法从他们给出的答案中获益,因为我有不同的Express设置 我已经在我的服务器上实现了socket.io并以一种简单的方式工作。这就是它的工作原理: 在bin/www中: #!/usr/bin/env node var debug = require('debug')('gokibitz'); var app = require('../../server'); app.set('port', process.env.PORT || 3000); var serv

这是其他人提出的问题,但我无法从他们给出的答案中获益,因为我有不同的Express设置

我已经在我的服务器上实现了socket.io并以一种简单的方式工作。这就是它的工作原理:

bin/www
中:

#!/usr/bin/env node
var debug = require('debug')('gokibitz');
var app = require('../../server');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
    debug('Express server listening on port ' + server.address().port);
});

var io = require('socket.io').listen(server);

io.on('connection', require('../routes/socket.js'));
所有我的路线和其他Express设置都在
。/../server.js

var routes = require('./server/routes/index');
var user = require('./server/routes/user');
...

app.use('/', routes);
app.use('/api/user/', user);
...
app.use('*', routes);
然后在
。/routes/socket.js
中,我得到了这个样板文件:

module.exports = function (socket) {
    socket.emit('send:news', { hello: 'world' });

    setInterval(function () {
        socket.emit('send:time', {
            time: (new Date()).toString()
        });
    }, 1000);

    return socket;
};
我想补充一句,这工作得很好。但是现在我希望能够在我非常普通的Express应用程序中从各种路径发出事件,而我一生都无法找到获取所需套接字对象引用的正确方法

示例:当用户发表评论时,我想向所有连接的用户发送一个事件,通知他们新的评论。从我的routes文件(
/server/routes/user.js
)中,我如何访问我需要发出事件的对象

以下是路由文件中相关位的骨架:

var express = require('express');
var router = express.Router();

router.post('/', function (req, res) {
  ...
});

module.exports = router;
我唯一可以访问它的地方是
。/routes/socket.js
文件,它是无用的

在有任何io或套接字对象传入之前,所有路由都在
app.js
中设置

我应该能够
要求('socket.io')
并以某种方式将其发送到所有连接的套接字吗

是否有一种合理的方法将连接的套接字存储在
。/routes/socket.js
上,以便从其他路由请求并发送到其他路由


谁能把我引向正确的方向吗?

我想你对这些概念感到困惑。io库使用或模拟客户端的websocket(双向套接字),与路由无关

您可以使用io对象向所有套接字发送通知:

io.emit('message_to_all', true);
您必须在io.sockets上创建一个数组,其中包含所有套接字

我建议您使用名称空间或文件室来学习文档:

添加一些内容:

如果要向同一路由中的所有人发送消息,可以加入具有相同路径名称的频道

例如,在客户端:

var socket = io(window.location.href); // Or route..
和服务器:

var nsp = io.of('/the/specific/route');
nsp.on('connection', function(socket){
  // ...
});
nsp.emit('message_to_all_in_route', data);
关于最后一个问题编辑:

您可以使用Express midleware API将请求或响应对象中的io对象发送到路由:

例如:

#!/usr/bin/env node
var debug = require('debug')('gokibitz');
var app = require('../../server');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
    debug('Express server listening on port ' + server.address().port);
});

var io = require('socket.io').listen(server);

app.use(function (req, res, next) {
  res.io = io;
  next();
});

io.on('connection', require('../routes/socket.js'));
在路线上:

route.post('/post/:id/comments', function (req, res) {

   // Do your logic

  var postio = res.io.of('/post/' + req.params.id);
  postio.emit('new_comment', commentData);

});

正如我在评论中所说,您可以向所有连接的客户发送:

io.emit(msg, data);
这将需要访问您在第一个模块中创建的
io
对象。在routes modeule中与您的模块共享的通常方式是从routes模块导出一个方法,该方法允许您传递
io
对象,然后在
routes
模块中进行必要的操作并创建
io
对象之后,您只需调用该方法将
io
对象传递给routes模块,它就可以将其保存在本地以备将来使用


io
只是一个共享对象,就像
app
对象一样。如果您希望某个模块能够使用共享对象,通常的方法是调用该模块中的某个方法,与该模块共享它可以使用的一些对象。

我最终能够使用此示例使事情正常工作:

我创建了一个名为
server/io.js
的新文件:

var io = require('socket.io')();

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

module.exports = io;
var express = require('express');
var app = express();
var http = require('http').createServer(app);
var port = process.env.PORT || 3000;

var io = require('./sockets').socketServer(http);
http.listen(port, function () {
    console.log('SERVER RUNNING.. PORT: ' + port)
});
然后我将
server/bin/www
更新为:

#!/usr/bin/env node
var debug = require('debug')('gokibitz');
var app = require('../../server');
var io = require('../io');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
    debug('Express server listening on port ' + server.address().port);
});

io.attach(server);
然后,在我的路线中,我使用:

var io = require('../io');
...
io.emit(...);
至少对我来说,缺少的是能够单独创建
io
对象,返回正确的对象,然后使用
io.attach(server)
inside
bin/www
在正确的点启动它


希望这将有助于其他人追随我的脚步。

我在该文件中创建了一个新文件
sockets.js

var socketio = require('socket.io');
var io;

module.exports = {
socketServer: function (app) {
    io = socketio.listen(app);

    io.on('connection', function (socket) {

        console.log(Object.keys(users));
        socket.on('message', function (data) {
            io.emit('updateChat', 'Hello World!')
        });
    });
  }
}
在我的
app.js
中:

var io = require('socket.io')();

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

module.exports = io;
var express = require('express');
var app = express();
var http = require('http').createServer(app);
var port = process.env.PORT || 3000;

var io = require('./sockets').socketServer(http);
http.listen(port, function () {
    console.log('SERVER RUNNING.. PORT: ' + port)
});

这对我有用。祝你好运

您是否尝试从路由向所有连接的用户广播消息?或者只发送给在路由上发出请求的用户?你想从你的路线上派谁<代码>io.emit(消息,数据)将发送到所有连接的客户端。如果您是从另一个模块执行此操作,则必须将
io
变量共享到该另一个模块。我正在尝试从路由向所有连接的用户广播消息。示例:用户向帖子添加注释。我想向所有用户广播一个(名称空间)事件,这样任何查看该帖子的人都可以收听更新,并用新评论刷新他们的页面。我知道我需要共享io对象,但我正在努力找到正确的方法来使用我的设置。在最后一种情况下,您需要创建一个单例来返回该对象或使其全局化。使用
io
对象似乎很简单,但是我不知道如何正确地共享
io
对象,以便我在不同文件中的路由可以使用它。通过名称空间(如我的回复中添加的示例),您可以使用io.of方法定义此路由。我想我们在谈论彼此。我已经更新了我的问题,以澄清我是如何努力访问我需要发出事件的对象的。您关于使用中间件的编辑看起来正是我所需要的:让我确保我可以让它工作。当中间件添加到
应用程序时,它似乎没有被调用:您确定它在在路线之后和
应用程序之后添加。收听
?也许我遗漏了什么。恐怕你高估了我从你的一般建议中获益的能力。我已经用我的一个路由文件的结构更新了我的问题:如何修改它以访问
bin/www
中的
io
对象?我尝试添加
module.export.io=io
bin/www
var io=require('../bin/www')。io
到我的路线,但是
io
只是