views:

1186

answers:

5

Typical PHP socket functionality is synchronous, and halts the thread when waiting for incoming connections and data. (eg. socket_read and socket_listen)

How do I do the same asynchronously? so I can respond to data in a data received event, instead of polling for data, etc.

+4  A: 

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);
chaos
What do you mean by differently? Can you show me any code samples of asynchronous data received events?
Jenko
So this is synchronous, but non-blocking? Then what exactly does non-blocking mean?
Jenko
No, it is asynchronous, and polling-based. The code is from a larger polling mechanism. PHP has no support for interrupt/signal driven socket I/O events like you're asking for, as far as I know. You achieve async communications by using operations that do not wait for completion but return immediately, with an indicative error code, if the operation isn't ready. Like reads on a non-blocking socket. There are lots of tutorials on async socket use in C that will go into lots of detail abou this; PHP's support is just a layer over the standard C stuff.
chaos
A: 

AFAIK PHP is strictly singlethreaded, which means you can't do this asynchronously, because Script execution is always linear.

It's been a while since i have done this, but as far as i recall, you can only open the socket, and have the script continue execution upon receiving data.

MGriesbach
Even chaos's code sample seems to corroborate this fact.
Jenko
PHP provides stream_select for async socket operations, analogous to posix select().
karunski
A: 

Check this out: http://www.jaisenmathai.com/blog/2008/05/29/asynchronous-parallel-http-requests-using-php-multi%5Fcurl/

Alex
why has this been down-voted?
Alex
I think that's because that article is about curl. And curl works with HTTP, not with raw sockets.
FractalizeR
yeah that's true. but i think one could turn this curl approach into just using raw sockets.
Alex
+3  A: 

How do I do the same asynchronously? so I can respond to data in a data received event, instead of polling for data, etc.

You will need to execute your script and issue stream_select to check weither there is any data to receive. Process and send data back.

FractalizeR
+1  A: 

As soon as the PHP script execution terminates there is no way to send/receive something.
PHP is a linear scripting language.

If you need a client, go normal synchronous sockets. If you want a server based on PHP (which is not a perfect idea, but what the heck..) go the same blocking sockets, handling each incoming connection in it's own thread.

Why not non-blocking sockets? Because I really doubt your client/server will do something while the buffer of your socket is being filled with the data.

Few links for you:

Creating a PHP socket server
Writing Socket Servers in PHP

Andrejs Cainikovs