如何使用 Express 4 路由中的 socket.io 向连接的套接字发出事件
How can I emit events to connected sockets using socket.io from within my Express 4 routes?
其他人问过的问题,但由于我的快速设置不同,我无法从他们给出的答案中受益。
我已经实现了 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'));
我所有的路线和其他快递设置都在../../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 应用程序中从各种路由发出事件,而我一生都无法找到正确的方法来获取对我需要的套接字对象的引用。
示例:当用户发表评论时,我想向所有连接的用户发出一个事件,通知他们新评论。从我的路由文件 ( ./server/routes/user.js
),如何访问发出事件所需的对象?
下面是路由文件中相关位的框架:
var express = require('express');
var router = express.Router();
router.post('/', function (req, res) {
...
});
module.exports = router;
我唯一可以访问它的地方是在../routes/socket.js
文件中,这是无用的。
所有路由都设置在app.js
中,然后再传入任何 io 或套接字对象。
我应该能够require('socket.io')
并以某种方式使用它来发射到所有连接的插座吗?
有没有一种明智的方法可以将连接的套接字存储在../routes/socket.js
上,以便可以从其他路由需要和发出它?
谁能引导我走向正确的方向?
我最终能够使用以下示例使事情正常工作:https://github.com/expressjs/generator/issues/45#issuecomment-53719435
我创建了一个名为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;
然后我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
对象,返回正确的对象,然后在bin/www
中使用io.attach(server)
在正确的点启动它。
希望这能帮助其他人追随我的脚步。
我认为你对这些概念感到困惑。socket.io lib 与客户端使用或模拟 websocket(双向套接字),与路由没有关系。
您可以使用 io 对象向所有套接字发送通知:
io.emit('message_to_all', true);
你必须在io.sockets上有一个数组,所有套接字。
您可以使用命名空间或房间来,我建议您学习文档:
http://socket.io/docs/rooms-and-namespaces/#
添加一些内容:
如果要向同一路由中的所有人发送消息,可以加入具有相同路径名称的频道。
例如,在客户端中:
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 中间件 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
对象。 与路由模式的模块共享它的常用方法是从路由模块导出一个方法,该方法允许您将io
对象传递给它,然后在routes
模块中需要并创建io
对象后,您只需调用该方法将io
对象传递给路由模块,它可以将其保存在本地以供将来使用。
io
只是一个共享对象,就像app
对象一样。 如果希望模块能够使用共享对象,通常的方法是调用该模块中的某个方法,以与其共享一些对象,然后可以使用这些对象。
我在该文件中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 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)
});
这对我有用。祝你好运!
- 在node.js中写入ECONNRESET错误和套接字连接检查
- 如何通过网络套接字连接到树莓派上的Mosquitto经纪人
- Will my'新对象'在套接字断开连接时被垃圾收集
- 将服务器托管的Web应用程序连接到本地Web套接字
- 如何使用套接字将node.js与ada连接起来
- 如何正确地通过angularjs服务连接到套接字
- 套接字发生了什么's在'断开连接'事件(服务器端)
- 是否自动更新套接字连接数据?socket.io
- '套接字连接错误'在Aptana 3上调试PHP/JS时
- 套接字IO未连接到正确的服务器
- NodeJs 套接字连接问题
- 节点网络套接字:1006远程对等方在谷歌Chrome上丢弃的连接
- 套接字连接用户在 swift 中多次触发
- 如何使用 Express 4 路由中的 socket.io 向连接的套接字发出事件
- 套接字 IO 未使用 swift 连接到服务器
- 套接字断开连接不起作用
- NodeJS 套接字连接不起作用
- 套接字发出 重新连接套接字后不触发
- 在连接时连接套接字房间
- 保持对每个用户连接套接字的引用