Saturday, 10 June 2017

Socket.io emit event from controller

In my Node.js server app I'd like to emit notifications from specific controllers triggered by requests hitting the HTTP API:

For example:

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

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

I'm handling socket connections as follows:

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;
}

After authenticating the incoming socket connection, it is subscribed to the room of its own ID.

The socket is initialised at the top of the project as follows:

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}`);
}); 

Although I'm able to process incoming events and respond to those, the problem with this structure is that I can't access the io object within the controllers to be able to emit data in a particular room as follows:

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

How should I modify my structure to be able to trigger socket events from the controllers of the HTTP API?



via sznrbrt

No comments:

Post a Comment