WebSockets are a push technology built for two-way communication. They are moving toward W3C standardization, and recent Chrome and Safari releases already support them.
The problem they address is familiar: long polling. In a long-polling setup, the client sends a request, and the server does not immediately answer. It holds the connection open until a timeout is reached or new data is ready. The client receives that response, then opens another request. This can reduce latency, since an open connection avoids some of the cost of starting from scratch, but it is not elegant. A request can stall while waiting, forcing another connection, and many Ajax applications using this pattern can waste server resources because connections stay tied up.
A better model would let the server wake up and send data to the client that needs it without the same reserved-connection overhead. That is the push model WebSockets provides.
Get a WebSocket server running
This walkthrough is mostly about the client, but the client needs something to talk to. The example environment uses XAMPP on Windows 7 to provide PHP, along with phpwebsockets, a WebSocket server written in PHP. Depending on the build, phpwebsockets may need small fixes. Other implementations are available, so if one does not work, try another and continue with the same client steps.
- jWebSocket (Java)
- web-socket-ruby (Ruby)
- Socket IO-node (Node.js)
Start Apache in XAMPP before continuing.

Adjust the server URL and interface
The server configuration may need changes during setup. For example, in setup.class.php:
public function __construct($host='localhost',$port=8000,$max=100)
{
$this->createSocket($host,$port);
}
Open the relevant files and change the host, port, or other values where appropriate.
Build the client page
Start with a basic template. The sample client.php looks like this:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<title>WebSockets Client</title>
</head>
<body>
<div id="wrapper">
<div id="container">
<h1>WebSockets Client</h1>
<div id="chatLog">
</div><!-- #chatLog -->
<p id="examples">e.g. try 'hi', 'name', 'age', 'today'</p>
<input id="text" type="text" />
<button id="disconnect">Disconnect</button>
</div><!-- #container -->
</div>
</body>
</html>
Add some CSS
Nothing elaborate is required; the goal is to space the elements out enough to work with them.
body {
font-family:Arial, Helvetica, sans-serif;
}
#container{
border:5px solid grey;
width:800px;
margin:0 auto;
padding:10px;
}
#chatLog{
padding:5px;
border:1px solid black;
}
#chatLog p {
margin:0;
}
.event {
color:#999;
}
.warning{
font-weight:bold;
color:#CCC;
}
Understand the WebSocket events
Before wiring up the page, it helps to know which events matter.

There are three events to use:
- onopen: a socket connection is opened
- onmessage: a message is received
- onclose: a socket connection is closed
What can be done with them?
First, create a WebSocket object:
var socket = new WebSocket("ws://localhost:8000/socket/server/startDaemon.php");
Checking whether an event fires is straightforward:
socket.onopen = function(){
alert("Socket has been opened!");
}
Receiving a message works the same way:
socket.onmessage = function(msg){
alert(msg); //Awesome!
}
In a real page, avoid relying on alert boxes and put the information into the client interface instead.
Write the JavaScript
Place the code inside $(document).ready(function() {}), then check whether the browser supports WebSockets. If it does not, fade out the chat controls and append a link pointing to Chrome.
$(document).ready(function() {
if(!("WebSocket" in window)){
$('#chatLog, input, button, #examples').fadeOut("fast");
$('<p>Oh no, you need a browser that supports WebSockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container');
}else{
//The user has WebSockets
connect();
function connect(){
//the connect function code is below
}
});
If the browser supports WebSockets, execution continues into a connect() function. That function brings together the open, message, and close events.
First define the server URL:
var socket;
var host = "ws://localhost:8000/socket/server/startDaemon.php";
Notice that the URL does not use http. It uses the WebSocket scheme, which is different from an HTTP URL. The address breaks down like this:

Inside connect(), wrap the work in try/catch so failures can be reported to the user. Create a new WebSocket connection, pass messages through a message function, and define onopen, onmessage, and onclose. Showing the socket state is not required, but it helps with debugging.
- CONNECTING = 0
- OPEN = 1
- CLOSED = 2
function connect(){
try{
var socket;
var host = "ws://localhost:8000/socket/server/startDaemon.php";
var socket = new WebSocket(host);
message('<p class="event">Socket Status: '+socket.readyState);
socket.onopen = function(){
message('<p class="event">Socket Status: '+socket.readyState+' (open)');
}
socket.onmessage = function(msg){
message('<p class="message">Received: '+msg.data);
}
socket.onclose = function(){
message('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
}
} catch(exception){
message('<p>Error'+exception);
}
}
The message function is simple: append the supplied text to chatLog. The socket event handlers include the opening paragraph tag and class, so the function only has to close the paragraph.
function message(msg){
$('#chatLog').append(msg+'</p>');
}
At this point the page can create a WebSocket connection and keep the user informed about its progress.

Send data
Rather than requiring a button click, listen for the Enter key and call send. The ASCII value for Enter is 13.
$('#text').keypress(function(event) {
if (event.keyCode == '13') {
send();
}
});
Here is the send() function:
function send(){
var text = $('#text').val();
if(text==""){
message('<p class="warning">Please enter a message');
return ;
}
try{
socket.send(text);
message('<p class="event">Sent: '+text)
} catch(exception){
message('<p class="warning"> Error:' + exception);
}
$('#text').val("");
}
The underlying call is just socket.send(), despite the surrounding UI checks.
Close the socket
Closing the socket takes a click handler on the disconnect button.

$('#disconnect').click(function(){
socket.close();
});
The complete JavaScript
$(document).ready(function() {
if(!("WebSocket" in window)){
$('#chatLog, input, button, #examples').fadeOut("fast");
$('<p>Oh no, you need a browser that supports WebSockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container');
}else{
//The user has WebSockets
connect();
function connect(){
var socket;
var host = "ws://localhost:8000/socket/server/startDaemon.php";
try{
var socket = new WebSocket(host);
message('<p class="event">Socket Status: '+socket.readyState);
socket.onopen = function(){
message('<p class="event">Socket Status: '+socket.readyState+' (open)');
}
socket.onmessage = function(msg){
message('<p class="message">Received: '+msg.data);
}
socket.onclose = function(){
message('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
}
} catch(exception){
message('<p>Error'+exception);
}
function send(){
var text = $('#text').val();
if(text==""){
message('<p class="warning">Please enter a message');
return ;
}
try{
socket.send(text);
message('<p class="event">Sent: '+text)
} catch(exception){
message('<p class="warning">');
}
$('#text').val("");
}
function message(msg){
$('#chatLog').append(msg+'</p>');
}
$('#text').keypress(function(event) {
if (event.keyCode == '13') {
send();
}
});
$('#disconnect').click(function(){
socket.close();
});
}//End connect
}//End else
});
Start the WebSocket server
The server has to be started from the command line. XAMPP includes a shell option for this. Open the XAMPP control panel, click Shell, and run:
php -q path\to\server.php

The WebSocket server is now running.
Try it
When the page loads, it attempts to establish a WebSocket connection. The code can be changed so that the user decides when to connect and disconnect. Once connected, the user can enter messages and receive responses from the server.

WebSockets are useful, but the API was still evolving when this pattern was current. Keep an eye on the W3C WebSocket API for changes.