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

46 thoughts on “PHP Websocket Server/Client nach Draft hybi-10

  1. Sven

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

  2. Sven

    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.

  3. 1412

    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?

  4. Simon

    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: /files/2011/09/client.html.txt (Needs jquery). Maybe it will help you to analyze you problem.

  5. Gustavo

    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)

  6. Simon

    Hmm, that’s weird. As you can see in the encode function the first byte of the encoded data is always set to 0x81 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.

  7. Simon

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

    Sec-WebSocket-Version: 8
  8. Simon

    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.

  9. Tijmen Scheifes

    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.

  10. 1412

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

  11. Rodrigo

    Hello Simon!!

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

    I was reading the protocol to encode/decode …

    Thanks!!
    Rodrigo

  12. 1412

    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?

  13. Simon

    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 🙂

  14. 1412

    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 😀

  15. Pingback: PHP WebSocket Server with hybi-10 | siriux.net

  16. Karel-Jan

    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?

  17. Simon

    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/

  18. Simon

    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.

  19. lame

    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

  20. Vince

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

  21. Simon

    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.

  22. Vince

    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.

  23. Vince

    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!

  24. Vince

    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.

  25. Simon

    …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 🙂

  26. Vince

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

  27. thomas

    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?

  28. 1412

    Help me….

    Run :
    C:Program FilesEasyPHP-5.3.8.0php>php.exe ..wwwlemmingzshadow-php-websocket-8a530d4lemmingzshadow-php-websocket-8a530d4serverserver.php

    Give me:
    Fatal error: Call to undefined function WebSocketsocket_write() in C:Program FilesEasyPHP-5.3.8.0wwwlemmingzshadow-php-websocket-8a530d4lemmingzshadow-php-websocket-8a530d4serverlibWebSocketConnection.php on line 168

  29. Simon

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

  30. Laszlo Dobos

    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!

  31. Laszlo Dobos

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

  32. Insphare

    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) . “rnrn”;
    Durch
    if (!empty($headers[‘Sec-WebSocket-Protocol’])) {
    $response .= “Sec-WebSocket-Protocol: ” . substr($path, 1) . “rn”;
    }
    $response .= “rn”;

    zu ersetzen.

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

  33. Insphare

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

  34. whaatt

    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. Required fields are marked *

π