Edit in JSFiddle

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Orbiter Share Application State</title>

<!--CSS-->
<style type="text/css">
#outPane {
  border: inset 2px; 
  height: 200px; 
  width: 500px; 
  overflow: auto; 
  padding: 5px; 
  margin-bottom: 5px
}
</style>

<!--Load the Orbiter JavaScript library (non-minified version). Use during development.-->
<script type="text/javascript" src="http://unionplatform.com/cdn/Orbiter_latest.js"></script>
<!--Load the Orbiter JavaScript library (minified version). Use for production.-->
<!--<script type="text/javascript" src="http://unionplatform.com/cdn/Orbiter_latest_min.js"></script>-->

<!--Application code-->
<script type="text/javascript">
//==============================================================================
// VARIABLES
//==============================================================================
var orbiter;
var appRoom;

//==============================================================================
// INITIALIZATION
//==============================================================================
function init () {
  // Create the Orbiter instance, used to connect to and communicate with Union,
  // then enable automatic reconnection (one attempt every 15 seconds)
  orbiter = new net.user1.orbiter.Orbiter();
  orbiter.getConnectionMonitor().setAutoReconnectFrequency(15000);
  orbiter.getLog().setLevel(net.user1.logger.Logger.DEBUG);
  
  // If required JavaScript capabilities are missing, abort
  if (!orbiter.getSystem().isJavaScriptCompatible()) {
    displayMessage("Your browser is not supported.");
    return;
  }
  
  // Register for Orbiter's connection events
  orbiter.addEventListener(net.user1.orbiter.OrbiterEvent.READY, readyListener, this);
  orbiter.addEventListener(net.user1.orbiter.OrbiterEvent.CLOSE, closeListener, this);
  
  displayMessage("Connecting to Union...");

  // Connect to Union Server
  orbiter.connect("tryunion.com", 80);
}

//==============================================================================
// ORBITER EVENT LISTENERS
//==============================================================================
// Triggered when the connection is ready
function readyListener (e) {
  displayMessage("Connected.");
  displayMessage("Joining room...");
  
  // Create the application room on the server. Configure the room to exist
  // until the next time Union Server shuts down.
  var settings = new net.user1.orbiter.RoomSettings();
  settings.removeOnEmpty = false;
  appRoom = orbiter.getRoomManager().createRoom("examples.shareAppStateRoom", settings);
  appRoom.addEventListener(net.user1.orbiter.RoomEvent.JOIN, joinRoomListener);
  appRoom.addEventListener(net.user1.orbiter.AttributeEvent.UPDATE, roomAttributeUpdateListener);
  
  // Join the application room
  appRoom.join();
}

// Triggered when the connection is closed
function closeListener (e) {
  displayMessage("Orbiter connection closed.");
}

//==============================================================================
// ROOM EVENT LISTENERS
//==============================================================================
// Triggered when the room is joined
function joinRoomListener (e) {
  displayMessage("Application room joined.");
  
  // Display the shared application state
  if (appRoom.getAttribute("numOccupantsLifetime") == null) {
    displayMessage("You are the first client to join this room.");
  } else {
    displayMessage("The last time a client joined the room was:");
    displayMessage(new Date(parseFloat(appRoom.getAttribute("lastOccupantJoinedAt"))));
    displayMessage("Number of clients that have ever joined the room:");
    // Add one because the current client hasn't been counted yet
    displayMessage(parseInt(appRoom.getAttribute("numOccupantsLifetime"))+1);
  }
  
  // Update the shared application state...
    // Set lastOccupantJoinedAt to the approximate current time on the server
  appRoom.setAttribute("lastOccupantJoinedAt", orbiter.getServer().getServerTime().toString());
    // Add one to the numOccupantsLifetime attribute
  appRoom.setAttribute("numOccupantsLifetime", "%v+1", true, false, true);
}

function roomAttributeUpdateListener (e) {
  // If the room's attributes change after it has been synchronized...
  if (appRoom.getSyncState() == net.user1.orbiter.SynchronizationState.SYNCHRONIZED) {
    // ...and the client that changed the attribute was *not* the current client
    if (e.getChangedAttr().byClient != orbiter.self()) {
      // ...then display a message for the changed attribute
      if (e.getChangedAttr().name == "lastOccupantJoinedAt") {
        displayMessage("UPDATE! A client joined at:");
        displayMessage(new Date(parseFloat(appRoom.getAttribute("lastOccupantJoinedAt"))));
      } else if (e.getChangedAttr().name == "numOccupantsLifetime") {
        displayMessage("UPDATE! New number of clients that have ever joined the room:");
        displayMessage(parseInt(appRoom.getAttribute("numOccupantsLifetime")));
      }
    }
  }
}

//==============================================================================
// UI
//==============================================================================
// Displays a single message on screen
function displayMessage (message) {
  // Make the new message element
  var msg = document.createElement("span");
  msg.appendChild(document.createTextNode(message));
  msg.appendChild(document.createElement("br"));

  // Append the new message to the output pane
  var outPane = document.getElementById("outPane");
  outPane.appendChild(msg);
  
  // Trim the chat to 500 messages
  if (outPane.childNodes.length > 500) {
    outPane.removeChild(outPane.firstChild);
  }
  outPane.scrollTop = outPane.scrollHeight;
}
</script>
</head>

<body onload="init()">
<!--Contains the output pane-->
<div id="outPane"></div>

</body>
</html>