Search code examples
node.jsexpresssocket.io

Socket.io emit on Express Route


I want to emit some data to the client when some API route gets called. I have to following code on server.js

var app  = express();
var http = require('http').Server(app);

var io   = require('socket.io')(http);

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

  socket.emit('tx', 'msg');

  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

Now I have this route /test:

var bsg   = require('./routes/test');

And that file:

var express      = require('express');
var passport     = require('passport');
var router       = express.Router();

router.get('/test',  function(req, res) {
  //work here
});

module.exports = router;

On client side:

<script type="text/javascript">
   var socket = io();

   socket.on('tx', function(data) {
     console.log(data);
   });
</script>

Whats the best solution for this?

Thanks!

Express 4 / socket.io 1.4.5


Solution

  • Attach the io instance to your app.

    app.io = io;
    

    Then you can access it via the request.

    router.get('/test',  function(req, res) {
      req.app.io.emit('tx', {key:"value"});
    });
    

    I should note that the more "correct" way to attach data to express is using app.set('io', io) and app.get('io') to retrieve it, just in case express started using the io property for something.

    If you are expecting to emit data to a single client you would need keep some kind of session mapping to link a standalone http request to a socket. A session ID might not be a one to one mapping though as you can have many sockets open for one session. You are better off handling a request/response pattern directly with socket.io callbacks.