Realtime XML-RPC API

  To restart the Instant Outliner, I needed the equivalent of FriendFeed's realtime update functionality.
  It's really elegant, but I couldn't make my software depend on another service for update notification. I started to do it in REST and realized that I was reinventing a lot of what XML-RPC already did.
  So I put aside the REST approach and went with XML-RPC.
  A day later I had it working and a day after that I had the Instant Outliner converted. Unlike previous implementations this one works perfectly, is instantaneous and requires no polling. The long-poll approach works perfectly.
  I wanted to document this for the programmers who are testing the Instant Outliner, because the realtime updating functionality is more general, it can be used to connect our workgroup together in more ways than through I/Oing.
  There are two entry-points, one to get the next set of updates, and one to push an update to the workgroup. Both assume there's an identity system in place that can independently determine if a username/password is valid. (The identity function hooks in as a callback.)
  Users can connect from more than one location at a time, each instance gets a complete set of updates. So I can leave my I/O app running at home and stay connected from a classroom or Starbucks.
  You can find the source for both the client and the server at builtins.realtime in opml.root.
  Here are the two entry-points:
  1. realtime.getUpdates (username, password) returns array of struct
    This is the long poll call. This routine doesn't return until: 1. There's one or more updates. 2. It times out.
    If there are N updates, the returned array contains N structs. Each struct has four or five pieces of information:
      1. htmltext -- a string that can be displayed explaining in verbiage what the event was.
      2. type -- a string that indicates how the update is to be processed. It's something a callback on the client can watch for. For the instant outliner, the type is "instantOutline."
      3. when -- the date/time the event was posted.
      4. username -- the user who caused the update.
      5. data -- optional, it's up to the poster of the event what it contains. In the instant outliner, it's the OPML text of the outline that updated.
    If there's an update waiting it returns immediately.
    The timeout period is up to the server. I have mine set to time out after 180 seconds. When it times out, the array returned has 0 elements.
    After receiving an update, whether it was an error or not, the caller should loop back and make another update call.
  2. realtime.pushUpdate (username, password, htmltext, type, data)
    The other side of the updating mechanism. Each user that's listening receives a copy of the update struct, which is returned when they next make a request to be updated.