I've got a problem with a PHP script I'm trying to make work (sorry for my strange language, I'm Swiss
Here is my code (http://paste-it.net/public/sae1180/ to see it better) :
Code: Select all
<?php
set_time_limit(0);
$address = '87.98.146.113';
$port = 17622;
if(($creation = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
echo "Unable to create the socket : "."socket_strerror(socket_last_error())"."\n";
exit();
} else {
echo "Creation ok.\n";
}
if(($option = socket_set_option($creation, SOL_SOCKET, SO_REUSEADDR, 1)) === false) {
echo "Unable to modifiy the option SO_REUSEADDR : ".socket_strerror(socket_last_error())."\n";
exit();
} else {
echo "Modification ok.\n";
}
if(($binding = socket_bind($creation, $address, $port)) === false) {
echo "Unable to bind the socket : ".socket_strerror(socket_last_error())."\n";
exit();
} else {
echo "Binding ok.\n";
}
if(($listening = socket_listen($creation,10)) === false) {
echo "Unable to listen to the socket : ".socket_strerror(socket_last_error())."\n";
exit();
} else {
echo "Listening ok.\n";
}
$real_array = array($creation);
while(true) {
$sockets = $real_array;
socket_select($sockets, $reading = NULL, $except = NULL, NULL);
foreach($sockets as $sock) {
if($sock == $creation) {
if(($client = socket_accept($sock)) === false) {
echo "Unable to accept the client : ".socket_strerror(socket_last_error())."\n";
exit();
} else {
echo "Client accepted.\n";
}
array_push($real_array,$client);
} else {
socket_recv($sock, $buffer, 2048, 0);
echo "Message sent : $buffer\n";
$broadcast_array = $real_array;
array_shift($broadcast_array);
envoi_message($broadcast_array,$buffer);
}
}
}
function envoi_message($destis,$content) {
foreach($destis as $desti) {
@socket_write($desti,$content);
}
}
?>It's an adaptation I made of a code I found in a PDF written by Thibault Imbert, called "Pratique d'ActionScript 3".
As you can see, it's a socket server which listens to clients (my clients are Flash chat applications) and broadcasts what it receives to all the other clients connected.
I launch it (using screen, to keep it alive) with
Code: Select all
php -f socket3.phpIt works perfect. BUT there is one problem, which bores me. I'll try to describe the events chronologically :
1) I launch the server with the command I wrote above => The terminal tells me it's launched, listening, binded, everything.
2) I connect with the Flash client, pick a nickname => The terminal tells me : "Client accepted".
3) I send a few messages with the Flash client => The XML nodes containing the message and the nickname appear on the terminal.
4) I close the Flash client => The terminal displays :
"Message sent :
Message sent :
Message sent :
Message sent :
..."
Again and again, an infinity of "Message sent : " !!
To avoid the terminal to display that, I first put an "if" which checked if $buffer was NULL. If it was, nothing was done. With it, everything went well, for the client and for the terminal.
But something is telling me that it's not normal... And indeed, the problem is clear : I do not "remove" the clients that are not connected anymore ! With my modifications it's doesn't appear to be very serious, but when I imagine many people connecting and the server having being running for a long long time, I guess that it will get much slower ! And it could even crash ! Because ALL the clients will be kept by the server ! So I want it to be cleaner, to remove clients that are not connected anymore.
And that's why I'm posting : I don't know how to do.
I tried to do this : Remember my "if" that checked if $buffer was NULL ? Well, I tried to make that, when the $buffer was NULL, then the client HAD to be disconnected. Why ? Because a NULL $buffer happened only in that case. Even with an empty nickname and en empty message, the XML structure of the broadcast string still appears, so it's not NULL.
I thought it could be the solution... But I couldn't make it work. Here's what I did : when the $buffer was NULL, I just did socket_shutdown and then socket_close to the $sock on which the foreach loop was working.
But then I got that message on the terminal, when closing the Flash client :
So I don't know what to doWarning: socket_select(): 5 is not a valid Socket resource in /home/pluton/socket3.php on line 37
How would you manage to remove disconnected users, for $real_array to contain the EXACT connected clients, and no ghosts (except during a few seconds, the lag doesn't matter at all) ?
Thank you very much