Start Using HTML5 WebSockets Today

Start Using HTML5 WebSockets Today

Tutorial Details
  • Topic: WebSockets
  • Difficulty: Easy
  • Estimated Completion Time: 1 Hour

One of the coolest new features of HTML5 is WebSockets, which let us talk to the server without using AJAX requests. In this tutorial, we’ll review the process of running a WebSocket server in PHP, and then building a client to send and receive messages to it over the WebSocket protocol.


What are WebSockets?

WebSockets is a technique for two-way communication over one (TCP) socket, a type of PUSH technology. At the moment, it’s still being standardized by the W3C; however, the latest versions of Chrome and Safari have support for WebSockets.


What do WebSockets Replace?

Websockets can replace long-polling. This is an interesting concept; the client sends a request to the server – now, rather than the server responding with data it may not have, it essentially keeps the connection open until the fresh, up-to-date data is ready to be sent – the client next receives this, and sends another request. This has its benefits: decreased latency being one of them, as a connection which has already been opened does not require a new connection to be established. However, long-polling isn’t really a piece of fancy technology: it’s also possible for a request to time-out, and thus a new connection will be needed anyway.

Many Ajax applications makes use of the above – this can often be attributed to poor resource utilization.

Wouldn’t it be great if the server could wake up one morning and send its data to clients who are willing to listen without some sort of pre established connection? Welcome to the world of PUSH technology!


Step 1: Get the WebSocket Server

This tutorial will focus more on the client building rather than server implementation.

I’m using XAMPP on Windows 7 to run the PHP server locally. Grab a copy of phpwebsockets which is a WebSocket server in PHP. (Note: I experienced some problems with this version, I made some changes to it and will including it in the source files) There are various WebSocket implementations; if one doesn’t work, you can try another or just continue with the tutorial.

Start the Apache server


Step 2: Change URLs and Ports

Change the server according to your setup, for example in setup.class.php:

public function __construct($host='localhost',$port=8000,$max=100)
{
	$this->createSocket($host,$port);
}

Browse through the files and make changes where appropriate.


Step 3: Start Building the Client

Lets get a basic template up; this is my client.php file:

<!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>​

So in this code we’re creating a simple template: we have a box for the chat log, an input box, and one disconnect button.


Step 4: Add Some CSS

Nothing fancy, just space some elements out.

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;
}

Step 5: WebSocket Events

First, let’s try and understand the idea of WebSocket events.

The Events

We’ll be using three events:

  • onopen: When a socket has opened
  • onmessage: When a message has been received
  • onclose: When a socket has been closed

But how can we implement this?

First create a WebSocket object

var socket = new WebSocket("ws://localhost:8000/socket/server/startDaemon.php");

And checking for events is as simple as:

socket.onopen = function(){
	alert("Socket has been opened!");
}

But what about when we receive a message?

socket.onmessage = function(msg){
	alert(msg);	//Awesome!
}

However, let’s avoid using alert boxes, and actually integrate what we’ve learned into the client page.


Step 6: JavaScript

Ok, so let’s get started. First we put our code in jQuery’s document ready function, then we check whether the user has a WebSockets-enabled browser. If they do not, we append a link to Chrome in the HTML.

$(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

	}
});

As you can see, if the user has WebSockets then we call a connect() function. This is the core of the functionality: we’ll start with the open, close and receive events.

We’ll define the URL of our server

var socket;
var host = "ws://localhost:8000/socket/server/startDaemon.php";

Wait, where’s the http in that URL? Oh right, it’s a WebSocket URL, so it’s using a different protocol. Here’s a breakdown of the pieces of our URL:

Let’s continue with our connect() function. We will put our code within a try/catch block; so if something goes wrong, we can let the user know. We create a new WebSocket, and pass the message to a message function which I’ll explain later. We create our onopen, onmessage and onclose functions. Note that we also show the user the socket status; this is not necessary, but I’m including it here as it can be helpful for 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 fairly simple, it takes in some text that we want to show the user and appends it to the chatLog. We create the appropriate class for paragraph tags in the socket event functions which is why there is only one closing paragraph tag in the message function.

