Javascript 如何从Express 4路由中使用socket.io向连接的套接字发送事件?
这是其他人提出的问题,但我无法从他们给出的答案中获益,因为我有不同的Express设置 我已经在我的服务器上实现了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
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)
insidebin/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
只是