views:

198

answers:

2

Hi so I'm trying to lurn how to make a chat with a socket server.

I noticed everybody uses the same code (ripoff from the zend developer zone).
The problem is no one really explains how it works. Especially the cryptic code after while(true) { .

This would benefit many so i hope someone could take the time and explain the code in detail (DETAIL!).

You can find the code here

A: 

PHP is not multithreaded, because of that you cant build good socket server. Use Python instead.

codez
A: 

I'll answer it myselfe. I went over it line by line.. this is how it works (I'm only explaining the part in the while(true) loops.

1.

// Setup clients listen socket for reading
$read[0] = $sock;
for ($i = 0; $i < $max_clients; $i++) {
    if (isset($client[$i]['sock']))
        $read[$i + 1] = $client[$i]['sock'];
}

This asings freshly created connections to the $read array to be watched for incoming data.

// Set up a blocking call to socket_select()
if (socket_select($read, $write = NULL, $except = NULL, $tv_sec = 5) < 1)
    continue;

Watches the $read array for new data (I'm still a bit unclear how this works)

/* if a new connection is being made add it to the client array */
if (in_array($sock, $read)) {
    for ($i = 0; $i < $max_clients; $i++) {
        if (empty($client[$i]['sock'])) {
            $client[$i]['sock'] = socket_accept($sock);
            echo "New client connected $i\r\n";
            break;
        }
        elseif ($i == $max_clients - 1)
            echo "Too many clients...\r\n";
    }
}

Determines when a new connection is being made, than finds an empty spot in the $client array and add the socket.

This next part I'll split up for easier explanation.

for ($i = 0; $i < $max_clients; $i++) { // for each client
    if (isset($client[$i]['sock'])) {

Loops through all the $client array but only works on the ones that actually have a connection.

if (in_array($client[$i]['sock'], $read)) {
            $input = socket_read($client[$i]['sock'], 1024);
            if ($input == null) {
                echo "Client disconnecting $i\r\n";
                // Zero length string meaning disconnected
                unset($client[$i]);
            } else {
                echo "New input received $i\r\n";
                // send it to the other clients
                for ($j = 0; $j < $max_clients; $j++) {
                    if (isset($client[$j]['sock']) && $j != $i) {
                        echo "Writing '$input' to client $j\r\n";
                        socket_write($client[$j]['sock'], $input, strlen($input));
                    }
                }
                if ($input == 'exit') {
                    // requested disconnect
                    socket_close($client[$i]['sock']);
                }
            }
        } else {
            echo "Client disconnected $i\r\n";
            // Close the socket
            socket_close($client[$i]['sock']);
            unset($client[$i]);
        }

First it sees if there is still an active connection, if not it closes it. If there is a connection it read the data, if there is noone this is code for a disconnect. If there is data it passes it along to other clients (but itselfe).

That's ti. Hope I got it right.

Putr