Reputation: 163
I've worked hours and hours on this, and I can't figure it out. I've browsed the posts on here trying to find the solution also and to no avail.
I have a Socket Server setup for my browser-based game. I've stripped it down trying to find the issue, and it seems that fread is hanging because if I comment out "fread($fp, 10024);" then it runs fine, but of course doesn't read the response.
While I debug this, I've broken the files down to the basics.
I have the Socket Server: ChatServer.php
set_time_limit(0);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_get_option($sock, SOL_SOCKET, SO_REUSEADDR);
socket_bind($sock, "127.0.0.1", "9990");
socket_listen($sock, 4);
$chatContent = "Testing, 1, 2, 3.";
do
{
$childSocket = socket_accept($sock);
$incomingData = socket_read($childSocket, 12048);
socket_write($childSocket, $chatContent, strlen($chatContent));
} while(true);
Then I have Test.php which should open the socket and read a response.
$fp = fsockopen("127.0.0.1", "9990", $errno, $errstr, 5);
echo $errstr . "<br />";
echo fread($fp, 10024);
$errstr doesn't display an error, because when I start ChatServer.php then reload Test.php, it never reloads. It hangs for minutes and lags my entire server. I'm running on a VPS. This worked fine before, then suddenly stopped working, and I can't figure out why.
Edit: Thanks to GigaWatt, I was able to get it working. Here is the code I used if you have the same issue. :)
set_time_limit(0);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_get_option($sock, SOL_SOCKET, SO_REUSEADDR);
socket_bind($sock, "127.0.0.1", "9990");
socket_listen($sock, 4);
$chatContent = "Testing, 1, 2, 3.";
do
{
$childSocket = socket_accept($sock);
$meta = stream_get_meta_data($sock);
if($meta['unread_bytes'] > 0) {
$incomingData = socket_read($childSocket, $meta['unread_bytes']);
}
socket_write($childSocket, $chatContent, strlen($chatContent));
} while(true);
Just use stream_get_meta_data and then unread_bytes.
Upvotes: 2
Views: 1605
Reputation: 20889
The call to socket_read
is a blocking call, meaning everything stops until the specified number of bytes have been read.
If you need to continue processing, consider using stream_get_meta_data
(the unread_bytes
value) to check how much unread data is waiting.
Once it reaches the desired threshold, then call socket_read
.
https://www.php.net/manual/en/function.stream-get-meta-data.php
Upvotes: 2
Reputation: 2825
It does exactly what you tell it to: waits for 12048 / 10024 bytes of data or socket being closed.
You might be interested in using a non-blocking socket (socket_set_nonblock/stream_set_blocking
) and a socket_select
loop or libevent.
Upvotes: 1