如何使用我的Express 4路由中的socket.io将事件发送到连接的套接字?
这是其他人问的问题,但由于我的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'));
我所有的路线和其他快速安装在../../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
),我怎样才能访问我需要发射事件的对象?
以下是来自path文件的相关位的骨架:
var express = require('express'); var router = express.Router(); router.post('/', function (req, res) { ... }); module.exports = router;
我可以访问的唯一地方是../routes/socket.js
文件,这是没用的。
在有任何io或socket对象传入之前,所有路由都设置在app.js
中。
我应该能够require('socket.io')
并以某种方式使用它来发射到所有连接的套接字?
有没有一个明智的方法来存储连接的插口../routes/socket.js
所以它可以被要求和发射到其他路线?
任何人都可以把我引向正确的方向吗?
我能够最终使用这个例子工作: https : //github.com/expressjs/generator/issues/45#issuecomment-53719435
我创build了一个名为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(...);
对我来说,至less缺less的一块是能够单独创buildio
对象,返回正确的对象,然后使用bin/www
io.attach(server)
在正确的位置启动它。
希望这会帮助别人追随我的脚步。
我认为你对这些概念感到困惑。 socket.io lib使用或模拟一个websocket(双向套接字)与客户端,并且没有关系与路由。
您可以使用io对象向所有套接字发送通知:
io.emit('message_to_all', true);
你必须在io.sockets上使用所有套接字。
你可以使用命名空间或房间,我build议你学习文档:
http://socket.io/docs/rooms-and-namespaces/#
添点什么:
如果要发送消息给同一路由中的所有人,则可以join到具有相同path名的通道中。
例如,在客户端:
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);
这将需要访问您在第一个模块中创build的io
对象。 通常的方式与你的模块与你的路由模式共享,将导出一个方法从路由模块,让你传递它的io
对象,然后你需要在routes
模块和创build的io
对象,你可以只需调用该方法将io
对象传递给路由模块,并将其保存在本地以供将来使用。
io
只是一个像app
对象一样的共享对象。 如果你想要一个模块能够使用一个共享对象,通常的方法是,你可以调用该模块中的某个方法来与它共享一些可以使用的对象。
我在该文件中创build了一个新的文件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) });
这是为我工作。 祝你好运!