Как я могу излучать события в подключенные сокеты с помощью socket.io из моих экспресс-маршрутов 4?
это вопрос, который задали другие люди, но я не могу извлечь выгоду из ответов, которые им дали, из-за другой экспресс-настройки, которую я имею.
у меня есть розетка.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
прежде чем есть какой-либо объект ввода-вывода или сокета для передачи.
должен ли я быть в состоянии require('socket.io')
и использовать его как-то выделяют на все подключенные сокеты?
есть ли разумный способ сохранить подключенное розетки на ../routes/socket.js
так его можно требовать и испускать к от других маршрутов?
кто-нибудь может направить меня в правильном направлении?
4 ответов
я смог в конечном итоге заставить вещи работать, используя этот пример: 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
объект отдельно, верните правильный объект, затем используйте io.attach(server)
внутри bin/www
чтобы запустить его в нужной точке.
надеюсь, это поможет кому-то еще следовать по моим стопам.
Я думаю, что вы запутались с понятиями. Розетка.IO lib использует или эмулирует websocket (двунаправленный сокет) с клиентом и не имеет отношения к маршрутам.
вы можете отправить уведомление всем сокетам, используя объект ввода-вывода:
io.emit('message_to_all', true);
вы должны массив на io.розетки, со всеми розетками.
вы можете использовать пространства имен или комнаты, я рекомендую вам узнать документация:
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);
о последнем вопросе редактирования:
вы можете отправить объект ввода-вывода в запрос или ответ объекта на маршруты, используя API Express midleware:
например:
#!/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
объект, созданный в первом модуле. Обычным способом поделиться этим с вашим модулем с вашим modeule маршрутов было бы экспортировать метод из модуля routes, который позволяет вам передать его io
объект, а затем после того как Вы необходимые в routes
модуль и создал
Я сделал новый файл 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)
});
это работает для меня. Удачи!