function message(msg){
	$('#chatLog').append(msg+'</p>');
}

So Far…

If you’ve been following up to this point, well done! We’ve managed to create a basic HTML/CSS template, create and establish a WebSocket connection and keep the user updated as progress was made with the connection.


Step 7: Sending Data

Now rather than having a submit button, we can detect when the user presses return on their keyboard, and run the send function. The ’13′ you see below is the ASCII key for the enter button.

$('#text').keypress(function(event) {
    if (event.keyCode == '13') {
   		send();
    }
});

And here’s 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("");

}

Remember what you see above may be a chunky bit of code, but in reality, the code we really need is:

socket.send(); //Thanks JavaScript

The extra code is doing a number of things: detecting if the user didn’t enter anything but still hit return, clearing the input box, and calling the message functions.


Step 8: Closing the Socket

Closing the socket is fairly straightforward: attach a click handler to our disconnect button and we’re done!

$('#disconnect').click(function(){
	socket.close();
});

The Completed 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

});

Step 9: Run the WebSocket Server

We will need command line access. Luckily, XAMPP has a handy shell option. Click ‘Shell’ on the XAMPP control panel, and type in:

php -q path\to\server.php

You have now started a WebSocket server!


Finished

When the page loads, a WebSocket connection will attempt to be established (try editing the code so the user has connect/disconnect option). Then, the user can enter messages and receive messages from the server.


That’s it!

Thanks for reading; I hope you enjoyed this tutorial! Remember, as exciting as WebSockets may be, things may change. You can refer here to keep up to date on the W3C WebSocket API.

