5

I'm not really talking about the general chat app, but rather specifically about the chatroom implementation.

So in node.js/socket.io, I thought of two approaches

  1. Create an array for each chatroom, broadcast message to all users in array

  2. Broadcasts all messages to all users, on clients' PCs determine if they belong in chatroom, if so, accept the message.

The weakness in 1 is that eventually as you scale up you will flood the server's memory with array objects, and I using only about 80mb on my hosting.

The weakness in 2 is that broadcasting to everyone is costly eventually and flooding the clients' machines won't make them happy.

I'm sure there are better approaches on how to implement the chatroom, so that's why I'm asking you guys to help me. I'm looking for performance on the server-side first then client-side, and it must be scalable.

Derek
  • 11,980
  • 26
  • 103
  • 162
  • With 80MB you can create a lot of chatrooms. Your arrays only need to hold the user's IDs. Did you run any memory consumption tests? – user123444555621 Sep 20 '11 at 07:20
  • We made a functioning [multi-room chatroom](https://github.com/Raynos/so642). It's open source, feel free to look. – Raynos Sep 20 '11 at 11:14
  • @pumbaa80 true, but 80mb becomes like 20-30mb after running a lot of other processes or cron jobs that I may need, plus I still don't think it's a good way to scale up because memory is expensive... – Derek Sep 20 '11 at 17:10
  • 1
    @Raynos, I looked at your implementation, and every room is still stored in the server's memory, right? Which really is not different than sticking a user in an array in memory. – Derek Sep 20 '11 at 17:12
  • 1
    @Derek no every room is stored in the database. However using socket.io I have sets of sockets I broadcast to per room, so I use method 1. I'm not storing extra objects in memory, I'm just storing a list of pointers to open sockets. – Raynos Sep 20 '11 at 17:18
  • 1
    @Raynos if every room is stored in a db and every broadcast would require a query into the db to see who's in the room, wouldn't the bottleneck at the db be huge and not really good for scaling up? – Derek Sep 20 '11 at 17:32
  • @Derek no, I meant meta data about the room is stored in the database. A room is just an object. What your talking about is the bag of sockets which are in a room. and the memory overhead for storing that array of sockets is incredibly minimal. Its a micro optimisation – Raynos Sep 20 '11 at 17:36
  • @Raynos so in other words it's like my approach 1 but with a db attached for meta data? – Derek Sep 20 '11 at 17:38

3 Answers3

5

Socket.IO 0.7+ introduced a rooms concept. This is probably the thing you are looking for.

io.sockets.on('connection', function (socket) {
  socket.join('room name');

  // broadcast the message to everybody in the room
  socket.on('chat message', function (data) {
    socket.broadcast.to('room name').emit('chat message', data);
  });

  socket.on('leave room', function (room) {
    socket.leave(room);
  });
});

So no need to manage your own array with users for specific rooms, socket.io has this build in.

3rdEden
  • 4,388
  • 1
  • 20
  • 18
  • didn't know that, i'll look into how they implement the socket.join() function then. But first, where are the socket.io documentations located? – Derek Sep 20 '11 at 17:04
  • The readme's: https://github.com/learnboost/socket.io https://github.com/learnboost/socket.io-client The site http://socket.io/ And in the wiki https://github.com/learnboost/socket.io/wiki – 3rdEden Sep 20 '11 at 20:38
  • I've prepared a [simple demo of a multiroom chat](https://github.com/jgonera/socket.io-multichat) using Socket.IO's rooms. It comes with a benchmark which lets you check how fast it can be. – Juliusz Gonera Nov 17 '11 at 13:19
1

I did something similar here:

http://davidgranado.com/demos/chat_shuffle/

You can test it out by opening up several windows and chatting with yourself since each instance is considered a person (it's my first node app).

The way it works is that every person is paired up with another person for a conversation. Effectively, everyone is in a two person room.

To get the messages across, I register the users as being associated with each other and only send it to the one partner chatter. This idea can easily be expanded out any number of people to associate the chatters. That way, you don't have to do a wasteful broadcast to everyone.

Just a guy
  • 5,812
  • 4
  • 21
  • 25
  • 1
    so say you have person1, person2, person3, how does the server know to send them all a message/know that they are in a chatroom without declaring an array to group them in a chatroom like in my approach 1? – Derek Sep 20 '11 at 05:59
  • I think my brain is not as sharp at this time as I thought. It's basically the same thing. At the moment, I don't use an array per se since it's only two of them. But to expand the idea, an array would be perfect for a chat room to know who to broadcast to. – Just a guy Sep 20 '11 at 06:07
-2

Now.js will make this much easier: http://nowjs.com/guide - their guide already has a how to, as well as their github repo https://github.com/Flotype/now/tree/master/examples/multiroomchat_example

balupton
  • 47,113
  • 32
  • 131
  • 182