Thanks Jim. Several good points here that I will look into. I've
already moved the include() bits into function calls. (That's simple
thing I should have corrected long ago.) The socket areas though I'm
less sure about how to adjust, since networking programming isn't
something I grok naturally.
On 10-Dec-07, at 9:57 PM, Jim Lucas wrote:
René Fournier wrote:
FWIW, here's the stripped-down skeleton of the server:
As always, constructive criticism is very welcome.
<?php
$socket = stream_socket_server("tcp://127.0.0.1:9876", $errno,
$errstr);
if ($socket) {
$master[] = $socket;
$read = $master;
$write = $master; while (1) {
$read = $master;
$write = $master;
The follow part, I think, is where your problem is.
This line tells the system to wait 1 second and then continue,
whether you have an inbound connection or not.
$mod_fd = stream_select($read, $_w = NULL, $_e = NULL, 1);
Then here you are testing for success or failure of the last call.
if ($mod_fd === FALSE) {
break;
}
Problem, if you don't have a connection, then the will fail
constantly.
once every second X (times) the number of connections you have...
But my understanding from the docs (where I used one of the examples
as a template for the script) socket is that it could/would only fail
on startup, that is if it can't perform stream_select() because it's
unable to bind to with stream_socket_server(), or am I wrong?:
"If the call fails, it will return FALSE and if the optional errno
and errstr arguments are present they will be set to indicate the
actual system level error that occurred in the system-level socket(),
bind(), and listen() calls. If the value returned in errno is 0 and
the function returned FALSE, it is an indication that the error
occurred before the bind() call. This is most likely due to a problem
initializing the socket. Note that the errno and errstr arguments
will always be passed by reference." (http://www.php.net/manual/en/
function.stream-socket-server.php)
In other wrongs, mod_fd can't return FALSE once the socket_server has
been created and bound to the specified IP... right?
for ($i = 0; $i < $mod_fd; ++$i) {
if ($read[$i] === $socket) { // NEW SOCKET
$conn = stream_socket_accept($socket, 900);
$master[] = $conn;
$key_num = array_search($conn, $master, TRUE);
} else {
$sock_data = fread($read[$i], 32768);
if (strlen($sock_data) === 0)
{ // CONNECTION GONE
$key_to_del = array_search($read
[$i], $master, TRUE);
fclose($read[$i]); unset
($master[$key_to_del]);
} elseif ($sock_data ===
FALSE) { // CONNECTION BROKEN
$key_to_del = array_search
($read[$i], $master, TRUE);
fclose($read[$i]);
unset($master[$key_to_del]);
} else { // READ
INCOMING DATA
Here, you are not removing the successful connections from $master,
so it keeps growing.... on and on...
But only until the connection closes, or no longer blocks (goes
away), in which case the program fcloses that socket and removes it
from master[].
As for the includes, well, I would turn them into function calls
and then have a different function for the different ways you want
the program to react.
Yes, I did that. It helps a bit with CPU.
// include (somefiles);
// include (somefiles);
// include (somefiles);
// [ ... ]
}
}
}
}
}
?>
I didn't see anything about your DB connections. Are those located
in the includes?
Just at header.inc, once.
How long, on average, does your processing of the incoming data
take? Because, to me, it looks like you might have a blocking
problem with the in-coming connections. If the initial connection
takes too long, then the following connections might be getting
blocked. You might want to look into pcntl_* functions to do
forking if you need it.
The processing is pretty quick. I don't think that's a bottleneck. It
basically just inserts the data into MySQL, not much processing
actually.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php