Tags: html5
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.google.com adailton

    how to program socket
    google frame?

    tested but did not work which protocols are supported?

  • Inavac

    Hello, Can somebody help me??? I can’t make run this…

    Safari

    Socket status(0)
    …5 seconds…
    Socket status(3)(close)

    The console:
    Resurce id #9 CONNECTED!
    Requesting handshake…
    Handshaking…
    Resource id #9 disconnected!

    Chrome:
    Socket status(0)
    …. and never connect…

    The console:
    Resurce id #9 CONNECTED!
    Requesting handshake…
    Handshaking…
    ….. and never pass of this line.. :L…..

  • http://www.google.com adailton

    grounds of error is because the protocols used in this tutorial was 75
    now changed to 76.

    use this srvidor this site: http://bohuco.net/blog/2010/07/html5-websockets-example/

    socket ainda é uma grande aventura talvez dor de cabeça por causa das atualizaçoes dos protocolos feto pelo webkit entao o melhor a se fazer é implementar socket js + xml + flash, senao voce vai sofrer com as atualizaçoes do chrome.

  • Neil

    “Welcome to the world of PUSH technology!” Really? 1997 called… it wants its crappy ideas back – and the buzzwords that go with them!

    • James

      Cute… now run along and let the grown ups play

    • Surender Dagar

      lol nice to have a new name ”
      Push Technology”

  • Ben

    Hey,

    Im wondering if i shall try to implement this on our chat or wait some more years?

    Are they planning to get this to work in the couple of month in all new browsers?

    Have been watching some solution within comet ajax programming but this seems better if it just start to work well in the close future.

    //Ben

    • http://www.marioplanet.com Zach

      I wish I had a better answer for you, but all I want to say is I’m really excited about WebSockets in a chat web app.

      When coupled with node.js an extremely succinct, fast and scalable chat server or web app seems like it can be constructed with the utmost ease.

      Quite exciting times!

  • http://sanjeevkumarjha.com.np sanjeev

    I am using your complete package to connect with web socket but fail to implement.
    My code is like this:

    if( ($this->master=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) master));
    }

    when I run my php file which create connection with web socket, I got error
    Fatal error: Call to undefined function socket_create() in the line
    if( ($this->master=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0 )

    Therefore i am not able to connect web socket and also not able to get response message from socket because Socket Status: 3 (Closed) is displaying in my browser when run client page .

    Have you got an idea what is missing?
    Thank you in advance.

  • vietpnk53

    I run your scipt and have exception in code javascript:

    try{
    socket.send(text); // exception here
    message(‘Sent: ‘+text)
    catch(exception){
    console.log(exception); ///~~~~> show exception : Error: INVALID_STATE_ERR: DOM Exception 11 …
    message(”);
    }

    help me!
    thanks!

    • Surender Dagar

      This is very nice technique to having communication over protocol,.. and we can avoid the traffic on the network…

  • Alex

    Whats the use of websocket? if well just to have localhost. hastle free

  • http://www.facebook.com/xymon.sinclair Xymon.Sinclair

    Alright, I can’t seem to get it to connect to the websocket, i’m a complete noob with this websocket junk and could use some help. If anyone has got this tutorial to run successfully, please message me @ http://www.facebook.com/xymon.sinclair and we’ll have a chat, that’d be just beautiful thanks :)

    • Tillmann

      If you’re a complete newbie on what grounds do you call it “junk”?

  • roody-poo

    how do I do javascript to javascript then?

  • http://john.plainfast.com John

    The correct link to phpwebsocket is http://code.google.com/p/phpwebsocket/

  • http://flaviowd.wordpress.com Flavio

    Hello,

    I tested your cod, but always get this message:

    # php -q htdocs\socket\server\startDaemon.php
    2011-09-26 08:03:30 System: Socket Resource id #7 created.
    2011-09-26 08:03:30 System: Socket bound to localhost:8000.
    2011-09-26 08:03:30 System: Start listening on Socket.
    2011-09-26 08:03:40 WebSocket: Resource id #8 CONNECTED!
    2011-09-26 08:03:40 WebSocket: Requesting handshake…
    2011-09-26 08:03:40 WebSocket: Handshaking…
    2011-09-26 08:03:40 WebSocket: Done handshaking…
    2011-09-26 08:03:40 WebSocket: Resource id #8 disconnected!

    How can I fix this?

    Tks in advance

  • Dan M

    First off, thanks for the excellent write up. I am having the same problems as Flavio however… looking forward to some resolution!

  • Anon

    Several mistakes in socketWebSocket.class.php. No arguments are passed in the __construct function, so if you try and change the host or port in startDaemon.php there is no effect. Headers returned are incorrect, and entirely missing handling of the Sec-WebSocket-Key header, which is why it isn’t working for anyone.

    http://en.wikipedia.org/wiki/WebSocket#draft-ietf-hybi-thewebsocketprotocol-06

    Fix the header to that, and you may have more luck.

  • anonymous

    Hello,

    I tested your code but the websocket server connection is closing without any message transfer.

    php -q C://AppServ/www/websocket/server/startDaemon.php

    2011-11-04 08:03:30 System: Socket Resource id #7 created.
    2011-11-04 08:03:30 System: Socket bound to localhost:8000.
    2011-11-04 08:03:30 System: Start listening on Socket.
    2011-11-04 08:03:40 WebSocket: Resource id #8 CONNECTED!
    2011-11-04 08:03:40 WebSocket: Requesting handshake…
    2011-11-04 08:03:40 WebSocket: Handshaking…
    2011-11-04 08:03:40 WebSocket: Done handshaking…
    2011-11-04 08:03:40 WebSocket: Resource id #8 disconnected!

    How can i fix this problem…… please help to get the solution

    Thanks & Regards.

  • obscuremind

    New phpwebsocket with Hybi-17 protocol.

    http://www.wilky.it/Shared/phpwebsocket.zip

    • http://www.yoannmoinet.com YoannM

      WOW !!! Thank you so much for that… I was tearing my hairs off with websocket for 2 days now.
      Got your source, launch it, worked perfectly in Chrome and Firefox.
      Thx so much, I think I love you right now.

    • bell418

      Yes! this one works! Thanks a lot. :)

      • stillyoung456

        the hybi-17 works in Firefox 19.0.2, but not in Chrome 27.0.1453.12

    • Sumeet

      Hey I am tried with ur code too but the prompt shows me this..
      ————————————————-
      C:\xampp\htdocs\phpwebsocket>php -q websocket.demo.php
      Server Started : 2012-07-25 05:50:05
      Listening on : localhost 12345
      Master socket : Resource id #5
      ——————————————-

      Whenever I send any msg from the browser i dont see any msgs on the promt..
      Where m I going wrong ?
      I am running the client in Crome.

  • Amir

    It’s very great informative stuff shared here useful one for many others who needs this kind of stuff,… scjp braindumps scmad dumps latest scwcd dumps security+ dumps sk0-003 latest dumps latest sscp dumps st0-099 dumps st0-29b braindump

  • http://lfs.net/ Mark Tomlin

    Websockets can replace long-polling, but it should not. In many cases, Server Side Events with EventSource should replace the push nature. WebSockets is used for a two-way (technically known as a full-duplex) connection. Where EventSource tells the client what’s going on, WebSockets allows for a conversation.

  • http://www.chzcb.com chzcb

    Thanks, right code source: http://code.google.com/p/phpwebsocket/

  • mk_89

    Question: for backward compatibility should the implemented website check what browser the user has in order to determine whether websockets is suitable for them, and if it is not suitable should their be an alternative (backward compatibility) such as long-polling? Thanks.

  • Carla

    Hi I’m using Google Chrome 16.0.912.77, and when I run the client, I saw this … Socket Status: 3 (Closed)
    I’ve also tried other examples (phpwebsockets), but It always connect and diconnect inmediatly.
    Could you help me.

    • Alli

      I am having the same problem… I’m trying it in Chrome 17.0.963.56 on localhost.

      Server:

      {PATH}>php startDaemon.php
      2012-02-20 07:02:51 System: Socket Resource id #7 created.
      2012-02-20 07:02:51 System: Socket bound to localhost:8000.
      2012-02-20 07:02:51 System: Start listening on Socket.
      2012-02-20 07:03:01 WebSocket: Resource id #8 CONNECTED!
      2012-02-20 07:03:01 WebSocket: Requesting handshake…
      2012-02-20 07:03:01 WebSocket: Handshaking…
      2012-02-20 07:03:01 WebSocket: Done handshaking…
      2012-02-20 07:03:01 WebSocket: Resource id #8 disconnected!

      Client:

      Socket Status: 0
      Socket Status: 3 (Closed)

      Error:
      Error during WebSocket handshake: ‘Sec-WebSocket-Accept’ header is missing

  • Bazzbos

    So we’ve regressed to forcing users to abandon their preferred browser just to make this work? Why are we moving backwards?!?! This is why I hate html5… none of this stuff is standard on anything yet. There’s always caveat with this new stuff. AJAX works just fine I’m not convinced of web sockets.

  • http://mikesmullin.com Mike Smullin

    This is good. The next step is to get a PHP server-side port of Socket.io which introduces cross-browser compatibility for websockets via graceful degradation to long-polling. I wonder how competitive the latest php-cli running in a loop without apache is versus ruby eventmachine and node.js? someone should benchmark.

  • Makram Chehayeb

    Hi I have a python server on my machine binding a socket to its
    IP ADDRESS and to a port that I chose(50001) I would like to build a
    simple web application that allows me only to send a string from a
    websocket to my raw TCP socket what should I do? I am actually trying to implement a web Remote Control for my nao robot any help will be much appreciated

  • mitya

    The tutorial is very vague when it says to set the host/ports to your requirements. What precisely does this mean to those of us that are new to sockets?

    I tried to get this demo working, but I can’t get any response when I post a message, e.g. ‘hi’.

    I loaded up the startDeamon manually and I get a PHP error saying socket_bind() can’t bind to host – unknown host.

    I access my localhost in the browser via localhost:33, so presumably localhost is the host and 33 is the port, but setting these in the startDeamon script just brings up the error.

  • ThisWasteOfTime

    Full of errors. Terrible tutorial. Needs many updates. Apparently, the author didn’t take time to test it.

  • ThisWasteOfTime

    What it seems like to me is that this shows how to host a chat. That’s useless. You don’t need websockets to host a chat. It doesn’t show any ‘long polling of the server’, though. It’s polling the client. Polling the client can be done without ajax or anything. There’s no option, in this tutorial, to send info from the server to the net. In other words, this doesn’t demonstrate ‘push’ technology. It only shows chat without page refresh. It’s a useless example of websockets technology. AJAX/jQuery without websockets would be better for this usage case because the websocket server is a waste of system resources when nothing is actually being pushed.

  • ThisWasteOfTime

    What it seems like to me is that this shows how to host a chat. That’s useless. You don’t need websockets to host a chat. It doesn’t show any ‘long polling of the server’, though. It’s polling the client. Polling the client can be done without ajax or anything. There’s no option, in this tutorial, to send info from the server to the net. In other words, this doesn’t demonstrate ‘push’ technology. It only shows chat without page refresh. It’s a useless example of websockets technology. AJAX/jQuery without websockets would be better for this usage case because the websocket server is a waste of system resources when nothing is actually being pushed.

  • Potado

    Awesome!

  • http://andrewensley.com/ Andrew Ensley

    FYI: The link to phpwebsockets is dead. Would love to see the socket.io tutorial. I guess I need to go premium.

  • http://blog.01tchat.com Peter

    Very nice tutorial!

  • John Holmes

    Great article. Now you can use WebSockets with small embedded devices. Check this out: http://handheldsci.com/em. It implements websockets in a micro-controller and works with all browsers.

  • http://instropy.com Oscar Nevarez

    I´ve patched the sourcecode according to the latest specificacions of WebSockets, mainly rewrite the handshake method. Can be downloaded from here: http://xb-interactive.com/webapps/websockets/webSocketNtus.rar

  • Jatin

    link to phpwebsocket is brokeen

  • Chris

    This example actually does not work at all. Also the ‘fixed script’ by Oscar Nevarez does not work. Both are full of very basic bugs. If someone has an actually working example of this, please share.

  • http://www.devtrix.net/sliderman/ Devtrix.net

    I was trying to understand why some demo apps don’t work for me.
    The reason was that my anti-virus was silently blocking all my browsers for using sockets.
    Hope it will help some people to get it to work.
    Here’s an old-school game which works using html5 and sockets: http://browserquest.mozilla.org/
    Nice article, cheers.

  • http://www.yarsi.ac.id IDRIS

    very nice artikel … tkhanks a lot

    Idris

  • Trylobot

    Your link to phpwebsocket has a typo.

    The project is currently called phpwebsocket

    and the link is http://code.google.com/p/phpwebsocket/ (you had an extra ‘s’)

  • Angelos

    i only get this:

    Socket Status: 0

    Socket Status: 3 (Closed)

    any idea how to fix it?

    • Angelos

      i copy paste the source code file on my server and then run through ssh the startdaemon

  • http://twitter.com/gmilby Gregory Milby

    re: php -q pathtoserver.php …Did you mean to reference startDaemon.php instead?

  • Sven

    So, Umar Hansa. How well do you think your ‘tutorial’ came across based on the comments? When you ‘try’ to communicate complex stuff to the public (and yes, web tech and the like IS complex), please make an effort and be VERY specific when you do. The web is already FULL of useless geeks showing off their skills – or lack of when talking communication skills.

  • pablo

    hi a get an error in shell console “Strict Standards: Only variables should be passed by reference in C:UserspabloDocumentsNetBeansProjectssocket3serversocketWebSocket.class.php on line 35″.

    I dont know what it’s mean, In browser console i have another error :

    firefox cannot connect with server: ws://localhost:8000/socket3/server/startDaemon.php.

    var socket = new WebSocket(host);

    any solutions what it is?

    • Arfian Hidayat

      this my problem too, any solution?

  • Man Singh

    I just wanted to know how can I change or what should I change the message sent goes to all clients connected .