I'd known, theoretically, about them for some time, but my first crash course was when I had to build (what I have labelled) a reverse-chat application for a very large government customer.<p>I was tasked with building an application that would allow a central presenter the ability to 'distribute' his chat messages out to as much as 5,000 users. The users could reply, but they would be moderated (and aggregated) by a team of n moderators (where n happened to be 3). User comments would be 'promoted' to the presenter, and the questions wouldn't show up on the screen unless the presenter responded to them.<p>The constraints were ridiculous. I had to build this app with Java, to be hosted on BEA WebLogic application server, and would be surfaced as a portlet on a BEA WebLogic portal. I was not allowed to make any changes to any existing databases already present though after some thought, I was able to get an Apache Derby database approved.<p>Long story short, the product was built, yadda yadda. After they'd used it a few times, some of the constraints were removed, and I was able to migrate it to a load-balanced platform. Of course, if you load balance an embedded database on two different servers, what happens is each node writes to its own data store, and that means that the users on side 1 are able to see side 1 chat, and the users on side 2 are able to see the side 2 chat.<p>So what I needed then, was some way for them to communicate. Since I'm tired of typing, I ended up having to write a bridge layer (with JMS) that communicated updates across the board, and then I ended up writing a task queue that allowed for components to be pushed into a queue, to prevent congestion.