Can PHP Asynchronously Use Sockets

Can PHP asynchronously use sockets?

Yup, that's what socket_set_nonblock() is for. Your socket interaction code will need to be written differently, taking into account the special meanings that error codes 11, EWOULDBLOCK, and 115, EINPROGRESS, assume.

Here's some somewhat-fictionalized sample code from a PHP sync socket polling loop, as requested:

$buf = '';
$done = false;
do {
$chunk = socket_read($sock, 4096);
if($chunk === false) {
$error = socket_last_error($sock);
if($error != 11 && $error != 115) {
my_error_handler(socket_strerror($error), $error);
$done = true;
}
break;
} elseif($chunk == '') {
$done = true;
break;
} else {
$buf .= $chunk;
}
} while(true);

Open asynchronous sockets in PHP

Use different functions: socket_create() and socket_connect() instead of fsockopen(). This works:

$socks = array();
for ($port = 21; $port <= 25; $port++) {
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sock);
@socket_connect($sock, 'localhost', $port);
$socks[$port] = $sock;
}

$startTime = microtime(true);
while ($socks && microtime(true) - $startTime < 3) {
$null = null;
$write = $socks;
socket_select($null, $write, $null, 1);
foreach ($write as $port => $sock) {
$desc = "$port/tcp";
$errno = socket_get_option($sock, SOL_SOCKET, SO_ERROR);

if ($errno == 0) {
echo "$desc open\n";
} elseif ($errno == SOCKET_ECONNREFUSED) {
echo "$desc closed\n";
} elseif ($errno == SOCKET_ETIMEDOUT) {
echo "$desc filtered\n";
} else {
$errmsg = socket_strerror($errno);
echo "$desc error $errmsg\n";
}

unset($socks[$port]);
socket_close($sock);
}
}

foreach ($socks as $port => $sock) {
$desc = "$port/tcp";
echo "$desc filtered\n";
socket_close($sock);
}

How to make asynchronous HTTP requests in PHP

The answer I'd previously accepted didn't work. It still waited for responses. This does work though, taken from How do I make an asynchronous GET request in PHP?

function post_without_wait($url, $params)
{
foreach ($params as $key => &$val) {
if (is_array($val)) $val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);

$parts=parse_url($url);

$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);

$out = "POST ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".strlen($post_string)."\r\n";
$out.= "Connection: Close\r\n\r\n";
if (isset($post_string)) $out.= $post_string;

fwrite($fp, $out);
fclose($fp);
}

Starting Pure PHP socket in Backend/Asynchronously

Solved this, it is not the one that i really want to do, but it's working now properly like what i intended to do from the first place..

Here is how i looks now:

public function __socket_write($text)
{
$service_port = xxxxxx;

$address = MyAddress;

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

$result = socket_connect($socket, $address, $service_port);

if ($result === false)
{
$this->__socket_start();
}

@socket_listen($socket);

...

socket_close($socket);
}

public function __socket_start()
{
$cmd = "php server.php";

shell_exec($cmd." > /dev/null 2>/dev/null &");
}

Is there a way to listen for new socket connections while doing a do, while loop in PHP?

I found the solution.
To anyone who was wondering what it was, use:

socket_set_nonblock($socketservervariable);

to make the server not wait for a client to connect before proceeding. That creates a new error though. When doing the client handshake the socket_read wanted a socket but it got the boolean value of false when the socket_accept function didn't detect a client connecting. So this was my solution to that:

$newclient = socket_accept($server);
if($newclient != false){
handshake($server, $newclient);
$clients[count($clients)] = $newclient;
echo "\n\nNew client connected!\n\n";
}

and that solved all of my problems.

How to implement a high performance asynchronous socket server application in PHP?

I think this is a typical case of "If all you have is a hammer, everything looks like a nail."

As you yourself already figured out, php is not the right tool for the job. You can probably find a way to do it anyway, but it'll most likely be messy.

So use the right tool for the job. You would not use a hammer to drive a screw into the wall, would you?



Related Topics



Leave a reply



Submit