Bağlamadığınız kod, engellenmeyen G/Ç işlemlerinin birçok yönüyle ilgili sınırlı bir anlayışa sahip olduğumda, uzun zaman önce yazılmıştır.
Gerçekten bunun çok sayıda uygulama olduğu bir olay döngüsüne ihtiyacı var, ancak bu örnekte, @rdlowrey'un Alert kitaplığını kullanacağım, çünkü bu, anlaşılması oldukça kolay olması gereken minimalist bir koddur. Ayrıca daha yüksek seviye olan ve daha birçok özellik sunan React numaralı telefondan bir döngü de alabilirsiniz.
Not Aşağıdaki örnek PHP 5.4+
<?php
// Array of addresses to test
$addresses = [
'192.168.5.150',
'192.168.5.152',
'google.com', // Important note: DNS is resolved synchronously here.
'192.168.5.155', // this can seriously slow down the process as it can block
'192.168.5.20', // for a few seconds, async DNS resolution is non-trivial
'192.168.40.40', // though
];
// The TCP port to test
$port = 80;
// The length of time in seconds to allow host to respond
$timeout = 5;
// This will hold the results
$lookups = [];
// Create a reactor
$reactor = (new \Alert\ReactorFactory)->select();
$count = count($addresses);
$completedCount = 0;
$onComplete = function($address, $result)
use(&$lookups, &$completedCount, $count, $reactor) {
// Cancel the watchers for this address
$reactor->cancel($lookups[$address]['failWatcher']);
$reactor->cancel($lookups[$address]['writeWatcher']);
$reactor->cancel($lookups[$address]['readWatcher']);
// Store the result
$lookups[$address] = $result;
// If there's nothing left to do, stop the reactor
if (++$completedCount == $count) {
$reactor->stop();
}
};
foreach ($addresses as $address) {
// Normalise the address to lower-case, as it will be used as an array key
$address = strtolower($address);
if (!isset($lookups[$address])) {
// Create a socket to connect asynchronously
$sockAddr = "tcp://{$address}:{$port}";
$flags = STREAM_CLIENT_ASYNC_CONNECT;
$socket = stream_socket_client($sockAddr, $errNo, $errStr, 0, $flags);
stream_set_blocking($socket, 0);
// Set up a timeout to watch for failed connections
$failWatcher = function() use($address, $onComplete, $timeout) {
echo "{$address} connect failed: Connect timed out\n";
$onComplete($address, false);
};
$failWatcherId = $reactor->once($failWatcher, $timeout);
// Watch for the stream becoming writable (connection success)
$writeWatcher = function() use($address, $onComplete) {
echo "{$address} connected successfully\n";
$onComplete($address, true);
};
$writeWatcherId = $reactor->onWritable($socket, $writeWatcher);
// Watch for the stream becoming readable (success or explicit fail)
$readWatcher = function() use($address, $onComplete, $socket) {
if ('' === $data = fread($socket, 1024)) {
echo "{$address} connect failed: Server refused connection\n";
$onComplete($address, false);
} else if ($data === false) {
echo "{$address} connect failed: Stream read error\n";
$onComplete($address, false);
} else {
echo "{$address} connected successfully\n";
$onComplete($address, true);
}
};
$readWatcherId = $reactor->onReadable($socket, $readWatcher);
// Store the watcher IDs so they can be destroyed later
$lookups[$address] = [
'failWatcher' => $failWatcherId,
'writeWatcher' => $writeWatcherId,
'readWatcher' => $readWatcherId,
];
}
}
// Set everything going
$reactor->run();
// $lookups is now an array of booleans indicating whether the address resulted
// in a successful connection
, size bize vermedi neden Diğer cevaplardan biri (29 oy ve bir ödül ile olanı gibi)? –
curl iyi, ancak soket de çok iyi, hızlı ve benim için en iyi seçenek. – user2203703