Closed t3chn0r closed 11 years ago
Could you post a gist with your php and javascript code please? I'll try to get my hands on an iOS5 device and test this weekend.
There aren't any debug tools you can just drop in. When I debug I'll usually write a class implementing MessageComponentInterface
that spits out $connection information and stick that between where I think the problem is. I'll consider releasing a proper debug class in the future.
Thanks @cboden, just created the following gist, if you have any question about anything please let me know.
Regards, t3ch
@t3chn0r - 2 hours in troubleshooting and I realized I grabbed an iOS4 device from work, oops!
I started with just raw JavaScript and my Fuzzing Test to replicate your issue, and have been adding components from your gist, testing each step of the way. I've gotten as far as using your JavaScript with jQuery.WebSocket without failure (and I have to step out for a few hours).
I have a few questions for you that I hope will help me replicate the issue:
Finally, I forgot to mention earlier, this Logger is one of the tools I use for debugging (with bin example). The other, if you use it, is PHPStorm. It's ability to put break points on key points of Ratchet's source files and examen variables is amazing.
Hello @cboden,
I use PHPStorm so I will take a look at it... Haven't used debugging features yet.
Regards
Just a quick update... I created a new Symfony2 project from scratch, added the command and the pusher files, and just added one page with the following code and I can see the issue happening with iOS 5.1.1:
<body>
{% block body %}
<div id="WebSocket_Status"></div>
{% endblock %}
<script>
jQuery(function($) {
"use strict";
(function($, application, window) {
application.WebSocketsClient = function() {
var ws = $.websocket( "ws://192.168.1.100:8000/", {
close: function() {
$("#WebSocket_Status").append("<p>Trying again in 10 seconds...</p>");
// Re-try connecting to the websocket server every 10 seconds
setTimeout( application.WebSocketsClient, 10000 );
},
open: function() {
$("#WebSocket_Status").append("<p>Connected...</p>");
},
message: function( e ) {
$("#WebSocket_Status").append("<p>Message received " + e.originalEvent.data + "...</p>");
}
});
};
})(jQuery, window.WST || (window.WST = {}), window);
// Try to connect to our websocket server
WST.WebSocketsClient();
});
</script>
</body>
Okie, I will re-test tonight after I'm done work. In the mean time can you test two things for me to help narrow it down please?
1) Can you test that Javascript with a plain CLI Ratchet test app (without symfony or ZMQ push); this will help me isolate where the problem is originating from.
2) I'm unable to obtain an iOS 5 device. Can you test on an iOS 5 simulator to verify the error will occur on a simulator as well as an actual iPad/iPhone -- this will ensure when I test on the simulator I will receive the same results you are.
To get a simulator (assuming you're on a Mac):
Downloads
, then select Components
Install
on the iOS 5.1 Simulator
cellHello @cboden, sadly I don't have a Mac, I'll see if I can find an emulator for Windows 7...
Regarding the Ratchet test app without Symfony2, is there anything already out there that I can use or should I build something from scratch?
Regards, t3ch
If you checkout the Ratchet repository and run the following command:
php tests/AutobahnTestSuite/bin/fuzzingserver-stream.php
This will start a WebSocket server on port 8001 that will send back any message received to the client that sends it. Make sure you've run composer install
first and that you run that command from the top repo directory.
I'll try looking for an iOS 5 device again. Cheers.
Sorry for the wait... Was pretty busy the last few days. I started server per your instructions, I then created a small client code (attached) and then tested different devices.
Trying in 10 seconds... Trying in 10 seconds... Trying in 10 seconds... Trying in 10 seconds... Trying in 10 seconds... Trying in 10 seconds... Trying in 10 seconds... Trying in 10 seconds... Connected...
The client code that I used to test it was this:
<head>
<meta charset="utf-8">
<title>Websockets Test with iOS 5</title>
<script src="js/jquery.js"></script>
<script src="js/jquery.websocket.js"></script>
<script src="js/json2.js"></script>
</head>
<body>
<div id="WebSocket_Status"></div>
<script>
jQuery(function($) {
"use strict";
(function($, application, window) {
application.WebSocketsClient = function() {
var ws = $.websocket( "ws://192.168.1.100:8001/", {
close: function() {
$("#WebSocket_Status").append("<p>Trying again in 10 seconds...</p>");
// Re-try connecting to the websocket server every 10 seconds
setTimeout( application.WebSocketsClient, 10000 );
},
open: function() {
$("#WebSocket_Status").append("<p>Connected...</p>");
},
message: function( e ) {
$("#WebSocket_Status").append("<p>Message received " + e.originalEvent.data + "...</p>");
}
});
};
})(jQuery, window.WST || (window.WST = {}), window);
// Try to connect to our websocket server
WST.WebSocketsClient();
});
</script>
</body>
</html>
If you need me to do some other tests please let me know.
Regards, t3chn0r
Excellent debugging info!
Can you update your HTML using these remote Javascript files and verify the error still occurs and ensure we're testing against the same versions:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://raw.github.com/dchelimsky/jquery-websocket/v0.0.4/jquery.websocket.js"></script>
<script src="https://raw.github.com/douglascrockford/JSON-js/master/json2.js"></script>
I tested your script (with the above changes) against my fuzzing server using PHP 5.4.6 on Ubuntu 12.10 64bit and was still unable to replicate your error. I've run into the rare scenario developing for iOS where everything works on the simulator but when once on the hardware it acts differently.
Since I'm unable to obtain an iPad 1 with iOS 5 I think we should collaborate offline; I'd like to setup a the above server with some logging and have you hit my server with your iPad so I can see what Ratchet is doing while you receive the error. Please add me on gChat or come see me on IRC and we'll work out a time to solve this issue.
I'm using those versions but I went ahead anyway and change the index.html to use those scrips instead of the local ones. I ran 3 tests in total:
1: connected in the 4th attemp. 2: connected in the 5th attemp. 3: connected in the 4th attemp.
No problem helping you with this. Not sure how to add you to Google Chat as I don't have your email. :)
My email is in Ratchet's composer.json file. I'll start setting up a server.
Was finally able to replicate the issue on iOS simulator with help from @t3chn0r
The Hixie protocol provides little/no information when errors occur; best I can tell right now is Ratchet is completing the upgrade handshake, telling its decorated component onOpen and then iOS closes the connection at the socket layer. I'm going to try to flesh out the Hixie unit tests a little more to see if I can replicate the protocol without a wire.
Here is a handshake request that failed (values were base64 encoded to be copy/paste'able):
Sec-WebSocket-Key1: QTN+ICszNiA2IDJvICBWOG4gNyAgc08yODhZ
Sec-WebSocket-Key2: TzEyICAgeVsgIFFSNDUgM1IgLiAyOFggNC00dn4z
Body Code: 6dW+XgKfWV0=
ping @mikealmond
I believe I finally found the underlying issue. I was finally able to replicate the issue on a simulator because of the infrastructure used; to test with @t3chn0r I setup a Ratchet server on my home network (slow upload speed) to gather debug information. Because the network connection was so slow TCP fragmented the messages, which is usually fine. However, the Hixie76 protocol uses a body length of 8 bytes and the HttpRequestParser looks for 2 CRLF's, which happens to be when the headers are received, but not the body. It then tells Ratchet the message is received, while it is in fact not.
I'll try to put some code in to the Hixie76 parser to trigger an underflow message, telling the HttpRequestParser to keep building the message.
Good catch Chris, glad I could help, although I did almost nothing... lol! :+1: :+1:
Apparently that was only part of the problem. I've confirmed Ratchet is now always receiving the challenge body but some connections are still failing on the client.
@t3chn0r Can you re-test with the new dev-hixie-testing
branch on Safari 5 and send me the header info on a failing request please?
Not sure if this related to the crapy implementation of websockets in iOS 5 or some other quirk going on but sometimes it takes up to 3 tries for an iOS 5 device to connect to the websocket server.
iOS 6 has no problems at all but with iOS 5 I can see the client connecting to the server but as soon as it connects the session is closed and the onClose event is called. This happens 2 or 3 times until at some point the client connects and stays connected.
It appears something is going on during the intial handshake that iOS 5 or the Ratchet server don't like and the connection is closed instantly.
I'm not sure how to debug this... Is there any parameter in Ratchet to enable some kind of deep debugging information to see why the connection is being dropped?
Thanks for any help...