1

Forgive the lack of a question. I'm trying to build a website with the same functions as a chat room. The idea of 5-50 viewers in each room (with thousands of rooms) is very real, only about 1% of the room would be chatting.

I've had some ideas, but everything I've come up with seems like it would require a crazy amount of processing power... What would be an efficient way to do this?

user1516606
  • 69
  • 2
  • 11

2 Answers2

2

There are specific programs designed for this purpose (ircd, see http://www.atheme.org/project/charybdis and similar.) However, if you really wish to reinvent the wheel, you will likely want a hosting solution that has a decent amount of physical RAM, and shared memory extensions (ex: APC.)

Shared memory functionality (APC in this case) will be the fastest way to keep everyone's conversations in sync, without the hard drive spinning up too much or otherwise MySQL spiraling out of control. You should be able to accommodate hundreds of concurrent requests this way without the server breaking a sweat, since it doesn't tax MySQL. It reads almost directly off the RAM chips.

You can key-store individual channels for conversations (ex: "channel-#welcome") and poll them directly via AJAX. See apc_store, apc_add and apc_fetch for more information.

Even if you end up storing conversations in MySQL for whatever reason, it's still preferable to use some kind of memory caching for reading, since that takes tremendous load off of the database server.

If you do it this way, it's best to make your databases innodb, since they won't lock during writes. Using APC, your limiting reagent will be amount of RAM and length of conversations that you intend to keep in shared buffer.

pp19dd
  • 3,625
  • 2
  • 16
  • 21
  • Appreciate the long answer, very interesting. Would you recommend the APC method over Comet? ( http://stackoverflow.com/questions/4174521/how-to-implement-a-chat-room-using-jquery-php?rq=1 ) – user1516606 Jul 11 '12 at 05:18
  • please please please don't re-invent this wheel. Take first part of his advice and use a program already designed to handle chat. Building a chat server in PHP & MySQL is an awful idea. – Gavin Towey Jul 11 '12 at 05:57
  • @GavinTowey thanks for the advice, but understanding/implementing ircd/charybdis looks like it's way above my skill level. I'm happy not using MySQL, just as long as I have a good understanding of how the code works, so if problem occurs later I can see whats went wrong easily. – user1516606 Jul 11 '12 at 08:45
  • In this case, APC and Comet would be complements of each other. You can use both. – pp19dd Jul 11 '12 at 12:26
1

You've asked a really broad question, but:

Store each message as a row in your database, use AJAX to reload the chat window content with the last few messages e.g.

SELECT * FROM `chat_messages` WHERE `room_id` = 'ID' ORDER BY `id` DESC LIMIT 100

Will select the 100 most recent messages for the chat room. Loop over the results and display all the messages as you want.

If your database user has permissions to create tables, you could also dynamically create a table for each chat room (which would be a lot faster performance wise)

You'd then simply have an input or textarea in a form, that when submitted, inserts a new row to the database (which will show up to everyone next time the chat window is reloaded).

Another, more optimised way to do it would be to only return new messages to users each query, by storing the timestamp of each message in the database, and storing the timestamp of the last request locally in JavaScript, then use a query like:

SELECT * FROM `chat_messages` WHERE `room_id` = 'ID' AND `timestamp` > 'LAST_REQUEST' ORDER BY `id` DESC LIMIT 100

Then appending the result to the chat window, rather than replacing it.

wyqydsyq
  • 1,992
  • 1
  • 20
  • 28
  • But won't that bash my server like crazy? 1000 users doing 100*selects every second? – user1516606 Jul 11 '12 at 04:54
  • Assuming you refresh once a second, wouldn't it be 1000 users doing 1 select a second? – wyqydsyq Jul 11 '12 at 05:00
  • Sorry typo, but still with the amount of users I plan on maintaining I don't think my server could handle it. – user1516606 Jul 11 '12 at 05:21
  • You could also have PHP write to a file every second, and AJAX load that file every second. That way the query only gets ran one time a second for each chatroom, and all of the AJAX requests are to the static file that PHP generated. – wyqydsyq Jul 11 '12 at 05:45
  • I had that idea, but it seemed a bit cumbersome? While researching the ideas @pp shared I found a lot more ideas on the subject. Appreciate your help. – user1516606 Jul 11 '12 at 08:42