Forum Moderators: coopster

Message Too Old, No Replies

While Loop Speed

Special behavior with sockets?

         

ChainsawXIV

4:06 am on Jan 28, 2008 (gmt 0)

10+ Year Member



I have a while loop in a script that is listening to a socket, opened with fsockopen(), and I'm getting some inconsistent behavior in terms of the rate at which it's looping. When a message comes in over the socket, it seems to be processed immediately. When I introduce a change on my end though - in this case, updating a database entry with a message to be sent out over the socket, it seems not to be processed until a new incoming message is received.

So, my question is this. Is there some special behavior with while loops and sockets (or something else in my code) that's causing this? Is this just a weird coincidence of some kind? It seems like desirable behavior in terms of efficiency on the server, but I also need to be able to force it some how, so that changes are processed promptly. Your help would be appreciated. Code snippet follows:


// Establish the IRC server connection
$server['SOCKET'] = @fsockopen($config['host'], $config['port'], $errno, $errstr, 2);

// Confirm that connection was established
if($server['SOCKET']){

// Set agent kill status to false
$config['kill'] = FALSE;</span>

// Send essential login commands
SendCommand("PASS NOPASS");
SendCommand("NICK " . $config['nick']);
SendCommand("USER " . $config['nick'] . " USING PHP IRC");

// MAIN LOOP - Process all messages recieved
while(!feof($server['SOCKET']) &&!$config['kill']){

// Get a line of data from the server
$server['read_buffer'] = fgets($server['SOCKET'], 1024);

// Ouput the message to the viewer
PublishLine($server['read_buffer'] . "\n\r");

// If a ping request is recieved, reply with pong
if(substr($server['read_buffer'], 0, 6) == "PING :"){
SendCommand("PONG :" . substr($server['read_buffer'], 6));

}

// When the end of the MOTD is recieved join a channel
if(strpos($server['read_buffer'], "422") ¦¦ strpos($server['read_buffer'], "376")){

// Enter the specified chanel
SendCommand("JOIN " . $config['chan']);

}

// Check for user commands in database
$query = "SELECT `user`,`send` FROM `sessions` WHERE `user` = " . $_GET['user'];
$result = mysql_query($query);
$updates = mysql_fetch_assoc($result);

// If the user entry is gone then kill the loop
if(mysql_num_rows($result) == 0){

// Set the kill flag in the config
$config['kill'] = TRUE;

// Send the quit command to the server
SendCommand('QUIT :Agent disconnecting...');

// Close the socket
fclose($server['SOCKET']);

}

// If there's a new message from the user
if($updates['send']){

// Relay the message to the server
SendCommand($updates['send']);

// Clear the command buffer
$query = "UPDATE `sessions` SET `send` = '' WHERE `user` = " . $_GET['user'];
$result = mysql_query($query);

}

}

// Agent is shutting down, clean up the database
$query = "DELETE FROM `messages` WHERE `user` = " . $_GET['user'];
$result = mysql_query($query);

}

[edited by: ChainsawXIV at 4:07 am (utc) on Jan. 28, 2008]

vincevincevince

3:13 am on Jan 29, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



$server['read_buffer'] = fgets($server['SOCKET'], 1024);

The code won't pass this line until it's managed to read 1024 bytes from the server. Sounds like you need a multi-threaded process to me - one thread doing the reading, one doing the writing.

ChainsawXIV

4:08 am on Jan 31, 2008 (gmt 0)

10+ Year Member



Thank you. That makes perfect sense now that you explain it.

How would you go about multi-threading this, given that I need to use the same socket for both sending and receiving? Is there a way I can accessing the same socket from a second script, or some way of running two loops simultaneously within a single script? I haven't worked with any deliberate multi-threading prior to this, and I'm not sure what my options are.