john smith
john smith

Reputation: 561

firing socket.emit() on http request

Right now I have the following code: foo

sIo.sockets.on('connection', function(socket){
  socket.emit('hello', 'world');
});

I would like to be able to emit this when somebody opens a page from my routes, like this:

//app.js
app.get('/send', routes.index);

//routes.js
exports.index = function(req, res){
  socket.emit('hello', 'world');
};

How can I achieve this? Thanks in advance

Upvotes: 2

Views: 3053

Answers (1)

Timothy Strimple
Timothy Strimple

Reputation: 23070

To send a socket message to all connected sockets, you can just call io.sockets.emit instead of socket.emit. There are a few ways to send messages using socket.io which I'll outline below.

// Send the message to all connected clients
io.sockets.emit('message', data);

// Send the message to only this client
socket.emit('message', data);

// Send the messages to all clients, except this one.
socket.broadcast.emit('message', data);

There is also a concept of rooms which you can use to segment your clients.

// Have a client join a room.
socket.join('room')

// Send a message to all users in a particular room
io.sockets.in('room').emit('message', data);

All of that covers how to send messages, but it's clear now you're asking about how to access the socket and / or io objects from inside a separate file. One options just has you pass those dependencies to the specified file. Your require line will end up looking something like this.

var routes = require('./routes')(io);

Where io is the socket.io object created from .listen. To handle that in your route file you'll have to change how you're defining your exports.

module.exports = function(io) {
  return {
    index: function(req, res) {
      io.sockets.emit('hello', 'world');
      res.send('hello world');
    }
  };
}

A cleaner implementation would have your routes expose events that your socket code can bind to. The following is untested, but should be very close.

var util = require("util"),
    events = require("events");

function MyRoute() {
  events.EventEmitter.call(this);
}

util.inherits(MyRoute, events.EventEmitter);

MyRoute.prototype.index = function(req, res) {
  this.emit('index');
  res.send('hello world');
}

module.exports = new MyRoute();

And then in your app.js file when you're binding express routes and socket.io.

app.get('/send', routes.index);

routes.on('index', function() {
  io.sockets.emit('hello', 'world');
});

There are many other ways to accomplish this, but the best one depends on what you're trying to do. As I alluded to before, calling broadcasting to everyone is going to be far more simple than broadcasting to a particular user.

Upvotes: 4

Related Questions