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

  • Pingback: Tweets that mention HTML5 WebSockets Example | bo! hu? co. -- Topsy.com()

  • zcorpan

    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.

  • Pingback: HTML5 websockets con PHP | Sentido Web()

  • DerFichtl

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

  • Pingback: Michael Feichtinger’s Blog: HTML5 WebSockets Example | Development Blog With Code Updates : Developercast.com()

  • Pingback: Michael Feichtinger’s Blog: HTML5 WebSockets Example | PHP()

  • http://www.polprav.blogspot.com/ deekobraz

    it was very interesting to read.
    I want to quote your post in my blog. It can?
    And you et an account on Twitter?

  • http://na skybinary

    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?

  • jsnoob

    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?

  • DerFichtl

    msg.data contains JSON as string … with eval i convert it to a real javascript object

  • Pingback: HTML5 websockets con PHP | Maya Digital()

  • deltaLeo

    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’);

  • Pingback: HTML 5: un esquema de enlaces()

  • http://www.bruchmann-web.de David

    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?

  • http://www.bruchmann-web.de David

    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?

  • DerFichtl

    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.

  • Ldup

    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!

  • DerFichtl

    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.

  • Pingback: PHP Websocket Class new Version  | BOHUCO()

  • Yves

    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?

  • cyberbobjr

    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

  • DerFichtl

    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 …

  • Macs

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

  • http://www.google.com adailton

    an error is occurring on the server can not answer the socket.

    php_exif.dll disabled the dll file that was giving error zend parameter in the library.

    I am using windows xp and windowdows 7 the same error.

    I’m from Brazil my net is networked to another pc

    image the error : http://img218.imageshack.us/i/imagemyj.gif/

  • http://www.google.com adailton

    solve the problems agora ta All ok

    thanks for posting can clear my doubts valew old ^ ^

  • http://www.google.com adailton

    thanks for posting this beautiful work.
    is being dealt a new server database that connects with
    javascript
    his name is jwebsocket a very good api
    to be compatible with Internet Explorer 6,7,8,9.

    http://jwebsocket.org/

  • DigitalLife

    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)

    • DerFichtl

      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 :)

  • Edska

    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.

  • Roy

    Hey, i’m tryng to get this to work.
    It still doesnt, and the reason is that crappy ‘hidden character’ that prevents json to be effectively interpreted, thus not appearing in the reply itself.
    here is the discovery:
    http://stackoverflow.com/questions/4880273/character-in-front-of-websocket-message
    But not the solution.I’m still looking for a good one to implement, or a way to get rid of that piece.

  • Roy

    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.

  • Roy

    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.

  • Pingback: Javascript Client Connecting To Phpserver By Html5 Websocket()

  • elennaro

    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!

  • elennaro

    now who can help me with wss?
    i mean SSL for web stocket workaround.

  • http://sanjeevkumarjha.com.np/ Sanjeev

    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

  • Digitalpassion

    How much better is this than Ajax JSON callbacks?

  • Digitalpassion

    How much better is this than Ajax JSON callbacks?

  • http://twitter.com/filiwiese Fili Wiese

    Could you please update the code to support the new hybi-10 draft?

  • http://twitter.com/filiwiese Fili Wiese

    Could you please update the code to support the new hybi-10 draft?

  • Pingback: Van Nuys Bail Bonds()

  • http://www.facebook.com/arturs.birzgals Arturs Birzgals

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

  • http://www.facebook.com/arturs.birzgals Arturs Birzgals

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

  • Pingback: HTML5 WebSockets Example | KC-TUTOR()

  • Paromatt

    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

  • Paromatt

    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

  • Elbriga

    source code not showing

  • m3ta

    “rather good than”? Go lean some basic english, fucktard.