来自HTTP API控制器的Socket.io触发事件

时间:2017-06-10 12:12:46

标签: javascript node.js sockets express

在我的Node + Express服务器应用程序中,我希望从HTTP API发出的请求触发来自特定控制器的通知:

例如:

router.route('/status').put(Order.changeStatus)

class Order {
  static changeStatus(req, res) {
    // Modifying database record with changed status
    // Emiting message to specific socket room
  }
}

我按如下方式处理套接字连接:

import AuthMiddleware from '../middleware/AuthMiddleware';

const socketio = require('socket.io');
let io;

module.exports.listen = function(app){
  io = socketio.listen(app);

  io.on('connection', function(socket){
    console.log('Client connected');

    AuthMiddleware.authenticateSocket(socket, (err, user) => {
      socket.join(user._id);
      console.log('Client joined to: ' + user._id);
    })

    socket.on('disconnect', () => {
      console.log('Client disconnected')
    });
  });

  return io;
}

在验证传入的套接字连接后,它会订阅自己ID的房间。

套接字在项目顶部初始化,如下所示:

import app from './app';
import http from 'http';


const PORT = process.env.PORT || 7235;
const server = http.createServer(app);

const io = require('./socket/main').listen(server);

// App start
server.listen(PORT, err => {
  console.log(err || `Server listening on port ${PORT}`);
}); 

虽然我能够处理传入事件并对其进行响应,但这种结构的问题在于我无法访问控制器中的io对象,以便能够在特定房间中发出数据如下:

io.sockets.in(userID).emit('notification', data);

什么是能够从HTTP API的控制器触发套接字事件的正确结构?

1 个答案:

答案 0 :(得分:1)

您的控制器需要有权访问已配置的io对象。最简单的方法是将它导出到模块中,而不是只导出listen函数,或许是这样:

import AuthMiddleware from '../middleware/AuthMiddleware';

const socketio = require('socket.io');
let io;

function listen(app){
  io = socketio.listen(app);

  io.on('connection', function(socket){
    console.log('Client connected');

    AuthMiddleware.authenticateSocket(socket, (err, user) => {
      socket.join(user._id);
      console.log('Client joined to: ' + user._id);
    })

    socket.on('disconnect', () => {
      console.log('Client disconnected')
    });
  });

  return io;
}

module.exports = {
  listen, io
}

然后您的控制器可以const io = require('./path/to/that').io;