Pubsub with Node.js and Socket.io for individual users

I want to check that i've got my knowledge the right way round with using pubsub to gather notifications for a specific user in a Node.js/socket.io environment.

Here's my setup:

  • Main application is written in PHP over Codeigniter. Auth is handled using Ion_Auth for CI (Session etc)
  • Realtime (currently just notifications) is handled with Node.js and Socket.io
  • Authenticated users can invite friends to "groups" - invite will send both email and internal notification if invitee already has account
  • Authenticated users can leave comments, perform actions on shared content. Both will result in a notification to all subscribed users of that content.

I believe the correct way to handle this, is for each user to be subscribed to a notification channel. This channel contains every notification for every user, which is pushed to the channel by a publish event fired any time we do one of the above actions. The subscription then checks this channel for specific data related to the user session, i.e.:

  • For notifications related to invites, the published event would contain some uniquely identifying user data, and we would check for that.
  • for notifications related to a specific piece of content, we would check the channel for published events containing identifying markers for that content.

Is this the right way to do it? I'm fairly new to socket.io, node.js and pubsub, but this seems to make sense to me. The part which is throwing me, is that we should be pushing events to the clients, rather than the client pulling events from the server. This solution seems to do both.

If there is a simpler solution (i.e. something more native to socket.io) i'd appreciate some insight. All I can really find in the way of tutorials or examples is the same chat client writeup over and over...

Edit: Alternatively, would it be more practical to maintain a hash of all connected client ids alongside their corresponding user id, then when a new message comes in, emit that message to the specific client using var socket = hash[userID]; socket.emit(message);

Anyone got any thoughts as to potential bottlenecks in this case? The site could potentially have many thousands of concurrent users being updated about multiple events.

I suggest not implementing the PubSub yourself. I had to do that kind of broadcast once and used RabbitMQ to handle the connections and routing (that includes broadcast).

Real time messaging to a browser is done using reverse Ajax calls (long held http connections, see Comet on Wikipedia)

See RabbitMQ server and libraries for Node

Rabbit MQ offers many advantage:

  • The client will alway be able to post a message as long as RabbitMQ is running.
  • You will be able to scope your server easily by starting another instance of your application server whenever you need more throughput (scale out).
  • Messages sent to RabbitMQ can be persisted.
  • Posting messages to RabbitMQ can be done inside a transaction.
  • Easy server insterface to manage your queues and exchanges.