在控制器中使用socket.io

tsc*_*ela 20 node.js socket.io

如果将新对象插入数据库,我只需要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;
Run Code Online (Sandbox Code Playgroud)

在我的控制器中,我尝试使用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);
  });
});
Run Code Online (Sandbox Code Playgroud)

我坚持到这里.永远不会触发"连接"事件,因此不会发出消息.这是在单独的文件中使用socket.io的正确方法吗?不幸的是我无法找到复杂的socket.io示例.

sle*_*man 45

您正试图反转控制流.执行此操作的方法是让控制器实现服务器可用于将控制权传递给的接口(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);
    });
}
Run Code Online (Sandbox Code Playgroud)

现在server.js:

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

io.sockets.on('connection', controller.respond );
Run Code Online (Sandbox Code Playgroud)

这个例子很简单,因为控制器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
    });
}
Run Code Online (Sandbox Code Playgroud)

现在在服务器上我们需要更多的工作才能通过终点:

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

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

请注意,我们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);
  });
Run Code Online (Sandbox Code Playgroud)

实际上,您甚至可以为每个端点使用多个控制器.请记住,除订阅事件外,控制器不会执行任何操作.这是正在进行收听的服务器:

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);
  });
Run Code Online (Sandbox Code Playgroud)

它甚至适用于普通的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);
});
Run Code Online (Sandbox Code Playgroud)

  • 你需要一个不同的控制器来处理socket.io,因为它是一个不同的服务.但是为了确保只发射,你可以以同样的方式传递socket.io.让你的控制器接受`req,res,io`作为参数,然后在app.post中让第二个参数为`function(req,res){TestCtrl.insert(req,res,io)}` (5认同)

Ary*_*rya 6

你可以很容易地做到这一点,你只需在 app.js 中编写套接字连接,然后你就可以在任何你想要的地方使用套接字

app.js文件中放入如下代码

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

 io.sockets.on("connection", function (socket) {
 // Everytime a client logs in, display a connected message
 console.log("Server-Client Connected!");

 socket.join("_room" + socket.handshake.query.room_id);

 socket.on('connected', function (data) {

   });
});

const socketIoObject = io;
module.exports.ioObject = socketIoObject;
Run Code Online (Sandbox Code Playgroud)

在任何文件或控制器中,您可以导入该对象,如下所示

 const socket = require('../app'); //import socket  from app.js

      //you can emit or on the events as shown 
 socket.ioObject.sockets.in("_room" + req.body.id).emit("msg", "How are You ?");
Run Code Online (Sandbox Code Playgroud)