PHP Websocket Server/Client nach Draft hybi-10

Vor ein paar Tagen habe ich ja schon einen Websocket-Client hier veröffentlich, welcher Draft hybi-00 unterstützt. Kurz danach veröffentlichte google jedoch eine neue Version von Chrome. In Chrome 14 hat google nun den Websocket-Draft hybi-10 implementiert und dort hat sich vieles grundlegend geändert. Neben einem neuen Handshake werden auch die Datenframes komplett neu codiert.
Ich habe meine Client-Klasse entsprechend angepasst und möchte sie natürlich wieder hier präsentieren, da sie dem ein oder anderen Entwickler sicherlich helfen wird. Desweiteren habe ich die “Connection-Klasse” des Websocket-Servers von Nico Kaiser so angepasst, dass sie auch den hybi10-Draft unterstützt.

Viel Spass bei basteln :)

HINWEIS: Da der Server aktuell ständig weiterentwickelt wird habe ich ein Repository auf Github angelegt. Bitte den jeweils aktuelle Code verwenden: https://github.com/lemmingzshadow/php-websocket

UPDATE: As the project is constantly updated and improved I created a repository on github. Please get the code here: https://github.com/lemmingzshadow/php-websocket

Fork me on GitHub
46 Responses to PHP Websocket Server/Client nach Draft hybi-10
  1. Oliver Reply

    Wenn Du die Dateien nicht .txt, sondern phps nennst, sollte das besser aussehen. :-D

  2. Sven Reply

    Seltsamerweise bekomme ich beim Senden eines Frames immer die Fehlermeldung, daß der String nicht UTF8 encodiert sei… jedoch nur bei einer Länge > 125 ….

  3. Lemmingz Shadow Reply

    In der Tat, da war noch ein kleiner Fehler in der Encode-Methode. Hab’s korrigiert. Danke für den Hinweis.

  4. Sven Reply

    Keine Ursache, ist zur Zeit schwierig, gutes Material zu den neuen Versionen zu bekommen, ich habe auch eben erst meine Klasse mit ein paar Weichen umgestellt. Ein Chat von mir läuft auf Websockets, Durch das plötzliche Update bei Chrome lief der bei den meisten natürlich nicht mehr.

    Naja, jetzt gehts wieder …

    Das Sheet hatte mich nur etwas konfus gemacht mit den Pasrsen der Frames.

  5. 1412 Reply

    using Chrome 14 and 16.. i can connect to socket server

    but cannot send data, socket select doesnt detect any change when data is sent, can you help me?

  6. Lemmingz Shadow Reply

    Sry but i never had this problem. I’m using the modified websocket-server by Niko Kaiser (metioned above) and it works fine with Chrome 14. For tests i use the these little HTML-File: http://lemmingzshadow.net/files/2011/09/client.html.txt (Needs jquery). Maybe it will help you to analyze you problem.

  7. Gustavo Reply

    Thanks!
    The decoding part is working fine,
    But I’m having problem with the Encode…

    The console in Chrome shows “Received unexpected continuation frame.”
    Chrome version 16.0.889.0 (dev)

  8. Lemmingz Shadow Reply

    Hmm, that’s weird. As you can see in the encode function the first byte of the encoded data is always set to 0×81 or 1000 0001. This makes the opcode part 0001 which represents a text-frame. (Cotinuation frame would be 0000)
    So i don’t think there is an error in the encoding function. But i currently don’t have Chrome 16 installed to test. Will do that tomorrow e.g. to check out if i get the same error.
    Perhaps in the meantime somebody else has a hint or can confirm that problem.

  9. Lemmingz Shadow Reply

    Just as an info: Firefox 7 was just released and supports websocket draft hybi-10.
    From the request header:

    Sec-WebSocket-Version: 8
  10. Gustavo Reply

    err… my bad, I was seding a chr(0) in the handshake…

  11. Lemmingz Shadow Reply

    I checked that and it seems the error message “Received unexpected continuation frame.” in most cases appears if you use Chrome >= 14 on a Websocket-Server which does not support hybi-10.

  12. Tijmen Scheifes Reply

    Great fix Lemmingz Shadow, works fine.

    For everyone who wants to send/receive messages over 4KB, adjust Server.php at line 43 and change 4096 to a higher value. If you don’t, the script will split the message in multiple messages and this doesn’t work as it should (with encryption messages are broken and without encryption some characters are missing.

  13. 1412 Reply

    its ot working for me, http://lemmingzshadow.net/files/2011/09/client.html.txt
    not work too, its connected but it wont receive nor send any data to socket server

  14. Rodrigo Reply

    Hello Simon!!

    I’d like to thank you for sharing your code!!

    I was reading the protocol to encode/decode …

    Thanks!!
    Rodrigo

  15. Jonny Reply

    Wow, very useful! Thanks so much!

  16. 1412 Reply

    after countless try and error effort, i take conclusions that its the browser that doesn’t bug send and receive data, cuz after using websocket bauglir server i also meet this bug

    i am using chrome 16.0.8 and firefox7, is anyone else success using websocket?

  17. Lemmingz Shadow Reply

    Can’t tell if it works with chrome 16 as I alsoways use stable versions, so try chrome 14 which works fine here.

    Further as I’m constantly playing around with the websocket-server I decided to fork the original one on github. You can find the latest version on: https://github.com/lemmingzshadow/php-websocket

    But please be aware that it is an early beta :)

  18. 1412 Reply

    take a look to this screenshoot
    http://img204.imageshack.us/img204/9961/chromesocket.png

    downgrading using chrom 14, and using your https://github.com/lemmingzshadow/php-websocket, but still no luck,

    could you give me your success screen shoot?

  19. Lemmingz Shadow Reply

    Can’t imagine a screenshot will help, but here is one of my desktop having the “webchat” running in chrome:
    http://img841.imageshack.us/img841/276/websocketscreen.jpg

    Btw. could it be some kind of firewall or other protection software wich blocks some traffic?

  20. Jan Reply

    Tausend Dank!! :-)

  21. 1412 Reply

    oh yes!

    before i use EasyPHP, and when i try using PHP standallone from php.net, it now working,

    thanks for all your help, now ill continue to develop my app :D

  22. [...] PHP Websocket Server/Client nach Draft hybi-10 GitHub Repository [...]... siriux.net/2011/11/php-websocket-server-with-hybi-10
  23. Karel-Jan Reply

    The current version is working in Chrome and Firefox, but not in Safari. nicokaiser version was working in Firefox and Safari but not in Chrome. Can these two be combined so it works in every browser?

    And does anyone have an idea when we can use this in production? And are there production alternatives?

    • Lemmingz Shadow Reply

      I have not yet tested my server in Safari. Will do that as soon as I’ve time for that.

      I currently don’t know a websocket server implemented in PHP that i would recommand for productional use, but you can check Socket.IO which is used by some big websites: http://socket.io/

  24. Lemmingz Shadow Reply

    I just tested Safari version 5.1.1 and it does not work cause it still uses the websocket protocol from draft hybi-00. This protocol is deprecated at not supported by this webserver anymore.

  25. lame Reply

    hi, there is a bug if websocket times out. It goes like this… dont know where report this bug :)

    PHP Warning: socket_recv(): unable to read from socket [110]: Connection timed out in Server.php on line 68
    PHP Warning: socket_write(): unable to write to socket [32]: Broken pipe in Connection.php on line 163
    PHP Warning: socket_close() expects parameter 1 to be resource, boolean given in Connection.php on line 209
    PHP Notice: Undefined offset: 0 in Server.php on line 106
    PHP Fatal error: Call to a member function getClientId() on a non-object in Server.php on line 107

  26. Vince Reply

    Does anyone have an issue with the server dying after ten minutes? Any way around the timeout issue?

  27. Lemmingz Shadow Reply

    Normally there is no timeout in phps cli-mode. You should check the php.ini used in by php-cli for any timeout/security settings.

  28. Vince Reply

    Lemmingz, can I email you the PHP log dump that occurs when the timeout happens? It begins like this, but goes (way) on:

    PHP Warning: socket_recv(): unable to read from socket [104]: Connection reset by peer in php-websocket/server/lib/WebSocket/Server.php on line 52

    I haven’t figured out why it crashes yet. The server doesn’t entirely crash, but any clients connected to that socket URL are lost. server.php begins infinitely throwing errors, and I have to bounce server.php to return everything to normal.

    I’ve compared code, but I’m not sure how Nico’s original library handled this, and why this doesn’t happen with his library. I do notice that with his though, at the timeout mark there seems to be a close/open again with the socket.

    I can send you the dump, or you can try and duplicate the issue. It seems fairly easy to duplicate. Also, I’ve merged some code into yours so that it now works in Safari and iOS too. Let me know if you’re interested in that.

    Cheers.

  29. Lemmingz Shadow Reply

    Hi,

    are you sure you’re using the latest version of my server from github? There was a problem when a client disconnects without sending a close frame. I fixed that in this revision: https://github.com/lemmingzshadow/php-websocket/commit/af3bdd48274b05f027d921b02134a278eca28fd4

    Please check if you have this modifications in your code.

  30. Vince Reply

    Hmm, in that case, I’m not. In fact, I believe I am several versions back. Sorry if this is a dumb question, but is there any way to tell which release I currently have? I cannot find version numbers in the code anywhere.

    Thank you!

    • Lemmingz Shadow Reply

      …is there any way to tell which release I currently have? I cannot find version numbers in the code anywhere.

      Sry currently i don’t have a version number in the project. Due to the fact the server is still in develeopment i’m just to lazy to update a version number on every commit. Just download the latest version and you should be fine.

      And btw.: Great to hear you like this projekt :)

  31. Vince Reply

    Also, THANK YOU for this outstanding library. You should setup a donation button because I would be more than happy to donate for using this excellent library. From one developer to another, thank you.

  32. Vince Reply

    Lemmingz, I was wondering what documentation you explore when you implement the sockets. What do you read to keep up to date?

  33. thomas Reply

    Hi does someone figured out why you cannot send/receive more then 8096 bits of data?

    is this a restriction of the socket server or of the protocol? Or did someone already made something to join the chunks?

  34. 1412 Reply

    Help me….

    Run :
    C:\Program Files\EasyPHP-5.3.8.0\php>php.exe ..\www\lemmingzshadow-php-websocket-8a530d4\lemmingzshadow-php-websocket-8a530d4\server\server.php

    Give me:
    Fatal error: Call to undefined function WebSocket\socket_write() in C:\Program Files\EasyPHP-5.3.8.0\www\lemmingzshadow-php-websocket-8a530d4\lemmingzshadow-php-websocket-8a530d4\server\lib\WebSocket\Connection.php on line 168

    • Lemmingz Shadow Reply

      Seems like your php installation was compiled without the socket extension. Please ask the EasyPHP Support for further Information.

  35. Laszlo Dobos Reply

    Dear Lemmingz!

    I would have a question about client.php.

    I’ve download your latest code from github and I copied to my server. I set: $server->setCheckOrigin(false); I started the server. OK. I open client/index.html in the browser, connected. Great! I open another index.html, it’s connected too. I opened the status.html page, which shows the connections. OK. Now if I send something (echo – blabla), the other index.html shows the text immediately. Works fine.

    Now I would like to send texts to the clients without any client action. I think client.php is for me, right? If I open this file or create a WebsocketClient object somewhere else, I will be able to send texts to clients, right? I’ve changed the code:

    $WebSocketClient = new WebsocketClient(‘localhost’, 8000, ‘/echo’);
    var_dump($WebSocketClient->sendData(‘hello’));
    unset($WebSocketClient);

    The response:
    Notice: Undefined offset: 1 in /var/www/client/client.php on line 52 Notice: Uninitialized string offset: 0 in /var/www/client/client.php on line 177 Notice: Uninitialized string offset: 1 in /var/www/client/client.php on line 178 Notice: Uninitialized string offset: 1 in /var/www/client/client.php on line 181 array(1) { ["payload"]=> bool(false) }

    The server response in console:
    2012-03-28 06:11:58 [info] [client 127.0.0.1:38052] Connected
    2012-03-28 06:11:58 [info] [client 127.0.0.1:38052] Performing handshake
    2012-03-28 06:11:58 [info] [client 127.0.0.1:38052] Invalid application: /echo

    Invalid application? If I rewrite /echo to /demo…

    $WebSocketClient = new WebsocketClient(‘localhost’, 8000, ‘/demo’);
    var_dump($WebSocketClient->sendData(‘hello’));
    unset($WebSocketClient);

    Now loading takes long time…loading loading, then:
    Notice: Uninitialized string offset: 0 in /var/www/client/client.php on line 177 Notice: Uninitialized string offset: 1 in /var/www/client/client.php on line 178 Notice: Uninitialized string offset: 1 in /var/www/client/client.php on line 181 array(1) { ["payload"]=> bool(false) }

    How can I solve this?
    Thank you so much!

  36. Laszlo Dobos Reply

    If I use:

    $WebSocketClient = new WebsocketClient(‘localhost’, 8000, ‘/demo’);
    var_dump($WebSocketClient->sendData(‘hello’));
    unset($WebSocketClient);

    I get on console:

    2012-03-28 06:20:40 [info] [client 127.0.0.1:38068] Connected
    2012-03-28 06:20:40 [info] [client 127.0.0.1:38068] Performing handshake
    2012-03-28 06:20:40 [info] [client 127.0.0.1:38068] Handshake sent
    2012-03-28 06:21:40 [info] [client 127.0.0.1:38068] Disconnected

    And the clients don’t get the text.:(
    What’s the problem? Thank you!!!!!

  37. Laszlo Dobos Reply

    Can this row cause a problem in client.php?
    $header.= “Sec-WebSocket-Origin: http://foobar.com\r\n”;

  38. Shift Reply

    Hi. TNX for this solution! Last application version from git works fine in Chrome Canary 21.0.xxx.

  39. Insphare Reply

    Mit Google-Chrome gibt es neue “Probleme”.

    Das Problem ist, dass “Sec-WebSocket-Protocol’ nur mit gesendet werden darf, wenn es auch in der Anfrage vorhanden ist.

    Die Lösung ist:

    $response .= “Sec-WebSocket-Protocol: ” . substr($path, 1) . “\r\n\r\n”;
    Durch
    if (!empty($headers['Sec-WebSocket-Protocol'])) {
    $response .= “Sec-WebSocket-Protocol: ” . substr($path, 1) . “\r\n”;
    }
    $response .= “\r\n”;

    zu ersetzen.

    Dann läuft’s auch in Google-Chrome 20.x

    • Lemmingz Shadow Reply

      Habe gerade einen entsprechenden Fix in das Git-Repository geschoben.

  40. Insphare Reply

    Danke! Es reicht aber aus, nur !emtpy() zu verwenden. Das schließ die Überprüfung, die isset() macht, mit ein. :)

  41. whaatt Reply

    Hallo aus Amerika Suedost!

    I’ve found your WebSocket server to be nearly perfect so far, but I have a recurring problem with memory leaks in Connection.php.

    I run a game server, and every now and then, the program crashes with the following message:

    Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 523800 bytes)

    It always occurs upon execution of this line:

    $encodedData = $this->hybi10Encode($payload, $type, $masked);

    in the send subroutine. If my memory serves me right, it usually happens when a client disconnects.

    Do you have any idea what might be causing this bug? Normally if I view memory usage, it doesn’t get much past 1 or 2 MB, so something is causing a major memory leak.

    Danke!

Leave a Reply

Your email address will not be published. Please enter your name, email and a comment.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>