[英]How can I emit events to connected sockets using socket.io from within my Express 4 routes?
這是其他人提出的問題,但由於我的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應用程序中從各種路徑發出事件,而且我不能為我的生活找到正確的方法來獲取對我需要的套接字對象的引用。
示例:當用戶發表評論時,我想向所有連接的用戶發出一個事件,通知他們新的評論。 從我的路由文件( ./server/routes/user.js
),如何訪問我需要發出事件的對象?
這是路徑文件中相關位的框架:
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
以便可以從其他路徑../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 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模塊導出一個方法,讓你傳遞io
對象,然后在routes
模塊中需要並創建io
對象之后,你可以只需調用該方法將io
對象傳遞給routes模塊,它就可以將其保存在本地以備將來使用。
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)
});
這對我有用。 祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.