Open sylbru opened 7 years ago
If it still passes the tests, and works in functional/manual testing, I'd be more than happy to consider a change. Certainly your fix seems reasonable; if we can't justify the use of unread_bytes
with a test or documentation it shouldn't be there.
A lot of the weird stuff going on in the stream handling is cargo-culted or dates from the original implementation.
You was lucky to send a message packet of bytes count equal to inner buffer length, so 'unread_bytes' value was zero.
I'll try to find out a solution. Just some free time needed.
I have the exact same issue. The probleem only seems to occur for me when using SSL; for some reason when using SSL fread only reads 1 byte at a time and ignores the $length parameter, whereas when we don't use SSL it reads the entire $length correctly. Then unread_bytes is always 0 causing the loop to break prematurely.
If I comment out the entire metadata section it works. Note that this does require the "Workaround Chrome behavior" around line 302, otherwise the loop would still break prematurely (because strlen($result) != $length). Because of this comment I did try Firefox but it still ignored $length.
Would it be considered safe if we remove the metadata section for the time being? It seems like a fallback to prevent getting stuck in a loop, though feof() should suffice for this.
All people who had problems connected with "Chrome behavior" or 'unread_bytes' check: plz download and try commit "82811a9e197b4ff11cccaba62e88c28ecfd907c6". Tested with SSL, both Chrome and Firefox. I hope all issues were solved.
Your reviews will be welcomed.
Looking at it (https://github.com/varspool/Wrench/commit/82811a9e197b4ff11cccaba62e88c28ecfd907c6) it wont fix my problem.
unread_bytes does not reflect real unread data length, just part in the system cache. Real code change is just check it for > 0, without using this value directly. So I don't mind delete this check. May be its a wild guess by i think it is correct now.
Strange behavior about Chrome. Can you describe your environment such like OS, php build, Chrome version? BTW how did you tried to connect socket, directly or apache/nginx proxy?
Alright, but mind you my problem has nothing to do with Chrome, I'm just calling it the "Chrome fix" because thats what it says in the code comment (line 302 "Workaround Chrome behaviour (still needed?)").
What I'm doing is:
error_log('l:' . $length . ', r:' . $result)
right after the fread($this->socket, $length)
Now after this the following happens:
strlen($result) == 1
so $continue gets put to true (this is the so called "Chrome fix")strlen($result) != $length
so this if gets skipped. I guess the idea is that if the entire $length was read that means that there's possibly more data that will require another read so it continues. However, since with SSL it only reads 1 byte this will never happen so it won't continue.if (!$metadata['unread_bytes']) {
on line 314, which has now changed to if (empty($metadata['unread_bytes'])) {
which is the same thing in this context. This evaluates to true because unread_bytes == 0. Now $continue == false and the loop ends.I have implemented a custom socket class in which I've removed the section and it seems to work just fine :)
I'm trying this library and using version 2 because the application I'm working on is written for PHP 5.4 (I know...), and while the move to PHP7 is planned, it's less urgent than my need to integrate WebSockets.
After spending a lot of time on trying to make all of this work, I stumbled on a weird issue where the script crashed because of this:
warning: Wrench\ConnectionManager: Wrong input arguments: exception 'InvalidArgumentException' with message 'Invalid request line'
The stack trace below this message showed that theonData
method was called with the string "G" as the$data
argument. I noticed the cause of this was that theSocket::receive()
method returned prematurely because of the'unread_bytes'
value of$metadata
being equal to 0 at that point.Not knowing much about this, but reading in the PHP documentation for
stream_get_meta_data()
that "You shouldn't use this value in a script," I tried commenting out this wholeif ($metadata && isset($metadata['unread_bytes']))
block.And to my surprise, it worked flawlessly, at least for now. I can now connect to the server, send and receive messages.
Is that a bug, of simply me using the library the wrong way? Is this method (removing the block) a proper patch or will it likely cause other issues?