Использовать socket.io в контроллерах

17

Мне нужен только socket.io для отправки сообщений клиентам, если новый объект вставляется в базу данных. Поэтому моя идея состояла в том, чтобы выпустить сообщение непосредственно из метода вставки моего контроллера. В моем файле server.js iam создает объект socket.io и пытаюсь сделать его доступным для других модулей:

var server = require('http').createServer(app);
var io = require('socket.io').listen(server);

//make socket io accessible for other modules
module.exports.io = io;

В моем контроллере я пытаюсь использовать socket.io следующим образом:

var io = require('../server').io;
...
io.sockets.on("connection", function(socket){
  passportSocketIo.filterSocketsByUser(io, function (user) {
    return user.workingAt === socket.handshake.user.workingAt;
  }).forEach(function(s){
    s.send("news", insertedObject);
  });
});

И здесь ям застрял. Событие «соединение» никогда не будет запущено, поэтому сообщение не будет выбрано. Это правильный способ использования socket.io в отдельных файлах? К сожалению, я не могу найти сложный пример socket.io.

    
задан tschiela 24.10.2013 в 09:03
источник

1 ответ

41

Вы пытаетесь инвертировать поток управления. Способ сделать это для вашего контроллера, чтобы реализовать интерфейс (API), который ваш сервер может использовать для передачи управления.

Простым примером может быть:

В mycontroller.js

// no require needed here, at least, I don't think so

// Controller agrees to implement the function called "respond"
module.exports.respond = function(socket_io){
    // this function expects a socket_io connection as argument

    // now we can do whatever we want:
    socket_io.on('news',function(newsreel){

        // as is proper, protocol logic like
        // this belongs in a controller:

        socket.broadcast.emit(newsreel);
    });
}

Теперь в server.js :

var io = require('socket.io').listen(80);
var controller = require('./mycontroller');

io.sockets.on('connection', controller.respond );

Этот пример прост, потому что API-интерфейс контроллера выглядит точно так же, как обратный вызов socket.io. Но что, если вы хотите передать другие параметры контроллеру? Как и сам объект io или переменные, представляющие конечные точки? Для этого вам понадобится немного больше работы, но это немного. Это в основном тот же трюк, который мы часто используем для создания или закрытия замыканий: генераторы функций:

В mycontroller.js

module.exports.respond = function(endpoint,socket){
    // this function now expects an endpoint as argument

    socket.on('news',function(newsreel){

        // as is proper, protocol logic like
        // this belongs in a controller:

        endpoint.emit(newsreel); // broadcast news to everyone subscribing
                                     // to our endpoint/namespace
    });
}

Теперь на сервере нам потребуется немного больше работы, чтобы передать конечную точку:

var io = require('socket.io').listen(80);
var controller = require('./mycontroller');

var chat = io
  .of('/chat')
  .on('connection', function (socket) {
      controller.respond(chat,socket);
  });

Обратите внимание, что мы пропускаем socket прямо, но мы фиксируем chat через закрытие. При этом вы можете иметь несколько конечных точек с собственными контроллерами:

var io = require('socket.io').listen(80);
var news_controller = require('./controllers/news');
var chat_controller = require('./controllers/chat');

var news = io
  .of('/news')
  .on('connection', function (socket) {
      news_controller.respond(news,socket);
  });

var chat = io
  .of('/chat')
  .on('connection', function (socket) {
      chat_controller.respond(chat,socket);
  });

Собственно, вы можете использовать несколько контроллеров для каждой конечной точки. Помните, что контроллеры ничего не делают, кроме подписки на события. Это сервер, который выполняет прослушивание:

var io = require('socket.io').listen(80);
var news_controller = require('./controllers/news');
var chat_controller = require('./controllers/chat');

var chat = io
  .of('/chat')
  .on('connection', function (socket) {
      news_controller.respond(chat,socket);
      chat_controller.respond(chat,socket);
  });

Он даже работает с простым socket.io (без конечных точек / пространств имен):

var io = require('socket.io').listen(80);
var news_controller = require('./controllers/news');
var chat_controller = require('./controllers/chat');

io.sockets.on('connection', function (socket) {
    news_controller.respond(socket);
    chat_controller.respond(socket);
});
    
ответ дан slebetman 24.10.2013 в 10:04
источник