HTML5 WebSockets Example

HTML5 WebSockets makes it possible to open a persistent connection to a server within a web-browser via javascript.

UPDATE: Mastering the new Spec-76 WebSockets handshake with PHP.

Websockets works already in the latest Webkit-browsers like Safari 5 and Chrome 5. Firefox 4 Beta 1 knows the Websocket-Object but it can’t open the connection :(

My Websocket test script sends the current mouse position via socket connection to the server and then receives all positions of all current open sockets and prints them to the browser-window. In other words, you can see the mouse cursors of the other users on the page.

var socket;
 
function init() {
	var host = "ws://84.38.67.247:8080/dev/websocket/server.php";
	try {
		socket = new WebSocket(host);
		socket.onopen = function(msg){ };
		socket.onmessage = function(msg){
			eval('var data = ' + msg.data + ';');
			for (userId in data) {
				if (data[userId].position) {
					var pos = data[userId].position.split(',');
					var color = data[userId].color;
					render(userId, pos[0], pos[1], color);
				}
			}
			dump(data);
		};
		socket.onclose = function(msg){ };
	} catch(ex){ console.log(ex); }
 
	$('body').bind('mousemove', function(evt){
		send(evt.clientX, evt.clientY);
	});
}
 
function render(u, x, y, c) {
	if ($('#'+u).length == 0) {
		$('
 
').appendTo('body');
	}
	$('#'+u).css('left', x+'px');
	$('#'+u).css('top', y+'px');
	$('#'+u).css('background', c);
}
 
function send(x,y) {
	var msg = x + ',' + y;
	socket.send(msg);
}

On the server side i use a PHP5 script. I have written my own server-class but it’s based on the work of the phpwebsocket project. The server.php instantiate the WebSocketServer object and contains the callback function.

New URL for Example: http://bohuco.net/labs/php-websocket-class/

http://bohuco.net/dev/websocket/

Source Codes:
WebSocketServer.php
server.php

48 thoughts on “HTML5 WebSockets Example”

  1. Firefox can’t open the connection for the same reason Chrome 6 dev can’t open the connection. You have implemented version -75 of the protocol (which Safari 5 and Chrome 5 use), while Firefox and Chrome 6 dev support version -76.

  2. Thanks zcorpan for your advice … i have recoded my class, now it works with the new Firefox 4 Beta too.

  3. Hey, nice introduction to websockets thanks :)

    I have successfully implemented some examples but they only work from localhost.
    How can i tell apache/php to allow socket connections beyond localhost?

  4. I don’t understand the need for the eval:
    [ eval(‘var data = ‘ + msg.data + ‘;’); ]

    why can’t you just do a real var data = msg.data?

  5. Hi skybinary,

    Please ensure that the socket is not just listening for localhost calls.
    e.g., let’s say you are working with port 8181. Then if you type within a terminal ‘netstat -an | grep LISTEN’ and
    you see something like this ‘127.0.0.1:8181′ that’s the root of your problem.
    So if you want to permit any incoming connection you should do something like this:
    $webSocket = new WebSocketServer(“0.0.0.0″, 8181, ‘process’);

  6. opening two windows with the example doesn’t seem to work.
    The first Window works but the second one not.
    Is it required and possible to set any parameter for the concerned window?

  7. After reloading both Browser-Windows it works and I get both cursers shown while the active one is correctly changeable while the other one is passive.
    In a list on the pic the IPs (surely the same) and the cursors are shown.

    Question is:
    1) how are the windows divided by the script
    2) why both windows had to be reloaded and why in the beginning just reloading the 2nd window didn’t show any cursor?

  8. Hi David, which browser (+ version) do you use? If you try with one chrome-window and one chrome inkognito window it should work … or two different browsers.

  9. Hello, very thanks you for this! work!
    But i’m too trying PHP WebSocket(http://code.google.com/p/phpwebsocket/) simple example(Chat) but don’t work and i’m get error: Error: INVALID_STATE_ERR: DOM Exception 11
    And status is: WebSocket – status 0

    Maybe know how to fix this ? :-)

    Thanks for this and Good Luck!

  10. Thanks Ldup for your question. I have nothing to do with this project, but i can see that the maintainer is working on the project and he usually answers questions very quick.

  11. Hi, i have a problem with a scripts that is almost the same as yours. The eval function of the very first message received from the server gives me an Unexpected token ILLEGAL error. But all the other messages after the first one work great. When I read the first message with a console.log(msg.data) there is absolutely nothing strange in this message. Is there something special with the first message sent by the server?

  12. Hi,
    i have the same problem as Yves : the first message sent by the server raise always a onerror event on the client, the others messages works fine after… really strange… (chrome version 8.0.552.224)
    Thank you

  13. Thanks for the comments, i can reproduce the problem and a quickfix is to wrap the eval in a try/catch block. i will look into the problem later, there seems to be a “hidden” char in the response …

  14. Do you plan to ad “wss” feature?
    this is the only option working for me behind firewall, simple “ws” fail to connect

  15. How does this work? From the little I know about php the script gets called each time a browser opens an page. I understand that the server.php calls run so it doesn’t return like simple php scripts, but why aren’t there server instances for every user calling this script? Is it that the “require_once” makes only the first call of the script work and the other silently fail so there is only one server object? I don’t understand why there are not many WebSocketServer objects with each having only 1 client.
    (Sorry for my bad english, I’m out of training)

    1. that is not a”typical” php-script which is opened in the browser via http … its a command line script, you can run it for example under linux oder mac osx via “php -q server.php” (if php is installed on the computer) … in this script is a endless-loop, so it runs until it is stopped with Crtl-C … hope that helps :)

  16. I have problem with this function – private function wrap($msg=””) { return chr(0).$msg.chr(255); }

    I get all info and at the end is this char – ÿ which is chr(255).
    Therefore at the client side I get error – “Invalid char”. If I remove “chr(255)” char “ÿ” is removed, but client side doesn’t work either.

  17. Found a solution: by js, just use the replace function of javascript example, assume msg is the string returned by websocket.message function

    msg = $.parseJSON(msg.data.replace(”, ”));

    or, without jquery:

    msg = JSON.parse(msg.data.replace(”, ”));

    Hope someone will find this helpful to someone.

  18. Sorry, but the ascii code got interpreted.
    Between the first ” in the code, insert
    0
    without the space between, it will work, giving back your Json content.

  19. Fixed memory leak on message quantity:

    Class WebsocketChatMessage {

    ….
    // Added destructor
    public function __destruct() {
    echo “menya stiraut ” . $this->text . “n”;
    unset($this->text);
    unset($this->username);
    unset($this->timestamp);
    }
    // End of added destructor

    ….

    }

    and in

    Class WebsocketChat {


    //added message limit
    private $maxmessage = 10;
    //End of changes in variables

    ….
    if ($msg->action == ‘chat’) {
    $text = filter_var($msg->text, FILTER_SANITIZE_STRING);
    $lastMessage = new WebsocketChatMessage($user->data[‘username’], $text . ” memory state ” . memory_get_usage(), time());

    $user->data[‘message’][] = $this->messages[] = &$lastMessage;

    //Begin of cleaning Checking if messages is too much

    if (count($this->messages) > $this->maxmessage) {
    //Cleaning old messages
    array_splice($this->messages, 0, 1);
    array_splice($user->data[‘message’], 0, 1);
    }
    //End of Cleaning
    }
    }
    }

    now the memory usage is clean and correct the script will live!

  20. I got ‘StartListening: Unable to bind socket – Address already in use.’ error when php -q server.php command execute in terminal.So web socket is not working.

    Please give me direction how can i test web socket properly working or not.

    Thank You

  21. function hybi_decode($data){
    $bytes = $data;
    $data_length = “”;
    $mask = “”;
    $coded_data = “” ;
    $decoded_data = “”;
    $data_length = $bytes[1] & 127;
    if($data_length === 126){
    $mask = substr($bytes, 4, 8);
    $coded_data = substr($bytes, 8);
    }else if($data_length === 127){
    $mask = substr($bytes, 10, 14);
    $coded_data = substr($bytes, 14);
    }else{
    $mask = substr($bytes, 2, 6);
    $coded_data = substr($bytes, 6);
    }
    for($i=0;$i<strlen($coded_data);$i++){
    $decoded_data .= $coded_data[$i] ^ $mask[$i%4];
    }
    return $decoded_data;
    }

    function hybi_encode($data)
    {
    $frame = Array();
    $encoded = "";
    $frame[0] = 0x81;
    $data_length = strlen($data); if($data_length > 8;
    $frame[3] = $data_length & 0xFF;
    } for($i=0;$i<sizeof($frame);$i++){
    $encoded .= chr($frame[$i]);
    } $encoded .= $data;
    return $encoded;
    }

  22. function hybi_decode($data){
    $bytes = $data;
    $data_length = “”;
    $mask = “”;
    $coded_data = “” ;
    $decoded_data = “”;
    $data_length = $bytes[1] & 127;
    if($data_length === 126){
    $mask = substr($bytes, 4, 8);
    $coded_data = substr($bytes, 8);
    }else if($data_length === 127){
    $mask = substr($bytes, 10, 14);
    $coded_data = substr($bytes, 14);
    }else{
    $mask = substr($bytes, 2, 6);
    $coded_data = substr($bytes, 6);
    }
    for($i=0;$i<strlen($coded_data);$i++){
    $decoded_data .= $coded_data[$i] ^ $mask[$i%4];
    }
    return $decoded_data;
    }

    function hybi_encode($data)
    {
    $frame = Array();
    $encoded = "";
    $frame[0] = 0x81;
    $data_length = strlen($data); if($data_length > 8;
    $frame[3] = $data_length & 0xFF;
    } for($i=0;$i<sizeof($frame);$i++){
    $encoded .= chr($frame[$i]);
    } $encoded .= $data;
    return $encoded;
    }

  23. Hi
    Please anyone who knows post how to get the “New URL for Example” working.
    I love to see working things before troubleshooting it on my pc later.

    I love websockets!
    matt

  24. Hi
    Please anyone who knows post how to get the “New URL for Example” working.
    I love to see working things before troubleshooting it on my pc later.

    I love websockets!
    matt

Comments are closed.