16

I saw this snippet:

On Server

io.sockets.on('connection', function(socket) {
  const subscribe = redis.createClient();
  const publish = redis.createClient();

  socket.on('publish', function(channel, data) {
    publish.publish(channel, data);
  });

  socket.on('psubscribe', function(channel) {
    subscribe.psubscribe(channel);
  });

  subscribe.on("pmessage", function(pattern, channel, message) {
    socket.emit('message', { channel: channel, data: message });
  });
});

On Client

$(".action").click(function() {
  socket.emit('publish', 'game.#{gameid}.action.' + $(this).data('action'),
  JSON.stringify({ nick: "#{nick}", ts: Date.now() })
);

And I'm wondering why? Doesn't Socket.IO have its own broadcast mechanism? Why choose Redis' Pub-Sub over Socket.IO? Can't we just do like this:

io.sockets.on('connection', function(socket) {
  socket.on('action', function(channel, data) {
    socket.broadcast.to(channel).emit(data)
  });
});

And if there is a reason to use Redis, what would be the benefit? Persistence?

Sơn Trần-Nguyễn
  • 2,188
  • 1
  • 26
  • 30
  • 2
    Your answer of "persistence" seems like a good one. Multi-process and multi-machine scaling is surely another. – Richard Simões Apr 15 '12 at 23:52
  • Thanks! Did not think of the scaling issue. – Sơn Trần-Nguyễn Apr 16 '12 at 00:28
  • 2
    Redis does not persist anything regarding pub/sub. It does not even queue the items in memory. – Didier Spezia Apr 16 '12 at 16:44
  • What I was thinking is even when the server dies after receiving event from a client and fails to broadcast, with Redis, other clients will still receive it. But then, if redis client dies, then yeah, no persistence at all :( So that's not a strong reason there. – Sơn Trần-Nguyễn Apr 17 '12 at 12:32
  • 2
    I think the main reason to use Redis here would be if there's a chance that non-sockets will want the information being broadcast. Redis works with other clients and would allow another applications you make to subscribe to what's happening. But without looking much into it, I'd have a glance at using RedisStore with socket.io (which has poor documentation) because I think that ends up using Redis' pub/sub system internally allowing for scalability. – Pluckerpluck May 10 '12 at 00:41
  • I want to add another use case of Redis Pub/Sub is bringing real-time functionality to traditional programming languages like PHP. You can use Pub/Sub channels to communicate with your Node.JS server in order to have an event-driven functionality in your PHP stack. – Maziyar Oct 09 '13 at 11:07

2 Answers2

16

The reason I chose to use Redis Pub Sub with Socket.io in my Real Time Activity Stream project (http://blog.cloudfoundry.com/2012/06/05/node-activity-streams-app-2/) was because I wanted to have multiple web servers (instances on Cloud Foundry or dynos on Heroku). As far as I could see, Socket.io stores the messages in memory (of one webserver), so how it could possibly broadcast to clients which are connected to another webserver?

Check out the post and let me know if it helps

Deepak Joy Cheenath
  • 5,796
  • 5
  • 25
  • 29
Monica Wilkinson
  • 635
  • 1
  • 8
  • 11
2

Redis is used here for at least two reasons. The first one is that it works really well as a publish and subscribe mechanism, including being able to select messages based on pattern matching to psubscribe. The second reason is the ease of other clients to be able to publish and subscribe through the redis mechanism. That is not to say that it is impossible, just convenient. This combined with the asynchronisity of node.js makes a powerful partnership.

It's not the only solution of course but one that seems to work rather well.

Lloyd Moore
  • 3,117
  • 1
  • 32
  • 32
  • I'm sorry but I still don't see those two reasons any better than socket.io pub-sub. I guess because I don't really need pattern matching for messages (even though it's a really powerful feature). And by "other clients", you meant "other than the browser"? – Sơn Trần-Nguyễn Jun 15 '12 at 09:41