views:

1745

answers:

6

I'm building a basic little AJAX shoutbox/chat for my website, but I'm not sure exactly how to implement the server polling.

Here's the basic program flow I'm thinking of:

  1. User comes to page and is shown the last 10 messages
  2. To get messages sent by others, the client javascript would request a URL with a timestamp parameter (set to the value of the last message the client received)
  3. The server returns all messages (up to a max of 10) since that timestamp.

The only issue is how often to poll the server. Obviously it should poll each time a new message is added, but when you're just reading others' messages it needs to automatically update.

Should it be a set time limit? eg: every 10 seconds. Or, should it vary depending on usage? eg: Check after 5 seconds. If there's no messages, don't check for another 10 seconds. If there's still no new messages, check in 15 seconds, then 20, up to maybe once every 30 seconds max. Each time there's a new message detected reset your timer back down to 5 seconds and start again.

I'm just concerned about putting unnecessary stress on the server, considering that we could have hundreds of users concurrently online.

...or have I got the whole thing wrong? Is there a better way to implement a basic javascript chat?

A: 

You should check to see if the other user is typing every 5 seconds or so, if the other user is typing, then you can check every 1 second to see if the user has sent a new message. Really though, you should be able to check every 1 second to see if other user is typing and if they are then every .25-.5 second check to see if new message has been sent. With broadband being so generally accepted on the inet, shouldn't be a problem. Go with the longer poll timeout for a dial-up access.

Suroot
there could be hundreds of people though. And wouldn't that require that each client send a request when the user starts typing as well as when they stop?
nickf
This is true, however in AJAX that's what the AJAX XMLHTTPRequest object was designed for.
Suroot
Sorry for the double post here but wanted to put this information in there: http://en.wikipedia.org/wiki/Comet_(programming)#XMLHttpRequest
Suroot
+5  A: 

You might want to look into what are known as Comet programming techniques to stream information down to your users, rather than having the client poll the server. This is actually a family of techniques, some of which may work better than others depending on the circumstances, such as what kind of server you're using and what kind of client compatibility you need.

If your server can handle a large number of open connections at a time (as in, it does not use an entire thread or process per connection, such as nginx or an erlang based server), you may wish to use a long polling technique, where as soon one message is received, the client immediately requests another message. If there are no messages available, the server simply keeps the connection open, possibly sending occasionally dummy data as a keepalive, until a message becomes available.

Brian Campbell
A: 

This is a very hard question, keep abuse in mind. Malicious users will hit you as often as possible, with the earliest timestamp faked so as to cause stress on your DB server. Be sure to validate that timestamp, or ignore it, because shouldnt everyone be in the same time anyway?

You can send the polling interval to the user as a function of the other user's response time. That's the best kind of dynamic I think.

Karl
yeah i thought of that - i figured I'd return the latest 10 messages since the given timestamp, so even if someone changes it to "0", they'll just get the last 10 messages.
nickf
+2  A: 

Comet, described by Brian is a nice technique, but requires session support on the server, which is probably more advanced than you care to implement for a simple chat box.

The best way to implement polling intervals is to imagine you having a chat window which you can minimize to do other stuff, or open to see if you have new messages. When you are in the middle of a conversation, you'll switch to it (poll) frequently. If you don't get any messages for a while, you will start looking rarer and rarer until you only check it occasionally.

Assuming you don't need to do real-time typing, you can probably poll every 3 seconds or so when at peak activity, and if nothing shows up for 5-10 polls, start to crank the interval up (perhaps doubling it every time) until it hits 30-60 seconds. Getting a message back should reset the poll interval back to a few seconds, while sending a message should poll instantly, but probably doesn't need to effect the frequency of polling otherwise.

levik
That's just what the asker outlined. Did you read the entire question?
Crescent Fresh
I think the key point there is the subtle clarification of a successful update vs. an unnecessary update. For the chat example, if there is a new chat, that indicates activity, and the polling interval should be baselined to a short interval (positive feedback loop). If a poll is done and there is no new chats, then the interval for the next one should increase (negative feedback loop). I think that's makes for a pretty powerful and efficient method of dealing with polling.
Tchalvak
+2  A: 

Honestly, if you are implementing a “basic little AJAX shoutbox/chat”, things like Jabber, Comet etc are overkill for you. These things will require you to run additional servers/proxies to take the load of the app server and db.
When you think about stuff like presence management (“Joe is typing...”), then things get overly complex for your app (considering “chat” is not your prime focus).
Think about adding widgets from providers like Meebo and Userplane. Once you scale think about the Jabber and the like…

Cherian
indeed it really is just supposed to be the most basic functionality
nickf
A: 

http://jabbify.com/home/comet_service This is a free comet based chat service by the guys who did the jmvc framework. Haven't tried it yet, but looks promising.

Ryan McIlmoyl