I'm sending from browser through Websocket an image data of around 5000 bytes but this line is receiving total of 1394 bytes only:
while ($bytes = socket_recv($socket, $r_data, 4000, MSG_DONTWAIT)) {
$data .= $r_data;
}
This is after handshake is done which is correctly being received. The json data is being cutoff after 1394 bytes. What could be the reason?
In the browser interface it is sending image as JSON:
websocket.send(JSON.stringify(request));
The browser interface is fine as it is working with other PHP websocket free programs I've tested.
Here is the full source code.
If data is not available for the socket socket, and socket is in blocking mode, the recv () call blocks the caller until data arrives. If data is not available and socket is in nonblocking mode, recv () returns a -1 and sets the error code to EWOULDBLOCK.
The recv () call was interrupted by a signal that was caught before any data was available. The request is invalid or not supported. The MSG_OOB flag is set and no out-of-band data is available. There has been a network or transport failure. Insufficient system resources are available to complete the call.
The server correctly identifies invalid port numbers, too few or too many port numbers, or other malformed requests. If you send the server no data ("") and keep the socket open, however, it will hang at data=fd.recv (1024).strip () on the recv instruction. Setting a timeout on the socket via settimeout.
Requests that the function block until the full amount of data requested can be returned. The function may return a smaller amount of data if a signal is caught, the connection is terminated, an error is pending, or SO_RCVTIMEO is set and the timer is expired for the socket.
You have our socket set up as non-blocking by specifying MSG_DONTWAIT, so it will return EAGAIN after it reads the first chunk of data, rather than waiting for more data. Remove the MSG_DONTWAIT flag and use MSG_WAITALL instead, so that it waits for all the data to be received.
There are a few ways of knowing if you have received all the data you are expecting:
1 and 2 are useful if you want to process the data while receiving it - for example if you are writing a game, chat application, or something else where the socket stays open and multiple messages are passed back and forth. #3 is the easiest one, and is useful when you just want to receive all the data in one go, for example a file download.
Just my 2 cents on this. socket_recv can return false on an error. Where it can also receive zero (0) bytes in non-blocking IO.
Your check in your loop should be:
while(($bytes = socket_recv($resource, $r_data, 4000, MSG_DONTWAIT)) !== false) {}
Altough I would check the socket for errors also and add some usleep call to prevent "CPU burn".
$data = '';
$done = false;
while(!$done) {
socket_clear_error($resource);
$bytes = @socket_recv($resource, $r_data, 4000, MSG_DONTWAIT);
$lastError = socket_last_error($resource);
if ($lastError != 11 && $lastError > 0) {
// something went wrong! do something
$done = true;
}
else if ($bytes === false) {
// something went wrong also! do something else
$done = true;
}
else if (intval($bytes) > 0) {
$data .= $r_data;
}
else {
usleep(2000); // prevent "CPU burn"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With