Hard Code Golf: Create a Chatroom Cue Storyline:  It is the early 21st century, and most things have become a thing of the past.  You and your fellow code-golf-eteers, however, are on a quest to reenact the 1990s.  As a part of this challenge, you must recreate a minimalistic chatroom.

The Goal:  To create a chatroom with as few bytes as possible.  The program(s) that you write shall function as a simple server, which serves a webpage, which allows users to post text onto the screen.

The Actual Goal:  To actually host a working chatroom from your own computer.  You don't have to do this, but it is a lot more fun this way.

Requirements:


Users should be able to give themselves a username that lasts for the session
Users should be able to repeatedly type and submit text, which will be displayed to other users 
Each user should be able to see the text that is submitted by all users, along with the usernames of the submitters, and the information should be displayed in chronological order
The page should also display the number of people online and a list of their usernames
Your chatroom should be accessible to anyone on the internet who knows where to find it (such as knowing the IP address).
It should function in modern web browsers.


All else is up to you!

Submissions:


Should include the source code, or a link to the source code
Should include screenshots of the functional chatroom
Should include the total size, in bytes, of all of the programs/files that you have written that are required to make it work.


This challenge has been in the sandbox for a while now, so hopefully all of the kinks have been worked out.
PHP + JQuery + HTML + CSS, 1535 bytes

This is a submission leaning more towards what the OP deemed as 'the actual goal'. That is, a fully functional chat server, which may be hosted on just about any web server anywhere.

Functionality includes:


Notifications when users enter or leave the chat room.
Notifications when users change their alias.
Real time polling for new messages, without generating excess server traffic, or server load.
Layout and usability strongly resembling existing chat clients, such as X-Chat.


To being a session, enter an alias in the appropriate box, and press Tab or Enter to submit. If the alias is already in use, you will be notified. Sending messages is also done via Enter.



For your convenience, an archive of all files may be found here: chat.zip (choose Download from the File menu). To install, unpack to a web directory on any server running PHP 5.4 or higher.

Caveats:


IE 8 or lower will spin into an infinite loop while polling, because for some reason unknown to humanity, all Ajax requests are cached by default. It also prevents you from sending the same message twice, and updating the user list properly. This could be fixed by adding cache:false to every Ajax request.
In all version of IE, messages will not be sent by pressing Enter, because the change event is not triggered (pressing Tab, however, does work). This could be fixed by adding an onkeypress handler, checking if the key was Enter, and then calling $(v).blur().focus().


In short, IE is not supported.



Client

Positioning of elements could be a bit more robust, but it should look alright with a minimum window size of about ~800x600.

chat.htm (190 bytes)

&lt;script src=jquery.min.js&gt;&lt;/script&gt;
&lt;script src=c.js&gt;&lt;/script&gt;
&lt;link rel=stylesheet href=c.css&gt;
&lt;select id=u multiple&gt;&lt;/select&gt;&lt;pre id=o&gt;&lt;/pre&gt;
&lt;input id=n onchange=u()&gt;&lt;input id=v onchange=s()&gt;


c.css (136 bytes)

i{color:#999}
#u{float:right;height:100%;width:200px;margin-left:10px}
#o{border:1px solid #999;height:93%;overflow-y:scroll}
#v{width:54%}


c.js (435 bytes)

var l
(function p(){
  $.ajax({url:'p.php',data:{n:$('#n').val()},success:function(d){
    $('#o').html(d).scrollTop(1e4);$('#u').load('n.php');
  },complete:p,timeout:2e4})
})()
function s(){
  $.get('s.php',{n:$(n).val(),v:$(v).val()})
  $(v).val('')
}
function u(){
  $.get('u.php',{l:i=l,n:l=$(n).val()}).fail(function(){
    alert("This name is already in use!")
    $(n).val(l=i)
  })
}
$(window).on('unload',function(){$.ajax({url:'l.php',data:{l:l},async:false})})




Server

I apologize for the server being broken up into so many tiny chunks. The alternative would be to use an adequate message protocol (via JSON encode/decode), or having a large if ... elseif ... according to which post variables are present. Making separate scripts, an just requesting from the one you need is a lot shorter, and perhaps simpler than both.

o.php (119 bytes) Opens as connection to the 'database'

&lt;?$m=array_slice(unserialize(file_get_contents(m)),-300);
$u=unserialize(file_get_contents(u));$t=time();extract($_GET);


c.php (57 bytes) Commits changes to the 'database'

&lt;?foreach([u,m]as$c)file_put_contents($c,serialize($$c));


p.php (151 bytes) Polls for new messages

&lt;?for($t=time();@filemtime(m)&lt;$t;usleep(1e3))clearstatcache();include('o.php');
foreach($m as$v)if($n&amp;&amp;$v[0]&gt;=$u[$n])echo@date("[H:i]",$v[0])."$v[1]\n";


s.php (62 bytes) Send a message to the server

&lt;?include('o.php');$m[]=[$t,"&lt;b&gt;$n&lt;/b&gt;: $v"];include('c.php');


u.php (222 bytes) User registration or alias change

&lt;?include('o.php');if(!trim($n)||$u[$n])exit(header('HTTP/1.1 418'));
$m[]=[$t,$u[$l]?
"&lt;i&gt;&lt;b&gt;$l&lt;/b&gt; is now known as &lt;b&gt;$n&lt;/b&gt;.&lt;/i&gt;":
"&lt;i&gt;&lt;b&gt;$n&lt;/b&gt; has entered the chat.&lt;/i&gt;"];
$u[$n]=$u[$l]?:$t;unset($u[$l]);include('c.php');


n.php (65 bytes) Retrieves the list of user names

&lt;?include('o.php');foreach($u as$k=&gt;$v)echo"&lt;option&gt;$k&lt;/option&gt;";


l.php (98 bytes) User has left (closed their browser)

&lt;?include('o.php');$m[]=[$t,"&lt;i&gt;&lt;b&gt;$l&lt;/b&gt; has left the chat.&lt;/i&gt;"];
unset($u[$l]);include('c.php');