Подтвердить что ты не робот

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

Мне нужен только socket.io для отправки сообщений клиентам, если новый объект вставляется в базу данных. Поэтому моя идея состояла в том, чтобы выпустить сообщение непосредственно из моего метода insert-method. В моем файле 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.

4b9b3361

Ответ 1

Вы пытаетесь инвертировать поток управления. Способ сделать это для вашего контроллера, чтобы реализовать интерфейс (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);
});